First of all I want to thank the Hibernate team for developing a great product that does a A+ job in solving the OR mapping problem.
We are currently facing this problem upgrading from 3.0.5 to 3.1.3. We are using the join tag to gather additional properties for our model object. The properties are being fetched from a view and hence need to be defined as readonly. We refered to Hibernate Manual (5.1.18) to define a joined property(s) as readonly ie inverse="true" on the join tag, and insert="false" update="false" on the property tags.
The below mapping
was working was in Hibernate 3.0.5. However, in
3.1.3 the mapping is trying to update entries in the view and is forcing the DB to throw a exception.
We are able to reproduce the problem via our junit tests w/o App server.
Mapping documents:
Code:
<hibernate-mapping package="dao.model" default-lazy="false">
<class name="dao.model.CodingItem" table="CODING_ITEM">
<id name="id" type="java.lang.Long" column="CODING_ITEM_ID">
<generator class="native">
<param name="sequence">CODING_ITEM_SEQ</param>
</generator>
</id>
<property name="name" type="java.lang.String" column="CODING_ITEM_NM" length="255" not-null="true"/>
<property name="label" type="java.lang.String" column="CODING_ITEM_LBL" length="255" not-null="true"/>
<property name="type" type="int" column="CODING_ITEM_TYP" not-null="true"/>
<set name="reviewTemplateCodingItems" cascade="delete" inverse="true">
<key column="CODING_ITEM_ID"/>
<one-to-many class="dao.model.ReviewTemplateCodingItem"/>
</set>
<set name="codingChoices" cascade="all-delete-orphan" inverse="true">
<key column="CODING_ITEM_ID"/>
<one-to-many class="dao.model.CodingChoice"/>
</set>
<join table="coding_item_usage_v" inverse="true">
<key column="cding_item_id"/>
<property name="numberOfTimesUsed" type="long" column="num_uses" insert="false" update="false"/>
</join>
</class>
</hibernate-mapping>
View sql:
create or replace view coding_item_usage_v
(
cding_item_id, -- had to change this from coding_item_id b/c sql generated by hiberate was causing ambiguous column reference. was working in hiber 3.0.5
num_uses
)
as
(
select ci.coding_item_id
,count(ca.coding_choice_id) as cc_use
from coding_item ci
inner join coding_choice cc on cc.coding_item_id = ci.coding_item_id
left outer join coding_answer ca on ca.coding_choice_id = cc.coding_choice_id
group by ci.coding_item_id
);
Code between sessionFactory.openSession() and session.close():Code:
StringBuffer hqlBuffer = new StringBuffer();
hqlBuffer.append(" delete ").append(className).append(" where id in (:ids)");
if (log.isDebugEnabled()) log.debug( "delete hql: "+ hqlBuffer.toString());
// perform delete
Query q = currentSession().createQuery(hqlBuffer.toString());
q.setParameterList("ids", getLongList(ids));
q.executeUpdate();
Full stack trace of any exception that occurs:
2006-07-20 14:59:36,969 DEBUG - [currentSession() -- client 'dao.manager.CodingItemHibernatePM' is using session w/ hashcode: 33212367. using connection: org.apache.commons.dbcp.PoolableConnection@6fd560]
2006-07-20 14:59:37,000 DEBUG - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
2006-07-20 14:59:37,000 DEBUG - insert into HT_CODING_ITEM select codingitem0_.CODING_ITEM_ID as CODING_ITEM_ID from CODING_ITEM codingitem0_ inner join coding_item_usage_v codingitem0_1_ on codingitem0_.CODING_ITEM_ID=codingitem0_1_.cding_item_id where CODING_ITEM_ID in (?)
2006-07-20 14:59:37,000 DEBUG - preparing statement
2006-07-20 14:59:37,000 DEBUG - binding '29' to parameter: 1
2006-07-20 14:59:37,016 DEBUG - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
2006-07-20 14:59:37,016 DEBUG - closing statement
2006-07-20 14:59:37,031 DEBUG - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
2006-07-20 14:59:37,031 DEBUG - delete from coding_item_usage_v where (cding_item_id) IN (select CODING_ITEM_ID from HT_CODING_ITEM)
2006-07-20 14:59:37,031 DEBUG - preparing statement
2006-07-20 14:59:37,031 DEBUG - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
2006-07-20 14:59:37,031 DEBUG - closing statement
2006-07-20 14:59:37,031 WARN - SQL Error: 1732, SQLState: 42000
2006-07-20 14:59:37,031 ERROR - ORA-01732: data manipulation operation not legal on this view
2006-07-20 14:59:37,031 DEBUG - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
2006-07-20 14:59:37,031 DEBUG - delete from HT_CODING_ITEM
2006-07-20 14:59:37,031 DEBUG - preparing statement
2006-07-20 14:59:37,031 DEBUG - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
2006-07-20 14:59:37,031 DEBUG - closing statement
2006-07-20 14:59:37,031 ERROR - Exception deleting objects with Ids: [Ljava.lang.String;@1d9d565 via Hibernate
com.renewdata.common.dao.DaoException: Exception deleting objects with Ids: [Ljava.lang.String;@1d9d565 via Hibernate
at com.renewdata.common.dao.AbstractHibernatePersistenceManager.deleteByIdArray(AbstractHibernatePersistenceManager.java:278)
at com.renewdata.common.dao.AbstractHibernatePersistenceManager.deleteById(AbstractHibernatePersistenceManager.java:253)
at com.renewdata.common.dao.AbstractHibernatePersistenceManager.deleteById(AbstractHibernatePersistenceManager.java:243)
at dao.CodingItemTest.testDelete(CodingItemTest.java:146)
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:324)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.hibernate.exception.SQLGrammarException: error performing bulk delete
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.hql.ast.exec.MultiTableDeleteExecutor.execute(MultiTableDeleteExecutor.java:124)
at org.hibernate.hql.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:334)
at org.hibernate.engine.query.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:209)
at org.hibernate.impl.SessionImpl.executeUpdate(SessionImpl.java:1126)
at org.hibernate.impl.QueryImpl.executeUpdate(QueryImpl.java:94)
at com.renewdata.common.dao.AbstractHibernatePersistenceManager.deleteByIdArray(AbstractHibernatePersistenceManager.java:274)
... 18 more
Caused by: java.sql.SQLException: ORA-01732: data manipulation operation not legal on this view
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:124)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:304)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:271)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:625)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:181)
at oracle.jdbc.driver.T4CPreparedStatement.execute_for_rows(T4CPreparedStatement.java:629)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1080)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:2904)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:2976)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:101)
at org.hibernate.hql.ast.exec.MultiTableDeleteExecutor.execute(MultiTableDeleteExecutor.java:115)
... 23 more
2006-07-20 14:59:37,047 DEBUG - [trxCommit() -- transaction was rolled back]
2006-07-20 14:59:37,047 DEBUG - closing session
2006-07-20 14:59:37,047 DEBUG - after transaction completion
2006-07-20 14:59:37,047 DEBUG - closing session
2006-07-20 14:59:37,047 DEBUG - after transaction completion
Name and version of the database you are using:
Oracle 10g[code]
Any help will be greatly appreciated.
Thanks,
Pratap.