【问题标题】:Hibernate: java.sql.BatchUpdateException: ORA-01732 on immutable view休眠:java.sql.BatchUpdateException:不可变视图上的 ORA-01732
【发布时间】:2013-01-28 16:04:43
【问题描述】:

首先,请参阅 Hibernate 映射摘录:Oracle DB TABLE 中有可变的 ParentObjects 引用 Oracle DB VIEW 中的不可变 ChildObjects:

1)一个ParentObject里面有一组ChildObjectInView,定义为不可变,没有级联:

<class name="ParentObject" table="t_parentobject">
...
    <set name="childObjectsInView" cascade="none" lazy="true" mutable="false">
        <key column="coivId" />
        <one-to-many class="com.it.ChildObjectInView"/>
    </set>      
</class>

2) ChildObjectInView 定义为

<class name="ChildObjectInView" table="view_coiv" mutable="false" lazy="true">
...
    <many-to-one name="parentObject" column="parentObjectId" update="false" insert="false" class="com.it.ParentObject" not-null="true" outer-join="true">
    </many-to-one>

</class>

调用 com.it.TestServiceImpl.saveParentObject() 会导致 Oracle 错误 ORA-01732:数据操作操作在此视图上不合法,尽管 mutable="false" 属性在设置了休眠映射。为什么会出现这个错误?

com.it.TestBean|could not delete collection: [com.it.ParentObject.childObjectsInView#398500]
org.hibernate.exception.SQLGrammarException: could not delete collection: [com.it.ParentObject.childObjectsInView#398500]
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
        at org.hibernate.persister.collection.AbstractCollectionPersister.remove(AbstractCollectionPersister.java:1071)
        at org.hibernate.action.CollectionRemoveAction.execute(CollectionRemoveAction.java:28)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
        at com.it.TestServiceImpl.saveParentObject(TestServiceImpl.java:418)

Caused by: java.sql.BatchUpdateException: ORA-01732: data manipulation operation not legal on this view
        at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10296)
        at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:216)
        at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
        at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
        at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
        at org.hibernate.jdbc.BatchingBatcher.addToBatch(BatchingBatcher.java:34)
        at org.hibernate.persister.collection.AbstractCollectionPersister.remove(AbstractCollectionPersister.java:1048)
        ... 69 more

【问题讨论】:

    标签: oracle hibernate


    【解决方案1】:

    我终于自己发现了有ParentObject新创建的情况,集合ParentObject.childObjectsInView被设置为null

    保存这个新创建的ParentObject Hibernate 尝试运行DELETE FROM &lt;view&gt; WHERE id=&lt;objectid&gt;。这个语句就像是对ParentObject.childObjectsInView中的所有对象进行了重置。

    我认为这个 Hibernate 的默认行为在这个地方是错误的,应该打开一个错误报告:Hibernate 有这样的信息,即孩子是不可变的,因此应该禁止任何操纵 SQL。

    解决方法: 确保始终将空集合设置为 ParentObject.childObjectsInView(而不是 null)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多