Java 如果使用save,为什么saveOrUpdate在执行时不在数据库中插入注释
我对冬眠的奇怪行为有疑问 我有以下的守则:Java 如果使用save,为什么saveOrUpdate在执行时不在数据库中插入注释,java,hibernate,orm,Java,Hibernate,Orm,我对冬眠的奇怪行为有疑问 我有以下的守则: Prepod prepod = new Prepod(); prepod.setId(1l); Student student = new Student(); student.setAge(12l); student.setName("name"); student.setId(1l); prepod.getStudents().add(student);
Prepod prepod = new Prepod();
prepod.setId(1l);
Student student = new Student();
student.setAge(12l);
student.setName("name");
student.setId(1l);
prepod.getStudents().add(student);
student.getPrepods().add(prepod);
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
session.saveOrUpdate(prepod);
session.saveOrUpdate(student);
session.getTransaction().commit();
hibernate告诉我:
Hibernate: update Student set age=?, name=? where id=?
Exception in thread "main" org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:81)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:73)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:57)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3016)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2918)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3247)
at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:140)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:276)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1214)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:403)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at logic.Main.main(Main.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
但是如果我使用
session.save(prepod);
session.save(student);
我明白了:
Hibernate: select max(id) from prepod
Hibernate: select max(id) from Student
Hibernate: insert into prepod (id) values (?)
Hibernate: insert into Student (age, name, id) values (?, ?, ?)
Hibernate: insert into prepod_Student (prepods_id, students_id) values (?, ?)
这对我来说是个好行为
你能解释一下为什么它如此有效吗
在我认为saveOrUpdate自动选择save或update之前。问题在于区分对象是否存在于数据库中 对象Prepod和Student的ID显然设置为generator=increment,这就是为什么我们看到selectmaxid语句。最有可能的是,未保存的值保留为默认值:0
这意味着Hibernate会将prepd实例视为新实例/临时实例,以防ID==0。但在代码中,您设置了id:student.setAge12l 因此,从Hibernate的角度来看,对象不再是瞬态的。它似乎是现有的、已经持久化的对象 因此,如果调用SaveOrUpdate,Hibernate将指示使用UPDATE语句,因为对象似乎不是瞬态的
如何解决?不要自行设置ID。只需依靠生成器=增量。在这种情况下,对象将是瞬态的,默认id==0,Hibernate将按预期工作,但在代码中设置id:student.setAge12l;-这里出错