关于在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

背景:

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

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

 

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

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

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

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

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

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

因此解决方案是:

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

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

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

通过测试:

参考:

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<Contact,Integer>实现自动管理

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

但是在调用的时候:

报错了 !!

 java.lang.IllegalStateException: Failed to load ApplicationContext  

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

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

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

因此把方法名修改正确:

Adress ->Name 

通过测试 

因此我们知道了,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访问数据库。

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

报错了!!

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

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

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

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

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

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

解决方法:

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

 

通过测试 

参考

SpringData JPA 数据表映射_jpa 怎么将表结构映射_路面烧卖的博客-CSDN博客

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值