Кроме того, вы можете установить точку останова и использовать этот статический метод, чтобы проверить, открыта ли транзакция.

даю, что лениво загруженная коллекция должна быть извлечена при доступе к коллекции в транзакционной области. Например, если я хочу получить коллекцию, я могу позвонить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 я ожидаю, что транзакция будет закрыта.

Что тут происходит?

Ответы на вопрос(2)

Ваш ответ на вопрос