LazyInitializationException for Id field with hibernate + Lo



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

问题堆栈跟踪:-

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((时,它在事务之外的静止层工作。

一旦我将代码更改为下面(添加龙目岛(,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(我必须强制使用龙目岛项目
2(我必须在Sevrice和trasaction之外使用searRequest.getCourseSchedule((.getId((

请提出解决方案,提前感谢!!

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

我刚才注意到了这一点...如果您在服务和交易之外,您将始终有该例外。尝试使用FetchType.EAGER,它应该可以工作。

当您退出事务时,您的实体将被分离,这意味着不会加载您标记为懒惰的所有集合。因此,您有两种选择:第一种是在事务中执行对集合getter的所有调用,第二种是将集合标记为渴望,因此当Hibernate加载实体时,它也将立即加载引用的集合。或者,您可以在交易中将实体映射到 DTO。只要您在事务中,惰性加载字段的获取器将始终工作,因此到DTO的映射器将访问所有信息。一旦DTO退出交易,您将可以访问已映射的所有字段,然后做任何您想做的事情。

这是我最终解决问题的方式!
我认为问题是在与龙目岛项目集成后开始的,但是当注释从方法(属性(级别移动到字段级别时,问题就开始了。
请耐心等待我的长答案。 这里的 foreign 是指数据库级别的外部表。
要访问事务外部外表中的任何列,您需要使用 FetchType.Eager (对于任何外部对象,默认处于休眠状态(或需要联接/子查询该表。

但是,如果您只想获取与 2 个表连接的外键(列((在我们的例子中为 ID(并想要保留FetchType.LAZY,那么您可以通过 2 种方式做到这一点:-

1(在getter方法上保留注释(manyToOne,JoinColumn等(

2(如果注释必须保留在字段级别,那么在父表中的外键字段上再写一个注释,即 -@Access(AccessType.PROPERTY(所以在上面的代码中解决我在id字段上添加了这个注释

当然时间表
@Entity
@Audited
@Table(name = "course_schedule")
@Getter
@Setter
public class CourseSchedule{
@Id
@GenericGenerator(name = "autoincr", strategy = "native")
@GeneratedValue(generator = "autoincr")
@Column(name = "id", unique = true, nullable = false)
@Access(AccessType.PROPERTY)
protected Long id;
..........
}

因此,座位申请中不需要更改。

最新更新