首页 > 解决方案 > 带有休眠+龙目岛的Id字段的LazyInitializationException

问题描述

当我将 Lombok 项目添加到我的休眠项目中并在实体类上使用它时,我遇到了惰性初始化@Getter问题@Setter@Entity当我使用休眠 5 时,实体类使用 Javax.persistence 进行注释。

问题堆栈跟踪:-

org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:146)
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:259)
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:73)
    at com.capehenry.domain.user.User_$$_jvst52e_9.getId(User_$$_jvst52e_9.java)
    at com.capehenry.business.rs.course.SeatRequestResource.validateSeatRequestCancel(SeatRequestResource.java:338)
    at com.capehenry.business.rs.course.SeatRequestResource.cancel(SeatRequestResource.java:220)

使用以下代码一切正常

@Entity
@Audited
@Table(name = "seat_request")
public class SeatRequest extends BaseEntity {

    private CourseSchedule courseSchedule;

@ManyToOne(fetch = FetchType.LAZY)
 @JoinColumn(name = "courseScheduleId", nullable = false)
public CourseSchedule getCourseSchedule() {
    return courseSchedule;
}

public void setCourseSchedule(CourseSchedule courseSchedule) {
    this.courseSchedule = courseSchedule;
}

当我做 searRequest.getCourseSchedule().getId() 它在休息层工作意味着在事务之外。

一旦我将代码更改为下面(添加 lombok),休息层的 searRequest.getCourseSchedule().getId() 就会开始抛出lazyInitializationException:-

@Entity
@Audited
@Table(name = "seat_request")
@Setter
public class SeatRequest extends BaseEntity {

    @ManyToOne(fetch = FetchType.LAZY, optional=false)
    @JoinColumn(name = "courseScheduleId", nullable = false)
    private CourseSchedule courseSchedule;

注意:- 1)我必须强制使用 Lombok 项目
2)我必须在 Sevrice 和 trasaction 之外使用 searRequest.getCourseSchedule().getId()

请提出解决方案,在此先感谢!

标签: javaspringhibernatelomboklazy-initialization

解决方案


我必须在服务和事务之外使用 searRequest.getCourseSchedule().getId()

我刚才注意到了这一点……如果您不在服务和交易范围内,您将始终遇到该异常。尝试使用FetchType.EAGER它应该可以工作。

When you are out of transaction your entities are detached, this means that all collections that you marked as lazy won't be loaded. So you have two options: the first is to perform all calls to collections getters inside the transaction, the second one is to mark as eager your collection, so when Hibernate loads the entity it will also load referenced collection immediately. Alternatively you could map to a DTO your Entity inside your transaction. As long as you are in the transaction the getters of lazy loaded field will always work, so a mapper to the DTO would access all informations. Once that the DTO is out of the transaction you will have access to all fields you have mapped, and than do whatever you want.


推荐阅读