org.hibernate.TransientObjectException异常

  代码如下:

复制代码
    /**
     * 测试4:新增一个秘书角色,并赋给张三该角色
     */
    @Test
    public void test4(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        
        /******S  开始业务逻辑*************/
        //get方法获取的对象都是持久态
        Role r1 = new Role();
        r1.setRole_name("秘书");
        User user = session.get(User.class,1l);
        user.getRoles().add(r1);
        
        session.update(user);
        /******E  开始业务逻辑*************/
        
        tx.commit();
    }
复制代码

报错如下:

复制代码
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: cn.qlq.domain.Role
    at org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:279)
    at org.hibernate.type.EntityType.getIdentifier(EntityType.java:455)
    at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:144)
    at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:888)
    at org.hibernate.persister.collection.AbstractCollectionPersister.insertRows(AbstractCollectionPersister.java:1545)
    at org.hibernate.action.internal.CollectionUpdateAction.execute(CollectionUpdateAction.java:85)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:560)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:434)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:465)
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963)
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339)
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
    at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
    at cn.qlq.relation.Many2Many.test4(Many2Many.java:103)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
复制代码

 

错误解释:

   大概的错误意思是: 游离态对象异常,对象引用了一个未保存的游离态对象,在保存对象之前请先保存游离态对象。

原因:

  大概是新建的Role对象未调用save方法,所以该对象还是游离态,但是已经将该对象与user建立关联,所以在更新user的时候报错。

 解决办法: 

  调用save方法将r1置为持久态。其实最后一句session.update(user)可写可不写,因为get获取的对象本来就处于永久态。

复制代码
    /**
     * 测试4:新增一个秘书角色,并赋给张三该角色
     */
    @Test
    public void test4(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        
        /******S  开始业务逻辑*************/
        //get方法获取的对象都是持久态
        Role r1 = new Role();
        r1.setRole_name("秘书");
        User user = session.get(User.class,1l);
        user.getRoles().add(r1);
        
        session.save(r1);
        session.update(user);
        /******E  开始业务逻辑*************/
        
        tx.commit();
    }
复制代码

 

posted @   QiaoZhi  阅读(407)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2017-08-05 lucene查询索引之QueryParser解析查询——(八)
2017-08-05 java的数据类型
2017-08-05 lucene查询索引之Query子类查询——(七)
2017-08-05 lucene修改索引——(六)
2017-08-05 lucene删除索引——(五)
2017-08-05 lucene中文分词——(四)
2017-08-05 lucene入门查询索引——(三)
点击右上角即可分享
微信分享提示