2017-09-04 80 views
2

我有異步端點的Spring MVC應用程序:如何將http會話傳遞給DeferredResult?

@GetMapping 
public DeferredResult<Collection<B>> get() { 
    DeferredResult<Collection<B>> result = new DeferredResult<>(); 
    Executors.newSingleThreadExecutor().submit(() -> result.setResult(service.getB())); 
    return result; 
} 

我想偷懶序列化對象與jackson-datatype-hibernate

@Entity 
@Table 
public class B { 

    @Id 
    @GeneratedValue 
    private UUID id; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "a_id") 
    private A a; 

    public A getA() { 
     return a; 
    } 
} 

但我發現了:

Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.example.demo.B["a"]) 
+0

錯誤與'Hibernate Session'相關,而不是'HTTP Session';基本上你也試圖在''a''屬性'B'類中''a'屬性,因爲你有一個'Lazy'獲取策略,你會得到錯誤 –

+0

@AngeloImmediata實際上它可以與Callable或CompletableFuture一起工作,當我不試圖執行新線程中的任務。我使用com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module添加了Bean MappingJackson2HttpMessageConverter與自定義ObjectMapper。 –

+0

這很奇怪..錯誤非常明顯,並且抓取策略總是很清晰。你是否檢查過它的工作原理時,所有參數都與不工作的測試相同? –

回答

0

我認爲會話提到有一個Hibernate會話不是HTTP會話。

你的POJO(B)包含映射與FetchType.LAZY所以當該屬性被讀取Hibernate的Session必須是爲了滿足懶人取開放和可用的屬性(A a)。

我懷疑你正在打開一個會話每調用線程,並且由於響應是在不同的線程上處理的,Hibernate會話在B被序列化的線程上不可用。您必須將某個狀態(可能是通過創建可執行任務/運行程序)傳遞給創建延遲結果的線程,您可以擴展它以在委派時包含當前打開的Hibernate會話(並且記住在您擁有時關閉此會話完成該線程)。或者,另外,您可以:

  • 打開在其上創建的遞延結果
  • 更改FetchType,使其不再是懶惰的線程上一個新的Hibernate Session。
相關問題