hibernate 常见问题总结

1. org.hibernate.ObjectNotFoundException: No row with the given identifier exist
这是因为,搜索表1,表1中有属性可以获取表2的数据,结果表1中的该属性为空或其在表2中不存在导致
在获取数据的get方法上 添加@NotFound(action = NotFoundAction.IGNORE) 就会过滤找不到对象的错误,从而获取的对象不在是以上异常而是null
如果对于@manytoone 的方法添加@NotFound 后会导致非懒加载,会影响一定的性能,最好是不在表1对应的对象中封装表2对象,直接通过表1中属性来搜索表2中的数据


2. saveorupdate 方法 HibernateOptimisticLockingFailureException 异常详解

Caused by: org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1


解释:因为更新时,需要有一个更新项,但实际上却是0,说明我本来是要进行新增的项却去执行了更新操作,且数据库中没有相关的更新项所以报错.

使用的是hibernate的saveOrUpdate方法保存实例。saveOrUpdate方法要求ID为null时才执行SAVE,在其它情况下执行UPDATE。在保存实例的时候是新增,但你的ID不为null,所以使用的是UPDATE,但是数据库里没有主键相关的值,所以出现异常。

如果是自增主键,有的数据库是可以修改自增主键例如:MySQL,有的数据库是不允许修改自增主键的例如postgresql

不要设置自增主键的值

3.数据插入时报 Duplicate entry '185264' for key 'PRIMARY'

查看程序,对象是先搜索,如果对象不存在,则进行插入,id使用的是自增,结果保存时,报重复主键异常.如果我本地启动访问是不会报错的

@Id  
@GenericGenerator(name = "idGenerator", strategy = "increment")
@GeneratedValue(generator = "idGenerator")

public Integer getId() {
return id;
}

这是因为 我本地与环境上链接同一数据库,当使用hibernate的自增时,都有缓存,本地将id加到了185300 ,而环境上却是185264,导致环境上报重复主键的错误,如果环境重启下,本地不再访问,则不会有问题.

解决方案:不使用自增策略


4. 修改对象obj时,对象中存在多对一关系,但是一的一方ExpertStation为空,ExpertStation对象中也存在多对一的关系userobj ,在页面展示时调用如obj.xxobj.id  会报如下异常错误 ,但是页面可以正常显示

org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: qnit.modules.expert.entity.ExpertStation; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: qnit.modules.expert.entity.ExpertStation
at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:188)
at org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:681)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:563)

Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: qnit.modules.expert.entity.ExpertStation
at org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:249)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:489)
at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:295)
at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:305)

原因: 当获取obj 对象时,对象被hibernate 存到session中,该对象此时是与数据库关联的,但是访问到页面时,通过obj获取ExpertStation 时,此时ExpertStation为null,然后再通过ExpertStation获取id时报错

解决方案: xxobj 保存时,


5. 多对多搜索列表展示条数不一致,不管是左链接 还是右链接 还是内链接 存在重复数据

添加distinct 排重处理:

setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)  因为是先到数据库查询数据后,hibernate再对该列表进行遍历去重 , 所以分页展示不对,设置返回个数时也不一致

改为如下 : 直接在语句前添加 distinct(),sql如:SELECT DISTINCT(cat_id) FROM cat_table
使用如下写法:  

  1. ProjectionList projectionList = Projections.projectionList(); 
  2. projectionList.add(Projections.property("id"));  
  3. projectionList.add(Projections.property("name"));  
  4. c.setProjection(Projections.distinct(projectionList));  // >>>> 这里差别 生成如下SQL: select distinct id, name from ....  
  5. List result = c.list();
但是,这样的写法只能搜索出 property 设置的属性,且返回对象为list<object[] > 使用起来不方便

如果既需要转化为对象[不设置属性],又需要进行排重处理,就只能用sql 或hsql 来实现了.用Criteria 就无法实现了

6. 保存对象时,提示在flush 前有未保存的实例 ,保存页上如果设置了User.id 则不会,只设置User.username则报以下问题

Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: qnit.modules.user.entity.User
at org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:249)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:489)
at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:295)
at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:305)
at org.hibernate.type.TypeHelper.findDirty(TypeHelper.java:294)

如果不设置User.id  在保存对象时,User.id=null  如果设置了User.id ,则 User.id=""  hibernate判断id为null ,则报异常.

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值