Кроме того, вы можете установить точку останова и использовать этот статический метод, чтобы проверить, открыта ли транзакция.
даю, что лениво загруженная коллекция должна быть извлечена при доступе к коллекции в транзакционной области. Например, если я хочу получить коллекцию, я могу позвонитьfoo.getBars.size()
, Отсутствие активной транзакции должно привести к исключению с сообщением об ошибке, например
не удалось лениво инициализировать коллекцию баров: .... не удалось инициализировать прокси - нет сеанса
Однако я заметил, что поведение в моем последнем приложении отличается. Я использую Spring Boot 1.5.1 со стартером "data-jpa". В прошлом я использовал Spring Boot, но для меня новичок в data-jpa.
Рассмотрим следующий случай. У меня есть загруженная коллекция 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 я ожидаю, что транзакция будет закрыта.
Что тут происходит?