2017-01-31 3 views
0

Я пытаюсь отладить уже существующий код, используя Hibernate и JPA. Сообщение об ошибке имеет смысл и даже имеет несколько других вопросов о том, как SO обсуждает это. Но когда я ищу сеанс, чтобы оставаться открытым, я обнаружил, что «сеанс» нигде не упоминается во всем теле кода (кроме сеансов HTTP - совсем другое). Более того, код выглядит так, как будто он должен работать, что заставляет меня думать, что есть информация о состоянии, которую я не вижу, но я не могу понять, какое государство я должен пытаться искать.«LazyInitializationException: не удалось инициализировать прокси - нет сеанса» - на самом деле, ни одного сеанса не найдено нигде

Я попытаюсь опубликовать простой пример, хотя я не могу подтвердить, что следующее будет делать то же самое, из-за всех связанных зависимостей. Надеюсь, достаточно будет сказать, что исключение, похоже, на 100% надежно брошено, заставив меня поверить, что я просто упускаю из виду что-то достаточно тривиальное.

код получает экземпляр класса определяется следующим образом:

@Entity 
@Table(name = "some_object") 
public class SomeObject { 
    @Valid 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "other_object_id") 
    private OtherObject otherObject; 
    // ...lots of other declarations 
    public OtherObject getOtherObject() {return this.otherObject;} 
    // ...lots of other accessors 
} 

Из этого экземпляра, другой объект приобретается, и атрибут называется на ней, в свою очередь:

OtherObject other = someObject.getOtherObject(); 
String strVal = otherObject.getOtherString(); 

где OtherObject объявлен как (частично) следующим образом:

@Entity 
@Table(name = "other_object") 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 
public class OtherObject { 
    @NotEmpty 
    @Column(name = "other_string") 
    private String otherString; 
    // ... 
    public String getOtherString() { return this.otherString; } 
    // ... 
} 

LazyInitializationException о ccurs по извлечению строки из otherObject.

Почему я не получаю LIE о приобретении someObject (он приобрел через некоторый JPA код, который я думаю не имеет значения здесь)?

Я думал, что могу предположить, что, поскольку первый аксессор, вероятно, приводит к запросу базы данных, которое успешно возвращается, что и второе. Это неверно?

Возможно, otherObject «уже здесь», и не вызывает запроса, тогда как получение otherString - нет. Как я могу проверить это? В любом случае нет кода, связанного с Session экземплярами, и любые вызовы объектов detach выглядят в совершенно неприменимых местах. Должен ли я выглядеть тяжелее? Должен ли я преследовать кроличью нору, чтобы получить доступ к протоколу Hibernate SQL для работы в Tomcat?

Или нет способа рассказать о том, что я здесь дал? Должен ли я добавить более подробную информацию?

ответ

2

С otherObject доставлен лениво, когда вы выполняете getOtherObject(), запрос базы данных отсутствует. Возвращается ленивый прокси-объект. Когда вы хотите изучить его содержимое , то есть otherObject.otherString доступ к базе данных происходит.

Если вы не работаете в транзакционном контексте (т. Е. Сеанс не открыт), вы получаете LazyInitializationException. Вы можете исправить это, либо извлекая otherObject с нетерпением (как это делается, зависит от того, как вы загружаете начальный SomeObject), либо открыв транзакцию/сеанс, чтобы запрос мог выполняться лениво.

Также не очень сложно записывать SQL-запросы, выполненные Hibernate.

+0

Хороший ответ, и, возможно, лучшее, что я могу получить, так как мало информации, которую я смог дать.Вопрос о ленивом прокси также имеет общий смысл, хотя теперь мне интересно: «someObject» был получен из сгенерированного кода службы Hibernate (я думаю), и теперь мне интересно, почему он тоже не выбрал исключение. Я уверен, что я недостаточно понимаю этот код, поэтому вопрос заключается в том, что он делает. –

Смежные вопросы