关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结

一、(@Data@ToString与@OnetoMany冲突

报错 

org.hibernate.HibernateException: collection was evicted

或者

org.springframework.orm.jpa.JpaSystemException: collection was evicted; nested exception is org.hibernate.HibernateException: collection was evicted

背景:

这是的代码是使用了JPA代替mybatis实现数据获取,数据库涉及到了客户Custormer联系人Contact 的一对多的关联关系

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第1张图片关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第2张图片

因此需要在entity 中的实体类表中的关联成员添加注解:@OneToMany 和 @ManyToOne

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第3张图片

 关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第4张图片

 这里我通过对象的方式来存储所关联的对象(记住这里);

于是今天在使用JPA访问数据库时,查询了第一页的用户信息时,报错了

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第5张图片

乍一看,能看报错说的是当前collection被弃用。

但是继续往下面看,显示的是hashcode报错

关于Collection我们只在用户类中用到了set,于是我联想到了Customer实体中的set集合

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第6张图片

这里报错的是hashcode,网上查阅资料,提示 lombok插件的@Data注解可能会和@OneToMany注解冲突,是因为@data注解里的EqualsAndHashCode 会检查 onetomany里的内容,干扰Hibernate的加载策略或类似的策略,从而会影响hashcode和equals的调用

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第7张图片

因此解决方案是:

一、重写实体类的hashcode和equals方法

二、弃用@Data@ToString注解 自己写getter setter 和toString方法 (亲测可行)

三、把对象存储方式由set改为list (亲测可行)

通过测试:

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第8张图片

参考:

java - Spring Framework Collection was evicted - Stack Overflow

SpringDataJPA——collection was evicted

 spring boot - HibernateException in hashCode or in equals - Stack Overflow

二、继承JpaRepository接口后,抽象方法名对应对象属性

 报错

java.lang.IllegalStateException: Failed to load ApplicationContext  

前提背景:

和前面一样,使用JPA规范的hibernate访问数据库。

实现前提需要创建Repository接口:(该接口通过继承 JpaRepository实现Spring自动管理)

除了简单的增删改查,我们还可以自定义接口方法进行Like查询

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第9张图片

但是在调用的时候:

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第10张图片

报错了 !!

 java.lang.IllegalStateException: Failed to load ApplicationContext  

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第11张图片

 继续往下翻 找到了根本原因

Caused by: org.springframework.data.mapping.PropertyReferenceException: No property 'address' found for type 'Contact'

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第12张图片

原来是接口的名字中包含的Address没有在数据库找到对应的字段

因此把方法名修改正确:

Adress ->Name 

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第13张图片

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第14张图片

通过测试 

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第15张图片

因此我们知道了,HIbernate是通过接口方法名来实现字段对应的,契合Springboot中的约定大于配置的思想。

三、toString 的循环调用问题

报错

java.lang.StackOverflowError
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:587)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149)
    at org.hibernate.collection.internal.PersistentSet.toString(PersistentSet.java:327)

背景前提:

和前面一样,使用JPA规范的hibernate访问数据库。

在我查询成功数据后,我们正当要输出数据的时候

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第16张图片

报错了!!

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第17张图片

显示的是栈溢出,紧接着的是重复的报错。

因此可以考虑是不是陷入了死循环。

经过一段时间的断点调试,我找到了原因所在

回到刚才记住的点,我们的Customer和 Contact实体类是通过对象的方式存储关联对象的。

在我们输出的时候调用了Customer的toString方法,其中就包括了Contact对象Set,然后由调用 Contact对象的ToString,

Contact又包含了Customer对象的成员变量,因此会陷入对象的toString死循环

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第18张图片

解决方法:

重写Customer的toString 方法,去掉set(或者list)成员变量的输出

 关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第19张图片

通过测试 

关于在SpringBoot中使用JPA规范Hibernate的出现的错误总结_第20张图片

https://www.jb51.net/article/253702.htm

你可能感兴趣的:(spring,boot,hibernate,java)