2016-08-25 83 views
0

我使用springBootTest來測試我創建的服務。在每個函數之前,我直接使用倉庫創建一個parententity。SpringBootTest沒有解決父子關係 - 未能延遲初始化

parentEntity = parentEntityRepository.saveAndFlush(ObjectMother.getParentEntityBuilder().string3("s3").build()); 

在我的測試中,我創建一個childentity

childEntity = childEntityRepository.saveAndFlush(ObjectMother.getChildEntityBuilder().parentEntity(parentEntity).build()); 

孩子們的關係定義如下

@Getter @Setter 
@OneToMany(orphanRemoval = true) 
@JoinColumn(name="PARENTENTITY_ID", updatable = false) 
private Set<ChildEntity> children; 

這是測試

parentEntity = parentEntityService.read(requestContext, parentEntity.getId()); 
parentEntity.getChildren().forEach(child -> Assert.assertNotNull(child.getText())); 

它會導致內調用以下錯誤

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.sap.icn.pi.test.data.mcp.ParentEntity.children, could not initialize proxy - no Session 

如果我添加@Transactional到我的測試方法我收到以下

java.lang.NullPointerException // for parentEntity.getChildren() 

**編輯:代碼片段**

@Test 
public void get_children_through_parent() { 
    parentEntity = parentEntityService.read(requestContext, 1); 

    parentEntity.getChildren().forEach(child -> Assert.assertNotNull(child)); 
    parentEntity.getChildren().forEach(child -> Assert.assertNull(child.getTooltip())); 
} 

ParentEntity類

@Entity 
@Table(name = "T_PARENTENTITY") 
@SequenceGenerator(initialValue = 1, name = "idgen", sequenceName = "SEQ_PARENTENTITY") 
@Builder @NoArgsConstructor @AllArgsConstructor 
@Localized 
public class ParentEntity extends BaseEntity{ 

    ... //props 

    @Getter @Setter 
    @OneToMany(orphanRemoval = true) 
    @JoinColumn(name="PARENTENTITY_ID", updatable = false) 
    private Set<ChildEntity> children; 
} 

回答

1

這是常見的JPA/Hibernate問題米對象被讀取的是不同的Hibernate會話或hibernate會話不再存在,所以懶加載不能執行SQL查詢來檢索懶惰依賴。這種情況的原因可能會有所不同,並且您沒有提供足夠的背景。

爲了解決這個問題,你有多種選擇:

  1. 確保對象讀取和懶惰關係在同一個Hibernate Session加載。 Spring爲每個控制器請求自動創建hibernate會話,所以最好確保您的對象不會在servlet過濾器中檢索到,並且在控制器/服務中不會檢索到惰性依賴關係。或者常見問題是將該對象傳遞給單獨的線程。
  2. 上改變依賴於急於:

    @Getter @Setter 
    @OneToMany(orphanRemoval = true, fetch = FetchType.EAGER) 
    @JoinColumn(name="PARENTENTITY_ID", updatable = false) 
    private Set<ChildEntity> children; 
    
+0

感謝您的解釋。建議2似乎並不合適,因爲我不想將我的抓取類型更改爲只是爲了能夠更好地進行測試。 我將如何確保在同一會話中讀取對象。我基本上只是使用我的服務層功能。 –

+0

您是否正在通過各種用戶請求分享它們? – luboskrnac

+0

分享什麼?在測試中,我稱之爲「e = myservice.read(...)」,之後是「e.getChildren()」,基本上就是這樣。我試圖添加@Transactional到測試類,這將解決錯誤,但getChildren將始終返回空值,然後... –