Hibernate从零开始_06_一对多关系(二)

    本来想配置多对多关系(中间表),并把多对多拆分为两个一对多之后发现一个问题,在一对多时,子类保存父类时报错

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.study.hibernate.domain.TbUser
 at org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:249)
 at org.hibernate.type.EntityType.getIdentifier(EntityType.java:509)
 at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:311)
 at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:321)
 at org.hibernate.type.TypeHelper.findDirty(TypeHelper.java:294)
 at org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:4049)
 at org.hibernate.event.internal.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEventListener.java:537)
 at org.hibernate.event.internal.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:235)
 at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:164)
 at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:230)
 at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:100)
 at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:55)
 at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1159)
 at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
 at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
 at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
 at com.study.hibernate.operate.HibernateTest.saveTest3(HibernateTest.java:275)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 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.runNotIgnored(BlockJUnit4ClassRunner.java:79)
 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
 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:50)
 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

配置如下:

    主表:

<hibernate-mapping>
  <class name="com.study.hibernate.domain.TbUser" table="tb_user" catalog="db_hibernate" select-before-update="true">
   <id name="id" column="id" type="java.lang.Long">
    <generator  class="native"></generator>
   </id>
   <property name="name" column="name" type="java.lang.String"></property>
   <property name="age" column="age" type="java.lang.Long"></property>
   <property name="city" column="city" type="java.lang.String"></property>
   
   <set name="orders" cascade="save-update,delete-orphan" inverse="true">
    <key column="tb_user_id"/>
    <one-to-many class="com.study.hibernate.domain.Order"/>
   </set>
  </class>
 </hibernate-mapping>

    从表:

<hibernate-mapping>
  <class name="com.study.hibernate.domain.Order" table="tb_order" catalog="db_hibernate">
   <id name="id" column="id" type="java.lang.Long">
    <generator  class="native"></generator>
   </id>
   <property name="addr" column="addr" type="java.lang.String"></property>
   <property name="totalprice" column="totalprice" type="java.lang.Long"></property>
   
   <many-to-one name="user" class="com.study.hibernate.domain.TbUser" column="tb_user_id" />
  </class>
 </hibernate-mapping>

    执行测试:报上面的错误

public void saveTest3(){
  Configuration configuration = new Configuration().configure();
  ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();  
  SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
  Session session = sessionFactory.openSession();
  Transaction transaction = session.beginTransaction();
  
  TbUser user = new TbUser();
  user.setName("wangwu");
  user.setAge(new Long(12));
  user.setCity("bj");
  
  Order order = new Order();
  order.setAddr("nihao");
  order.setTotalprice(new Long(200));
  order.setUser(user);
  session.save(order);
  
  transaction.commit();
  session.close();  
  sessionFactory.close();
 }

    原因是因为在没有保存主表的情况下保存了子表,解决办法在<many-to-one> 中加入cascade

 <many-to-one name="user" cascade="all" class="com.study.hibernate.domain.TbUser" column="tb_user_id" />

    问题解决,输出结果为:

 Hibernate: insert into db_hibernate.tb_user (name, age, city) values (?, ?, ?)
 Hibernate: insert into db_hibernate.tb_order (addr, totalprice, tb_user_id) values (?, ?, ?)

转载于:https://my.oschina.net/u/159221/blog/190600

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值