• 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();
        }
  • 相关阅读:
    bootStrap-treeview插件
    UML常用图的几种关系的总结
    RFC中文文档
    继承:重新使用接口
    Java8向后兼容
    Java8 时间调节器
    Java8 ChronoUnits枚举
    BigDecimal.divide方法
    java.lang.Double.byteValue() 方法
    事件处理是什么?
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/9427544.html
Copyright © 2020-2023  润新知