Caused by: org.hibernate.TransientObjectException: The given object has a null identifier

本文通过实战案例解析了Hibernate中瞬时态、持久态和游离态的概念及其转换过程,并分享了作者在使用Hibernate进行数据库操作时遇到的具体问题及解决办法。

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

 今天在写代码的时候又遇到了关于hibernate的操作,因为一直没有系统的学过hibernate做起来还是有些吃力。各种百度各种Google,记得以前也这样做过只不过没把当时的学到的、了解到的记录下来,看过就忘了。为了不再重蹈覆辙,今天要把遇到的问题及解决方法,网上搜罗到的知识在这里汇总一下。一,是为了加深对这些知识的掌握,二,如果能帮到遇到同样问题的朋友就更好了。话不多说,上菜。

 因为遇到的问题算是解决了(可能还会出现新的问题),还原现场,且听我娓娓道来。

第一阶段,拿起代码就是写。

大体逻辑:将对象保存到数据库,如果数据库中有此对象(根据唯一约束)则更新。听起来没毛病。


    public void addAwosList(List<AwosDto> awosDtos) {
        if (awosDtos.size() == 0) return;
        for (AwosDto awosDto : awosDtos) {
            Awos awos = new Awos(); //瞬时态
            BeanUtils.copyProperties(awosDto, awos);
            if(awosDao.findByReportIDAndRno(awos.getReportId(),awos.getRno()) == null){
                awosDao.add(awos); //变为持久态
            }else{
                awosDao.update(awos);
            }
        }
    }

执行,第一个错误来了,直译一下,hibernate瞬时态对象异常:你给的对象有空的标识符(真不能直译)。简单来说就是没有主键。这时候,我们就见识到了hibernate的冰山一角,瞬时态。

Caused by: org.hibernate.TransientObjectException: The given object has a null identifier

第二阶段,小失落

没有主键还不好办,那就加上呗


    public void addAwosList(List<AwosDto> awosDtos) {
        if (awosDtos.size() == 0) return;
        for (AwosDto awosDto : awosDtos) {
            Awos awos = new Awos();
            BeanUtils.copyProperties(awosDto, awos);
            if(awosDao.findByReportIDAndRno(awos.getReportId(),awos.getRno()) == null){
                awosDao.add(awos);
            }else{
            Long id = 
                    awosDao.findByReportIDAndRno
                            (awos.getReportId(),awos.getRno()).
                            getId();        
                awos.setId(id);
                awosDao.update(awos);
            }
        }
    }

执行,第二个错误,接着直译,非唯一对象异常:一个有着同样标识符的对象已经与Session绑定了。到了这里就有点头大了。我们又见识到了冰山的另一角,Session.

既然说已经在session中存在,那就直接在session中更改并提交。

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session

第三阶段,各种搜索

让我们从三种状态说起,transient (瞬时态)、persistent(持久态)、detached(游离态)。
官方文档见Chapter 10. Working with objects

  • 瞬时态 是一个对象刚通过new操作被实例化,还没有关联Session,没有在数据库中持久化表示也没有被分配标识符(说人话,就是TMD这个实例在数据库中没有对应的存在也没有分配主键)。主键分类
Cat cat = new Cat();
cat.setName("大橘");
//在这里cat就属于瞬时态
  • 持久态 持久态实例存在于数据库中也有主键,它与Session相关联,Session 具有一个缓存, 位于缓存中的对象称为持久化对象, 它和数据库中的相关记录对应。我们可以通过关联Session来把一个瞬时态变为持久态。
Long id = (Long)session.save(cat);//具体返回什么,要看代码
//cat现在就属于持久态了
  • 游离态 是一个对象已经被持久化(存到数据库),但是Session被关闭了。它的引用依然有效,当然也能修改(cat.setName("小花"))
    这里写图片描述
    说了这么多有什么用呢,其实还是有的,至少知道了一个对象是处于什么状态。但还是不能直接解决上述问题啊

更新中….

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值