Как мне заставить hibernate охотно извлекать EmbeddedId?

#java #spring-boot #hibernate #lazy-initialization

Вопрос:

Иногда я получаю следующую ошибку:

 org.hibernate.LazyInitializationException: could not initialize proxy [com.dd.translation.domain.postgres.Offer#OfferKey(offerId=03Y, difId=b3e79b1925ce4e41905a2ce214943d1f)] - no Session
 

Встраиваемый:

 @Builder
@Embeddable
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OfferKey implements Serializable {

    @Column(name = "offer_id", columnDefinition = "CHARACTER VARYING(64) NOT NULL")
    private String offerId;

    @Column(name = "dif_id", columnDefinition = "CHARACTER VARYING(64) NOT NULL")
    private String difId;

}
 

Встроенный объект:

 @Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Table(name = "offers")
public class Offer {

    @EmbeddedId
    private OfferKey offerId;
    private LocalDateTime validDate;
}

 

В этом проекте нет другой ленивой загрузки, и я бы не предположил, что она мне понадобится @Transactional . Я пытаюсь выяснить, есть ли способ вручную установить его в режим ожидания или кто-нибудь сталкивался с этой проблемой. Лично я не использую этот шаблон, но он есть в существующем коде, и я пытаюсь понять, нужно ли его удалять или есть простое исправление.

Ответ №1:

Ошибка указывает на то, что Offer объект, к которому вы пытаетесь получить доступ, не инициализирован, а не встроенный идентификатор.

Я предполагаю, что у вас есть что-то подобное в одной из ваших моделей:

 @ManyToOne(fetch = FetchType.LAZY)
Offer offer;
 

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

Вы можете изменить значение FetchType на НЕТЕРПЕЛИВЫЙ, но я бы не рекомендовал этого делать. Лучшим решением было бы применить @EntityGraph к репозиторию метод, который предписывает ему загрузить ассоциацию.