我是Hibernate的新手,我无法让@OneToOne
在我们的代码中运行
经过多次阅读,我构建了一个隔离区示例,并考虑向社区提供帮助。
假设有3个类:1个抽象(Class_A)和2个继承自它的类(Class_B / Class_C)。 Class_C有一个指向Class_B的单向指针 (我已经准备了一个图表,但该网站不会让我发布它: - /)。
注意:
hibernate.hbm2ddl.auto=update
开发。@Embeddable
。Class_A
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Class_A {
@Id
public long myId = 0;
}
Class_B
@Entity
@Table(name = "Class_B")
public class Class_B extends Class_A {
private String myString = "Hellos - I'm Class_B!";
}
Class_C
@Entity
@Table(name = "Class_C")
public class Class_C extends Class_A {
private String myString = "Hellos - I'm Class_C!";
@OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@NotNull
private Class_B classB;
public void setClassB(Class_B classB) {
this.classB = classB;
}
}
Hibernate代码
StatelessSession statelessSession = sessionFactory.openStatelessSession();
Class_C classC = new Class_C();
classC.myId = 92;
Class_B classB = new Class_B();
classB.myId = 8000;
classC.setClassB(classB);
statelessSession.beginTransaction();
statelessSession.insert(classC);
statelessSession.getTransaction().commit();
statelessSession.close();
在insert(classC)
Hibernate只发出一个SQL来插入Class_C。没有SQL来插入Class_B。我在Oracle中看到Class_C的详细信息,但Class_B的表是空的
这是SQL:
Hibernate:插入Class_C(classB_myId,myString,myId)值(?,?,?)
在getTransaction().commit()
,它会以
这样:
java.sql.BatchUpdateException: ORA-02291: integrity constraint (NDP.FK9619CF1CAD47EF0F) violated - parent key not found
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:17660)
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:771)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
at org.hibernate.impl.StatelessSessionImpl.managedFlush(StatelessSessionImpl.java:333)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
...
@GenerateValue
的{{1}}不予考虑。这是失败的原因吗?@Id
与@OneToOne(cascade = CascadeType.ALL)
+ @OneToOne
之间的区别是什么?非常感谢!
答案 0 :(得分:0)
我猜原因是
StatelessSession statelessSession = sessionFactory.openStatelessSession();
尝试使用普通Session
代替:
Session session = sessionFactory.openSession();
StatelessSession
是一种特殊目的工具,只能在特殊情况下使用。对于常规操作,您应始终使用Session
。来自Hibenrate文档:
或者,Hibernate提供了一个面向命令的API,可用于以分离对象的形式将数据流入和流出数据库。 StatelessSession没有与之关联的持久性上下文,也没有提供许多更高级别的生命周期语义。特别是,无状态会话不实现第一级缓存,也不与任何第二级或查询缓存交互。它不实现事务性后写或自动脏检查。 使用无状态会话执行的操作永远不会级联到关联的实例。
答案 1 :(得分:0)
请检查Hibernate文档。如上所述:
使用无状态会话执行的操作永远不会级联到关联的实例。 http://docs.jboss.org/hibernate/core/3.3/reference/en-US/html/batch.html#batch-statelesssession
使用 org.hibernate.StatelessSession ,您可以在插入对象时处理对象的相互依赖性。当您使用 org.hibernate.Session 时,情况并非如此。
在这种情况下,您必须将classB对象保留在 classC对象之前才能使其工作。坚持订单很重要。如果更改持久性顺序,则会出现 org.hibernate.exception.ConstraintViolationException 。请谨慎选择何时使用无状态会话,因为它没有持久性上下文。
statelessSession.beginTransaction();
statelessSession.insert(classB); // <- Persisting classB
statelessSession.insert(classC);
statelessSession.getTransaction().commit();
statelessSession.close();
使用Hibernate 3.6.0 Final + MySQL 5.0.51a-24进行测试