hibernate select操作出现字段被截断错误

本文探讨了在使用Hibernate进行数据库查询时遇到的字段被截断错误。问题源于一个select操作,但错误提示却显示为update操作导致。通过分析,发现错误源在于对象状态管理,特别是持久态对象的set方法触发了更新操作。解决方案是对持久化对象的修改进行管理,理解并掌握Hibernate的三态(临时、持久、游离)概念,确保在适当的时候更新数据库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

hibernate 使用面向对象的思想,
将数据表抽象为类,
数据记录抽象为对象,

比较完美的减少了对sql的显式使用,用起来也是比较方便,通过操作对象就能增删改数据库记录.
优点:

  • 单表查询简单,
  • crud完美移植到方法的调用,
  • 对开发人员sql的要求比较低
    缺点:
  • 多表查询比较麻烦,
  • 映射比较繁琐
  • 字段完全查出,性能有消耗
    这些优缺点只是个人理解.

接下来才是本文重点:

主角登场–遇到的问题

起初学习hibernate也没有考虑hibernate 对象的状态问题:
最近项目是用到hibernate开发,出现一个奇妙的错误:
博主在代码中执行查询,查询出数据库的一条记录,使用的是与数据表有着映射关系的Pojo类.

java伪代码如下:

@Service
class myService{
@Transactional
Map<String,Object> getById(Integer pojoId){
Pojo object=PojoDao.get(pojoId);
if(object!=null){
 object.setRemark("object  from database");
 }
 Map<String,Object> result=new HashMap<>();
 result.put("data",object);
 return object;
}


}

bug 登场

实际测试接口调用此方法,发现是500错误,并且报错是字段被截断的错误,心想,显而易见是使用的select,如果是insert或者是update还能说的过去,仅仅是select,爆出这个错误,真是令人费解.

接着打断点,一直执行到 return object都是没有排除异常的,return之后就是@Transactional的地盘了,提交事务,抛出异常,此时控制台输出了一条sql

update Pojo set = … where id=**

出来了一条update的sql,接着是一条字段被截断的错误
想想,应该是那个setRemark 方法调用导致的问题,很久以前马马虎虎看过hibertnate的三态,由于没有遇到问题,只是似懂非懂的一扫而过,这下遇到问题,就往这个方向考虑.

快刀登场

将setReark()的那一行代码注释掉,启动测试,接口200,没有问题,进一步证实了猜测.
提交事务会引起对象同步到数据库.
具体的还是来理解一下hiberbate的三态吧:

理论支持

三态=临时+持久+游离 1

临时(Transient): new 操作创建,并且还没和session相关联. 使用session执行必要的sql可以将其转换为持久态
持久态(Peristent):对象和数据库的一条记录存在映射,对象拥有持久化标识.hibernate会检测到持久化对象的所有改动,并且在当前操作单元执行完毕,自动将当前的新的状态(包含对象属性值)
同步到数据库.
游离态(Detached:与持久对象关联的session关闭后,对象变为游离态.对游离态的引用依然有效,游离对象如果余新的session关联,会再次转变为持久态,处于游离状态期间,该对象发生变化,也能够同步到数据库


  1. 三态的理解来自此博客
    回到此问题,pojo对象应该还是处于持久态,人为修改,自动提交事务,导致将修改同步到数据库,以至于出现此错误.
    三态问题还需要仔细研究. ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值