我的期望是,當在事務範圍內訪問集合時,應該獲取延遲加載的集合。例如,如果我想獲取集合,我可以撥打foo.getBars.size()
。由於沒有活動事務的應該導致一個錯誤消息的異常像Spring Data JPA - 無需@Transactional獲取Lazy Loaded集合
未能懶洋洋地初始化酒吧集合:......無法 初始化代理 - 沒有會話
然而,我注意到我的最新應用程序中的行爲不同。我正在使用Spring Boot 1.5.1和「data-jpa」啓動器。過去我使用過Spring Boot,但data-jpa starter對我來說是新的。
請考慮以下情況。我有一個懶加載的ManyToMany集合。
@SuppressWarnings("serial")
@Entity
@Table(name = "foo")
public class Foo implements java.io.Serializable {
....
private Set<Bar> bars = new HashSet<Bar>(0);
....
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "foo_bar_map",
joinColumns = {@JoinColumn(name = "foo_id", nullable = false, updatable = false)},
inverseJoinColumns = {@JoinColumn(name = "bar_id", nullable = false, updatable = false)})
public Set<Bar> getBars() {
return this.bars;
}
public void setBar(Set<Bar> bars) {
this.bars = bars;
}
我的服務方法沒有被標記爲事務性,但我訪問延遲加載的集合
@Service
public class FooServiceImpl implements FooService {
@Autowired
private FooRepository fooRepo;
@Override
public FooDTO findById(int fooId) {
Foo foo = fooRepo.findOne(fooId);
// The FooDTO constructor will access foo.getBars()
return new FooDTO(foo);
}
而對於在FooDTO構造
public FooDTO(Foo foo) {
...
for (Bar bar : foo.getBars()) {
this.bars.add(bar);
}
}
出乎我的意料和過去的情況下經驗,此代碼成功執行並獲取集合。此外,如果我在服務方法中引發斷點,則可以遍歷代碼並查看日誌中的SQL語句,這些語句用於在調用fooRepo之後獲取條形圖。在我致電fooRepo之後,我預計交易將被關閉。
這裏發生了什麼?
誰致電該服務?我的猜測是調用者是事務性的。 –
@JBNizet這個方法被一個控制器調用,它沒有標記爲事務性的...... –
默認情況下,Spring引導似乎使用OpenEntityManagerInViewwInterceptor:https://github.com/spring-projects/spring-boot/blob/主/彈簧引導自動配置/ SRC /主/ JAVA /組織/ springframework的/引導/自動配置/ ORM/JPA/JpaBaseConfiguration.java#L203。另請參閱http://docs.spring.io/spring-boot/docs/1.4.2.RELEASE/reference/htmlsingle/#common-application-properties(並搜索OpenEntityManagerInView) –