更新不存在的表 - 崩溃 ORA-00942

发布于 2024-10-18 17:37:49 字数 2649 浏览 2 评论 0原文

我们在 Hibernate 尝试更新一个不存在的表时遇到了奇怪的异常。以下是一个简单的示例(Hibernate 3.6.0 Final + Oracle 11g + Pure Java)。

这里 Class_A 是 TABLE_PER_CLASS 层次结构策略中的抽象(每个具体类一个表)。这是简单的版本,请告诉我我们的代码有什么问题:

Class_A

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Class_A {
    @Id
    @Column(name="blabla")
    public long myId = 0;
}

Class_B

@Entity
public class Class_B extends Class_A {
    private String myString = "Hellos - I'm Class_B!";
}

Class_C

@Entity
public class Class_C extends Class_A {
    private String myString = "Hellos - I'm Class_C!";

    @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn
    @OrderColumn(name="list_order")
    public List<Class_A> as;
}

代码

Class_C c = new Class_C();
c.myId = 92;
Class_B b = new Class_B();
b.myId = 10;
List<Class_A> bs = new ArrayList<Class_A>();
bs.add(0, b);
c.as = bs;

Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(c);
session.getTransaction().commit();
session.close();

崩溃

commit() 处,Hibernate 尝试以下 SQL:
Hibernate:更新 Class_A 设置为_blabla=?,list_order=? where blabla=?

然后崩溃:

java.sql.BatchUpdateException: ORA-00942: table or view does not exist

    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.engine.ActionQueue.executeActions(ActionQueue.java:268)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:188)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)

Hibernate 为什么这样做?

非常感谢!
- 十种

We've been getting a weird exception from Hibernate trying to update a non-existent table. Following is a simple example (Hibernate 3.6.0 Final + Oracle 11g + Pure Java).

Here Class_A is abstract in a TABLE_PER_CLASS hierarchy strategy (table per concrete class). Here's the simple version, please tell me what's wrong with our code:

Class_A

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Class_A {
    @Id
    @Column(name="blabla")
    public long myId = 0;
}

Class_B

@Entity
public class Class_B extends Class_A {
    private String myString = "Hellos - I'm Class_B!";
}

Class_C

@Entity
public class Class_C extends Class_A {
    private String myString = "Hellos - I'm Class_C!";

    @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn
    @OrderColumn(name="list_order")
    public List<Class_A> as;
}

Code

Class_C c = new Class_C();
c.myId = 92;
Class_B b = new Class_B();
b.myId = 10;
List<Class_A> bs = new ArrayList<Class_A>();
bs.add(0, b);
c.as = bs;

Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(c);
session.getTransaction().commit();
session.close();

Crash

At commit(), Hibernate tries this SQL:
Hibernate: update Class_A set as_blabla=?, list_order=? where blabla=?

Then crashes on:

java.sql.BatchUpdateException: ORA-00942: table or view does not exist

    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.engine.ActionQueue.executeActions(ActionQueue.java:268)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:188)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)

Why does Hibernate do this?

Much thanks!
- Ten of a Kind

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岛徒 2024-10-25 17:37:49

我认为您需要使关系成为双向的,并将一对多映射为多对一的逆关系。事实上,如果您查看 http ://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/inheritance.html#inheritance-limitations,您会注意到多态一对多仅限于 < code>inverse="true" 仅在每个具体类策略的表中。

因此,试试这个:

在 A 类中:

@ManyToOne
@JoinColumn
private Class_C c;

在 C 类中:

@OneToMany(mappedBy = "c")
private List<Class_A> as;

I think you need to make the relationships bidirectional, and map the one-to-many as the inverse relationship of the many-to-one. Indeed, if you look at http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/inheritance.html#inheritance-limitations, you'll note that polymorphic one-to-many is limited to inverse="true" only in the table per concrete-class strategy.

Thus, try this :

In class A :

@ManyToOne
@JoinColumn
private Class_C c;

In class C :

@OneToMany(mappedBy = "c")
private List<Class_A> as;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文