Hibernate代理.toString惰性初始化异常

huangapple go评论69阅读模式
英文:

HibernateProxy.toString lazy initializacion exception

问题

我在调试我的 POC 时遇到了一个奇怪的错误。
我有两个实体:

@Getter
@Setter
@Entity
@Table(name = "APPLICANT")
public class Applicant implements Serializable {

    private static final long serialVersionUID = 6060170457948717553L;

    @Id
    @Column(name = "applicant_id", insertable = false, nullable = false)
    private Long applicantId;

    @Column(name = "application_id", unique = true)
    private String applicationId;

    @OneToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "application_id", referencedColumnName = "application_id", insertable =
    false, updatable = false)
    private ApplicationEntity applicationEntity;
@Getter
@Setter
@Entity
@Table(name = "APPLICATION")
public class ApplicationEntity implements Serializable{

    private static final long serialVersionUID = 7300036359295729197L;

    @Id
    @Column(name = "APPLICATION_ID")
    private String id;

    @OneToOne(mappedBy = "applicationEntity", fetch = FetchType.LAZY)
    private Applicant applicant;

这些类具有继承自 CrudRepository 的存储库接口,在 Applicant 存储库中,我有一个自定义方法来通过 applicationId 获取实体:
Applicant findByApplicationId(String applicationId);

但是,当我调试时,在 applicationEntity 属性中看到以下消息:

Method threw 'org.hibernate.LazyInitializationException' exception. Cannot evaluate org.example.postgres.jpa.model.ApplicationEntity$HibernateProxy$qa4PKx8V.toString()

qa4PKx8V 每次执行新的测试时都会更改。

我尝试了许多在 @Join 注释中的组合,我删除了 lombook 注释,我也使用了 @Transactional 注释,但始终是相同的错误。

需要注意的一个关键点是,我可以在没有任何错误的情况下获取表中的数据,我只是在调试器中看到这个消息,所以我的问题是,这是 IntelliJ 的问题还是类似的情况?还是我需要通过配置或更改代码来解决这个问题?

谢谢。

英文:

I'm getting a weird error while I'm debugging my POC.
I have 2 entities:

@Getter
@Setter
@Entity
@Table(name = "APPLICANT")
public class Applicant implements Serializable {


    private static final long serialVersionUID = 6060170457948717553L;

    @Id
    @Column(name = "applicant_id", insertable = false, nullable = false)
    private Long applicantId;

    @Column(name = "application_id", unique = true)
    private String applicationId;

    @OneToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "application_id", referencedColumnName = "application_id", insertable = 
    false, updatable = false)
    private ApplicationEntity applicationEntity;

@Getter
@Setter
@Entity
@Table(name = "APPLICATION")
public class ApplicationEntity implements Serializable{

    private static final long serialVersionUID = 7300036359295729197L;

    @Id
    @Column(name = "APPLICATION_ID")
    private String id;

    @OneToOne(mappedBy = "applicationEntity", fetch = FetchType.LAZY)
    private Applicant applicant;

These classes has the repositories interfaces extending from CrudRepository, and in the Applicant repository I have a custom method to get the entity with the applicationId:
Applicant findByApplicationId(String applicationId);
But, when I'm debugging, I see the following message in the intellij debuguer on the applicationEntity attribute:

Method threw 'org.hibernate.LazyInitializationException' exception. Cannot evaluate
org.example.postgres.jpa.model.ApplicationEntity$HibernateProxy$qa4PKx8V.toString()

The value qa4PKx8V changes every time that I perform a new test.

I tried a lot of combinations in the @Join annotation, I've deleted the lombook annotations, I've used the @Transactional annotation either, but is always the same error.

A key point to note, is that I can get the data from the table with any error, I just see this message in the debugger, so my question is, this is a thing of intellij or something like that? Or I need to fix this with configuration or changing something in my code?

Thanks.

答案1

得分: 2

我假设你有一个自动生成的 toString() 实现?

一般来说,你应该避免在 toString()equals()hashCode() 等方法中引用懒加载的属性。如果不这样做,将会导致 LazyInitializationException 异常,就像你现在遇到的情况一样。当这些方法在没有活动事务上下文的情况下尝试访问懒加载属性时,就会触发该异常。

(这实际上是 "IntelliJ 的一件事情",因为尽管调试的代码可能被事务包围,但 IntelliJ 检查器会在单独的线程上评估表达式,在该线程中没有活动事务 = 没有打开的持久化上下文。而且,这只会发生在 @XxxToOne(optional = false) 的属性上)

英文:

I am assuming you have an autogenerated toString() implementation?

In general, you should avoid referencing lazily-loaded properties in toString(), equals(), hashCode() etc. Failing to do so will result in LazyInitializationException surprises like the one you're facing, triggered by the aforementioned methods whenever they try to access lazy properties outside of an active transaction context.

(This is indeed 'a thing of intellij', in the sense that although the debugged code is probably surrounded by a transaction, the Intellij inspector evaluates the expression on a separate thread where no transaction is active = no persistence context is open. Also, it will only happen with @XxxToOne(optional = false) properties)

huangapple
  • 本文由 发表于 2020年7月25日 05:42:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/63081855.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定