I have a base class Location and a sub-class PointLocation. I'm using Table per Class strategy with the CAT_CODE column as the descriminator.
Both classes map to the LOC table which has a spatial column. I've created a view (LOC_VW) that transforms the spatial column into a latitude, longitude, altitude and is used for rehydrating the objects. I'm using the <sql-insert> tag to generate the SQL necessary to update the LOC table.
My problem is that Hibernate does not seem to be including the descriminator in the substitution. Thus, I receive a "not all variables bound" error from Oracle. This is confirmed with the use of p6spy. Below are snippets from the p6spy log file:
INSERT INTO LOC (OWNER_ID, UPDATE_SEQNR, LOCATION, LOC_ID, CAT_CODE) values (-1, -2, SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(-77.678, 35.777, 999.0), NULL, NULL), 105, null)
and
INSERT INTO LOC (CAT_CODE, OWNER_ID, UPDATE_SEQNR, LOCATION, LOC_ID) values (-1, 1, 35.777, SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(-77.678, 999.0, 113), NULL, NULL), null)
<NOTE: All other values are correct, if out of order. The NULL, NULL in the SDO_POINT_TYPE is correct>
I tried placing CAT_CODE at both the end and beginning and in both cases, the descriminator value "PT" show's up nowhere. This behavior seems inconsistent with my understanding of how descriminator values work with the default Hiberate mapping functionality.
Thanks,
Roy French
Hibernate version:
3.0 Alpha
Mapping documents:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Location" table="LOC_VW">
<id name="locId" type="long" column="LOC_ID">
<meta attribute="scope-set">private</meta>
<generator class="sequence">
<param name="sequence">loc_id_seq</param>
</generator>
</id>
<discriminator column="CAT_CODE" type="string"/>
<property name="ownerId"
type="long"
column="OWNER_ID"
not-null="true"
length="11">
<meta attribute="scope-set">private</meta>
</property>
<property name="updateSeqnr"
type="long"
column="UPDATE_SEQNR"
not-null="true"
length="15">
<meta attribute="scope-set">private</meta>
</property>
<subclass name="PointLocation"
discriminator-value="PT" >
<property name="longitude"
column="LONGITUDE"
type="double"
update="false"/>
<property name="latitude"
column="LATITUDE"
type="double"
update="false"/>
<property name="altitude"
column="ALTITUDE"
type="double"
update="false"/>
<sql-insert>INSERT INTO LOC (OWNER_ID, UPDATE_SEQNR, LOCATION, LOC_ID) values (?, ?, SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(?, ?, ?), NULL, NULL), ?)</sql-insert>
<sql-update>UPDATE LOC set OWNER_ID=?, UPDATE_SEQNR=?, LOCATION=SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(?, ?, ?) where LOC_ID=?</sql-update>
</subclass>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
Session s = factory.openSession();
s.beginTransaction();
s.save(obj);
s.commitTransaction();
s.close();
Full stack trace of any exception that occurs:
15:19:40,844 ERROR JDBCExceptionReporter:38 - could not insert: [com.saic.r2c2.bo.PointLocation#115]
java.sql.SQLException: ORA-01008: not all variables bound
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:573)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1891)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1093)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2047)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1940)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2709)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:589)
at com.p6spy.engine.logging.P6LogPreparedStatement.executeUpdate(P6LogPreparedStatement.java:183)
at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
at org.hibernate.persister.BasicEntityPersister.insert(BasicEntityPersister.java:1598)
at org.hibernate.persister.BasicEntityPersister.insert(BasicEntityPersister.java:1878)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:37)
at org.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:1224)
at org.hibernate.event.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:516)
at org.hibernate.event.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1191)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:61)
at test.LocalHibernateUtils.commitTransaction(LocalHibernateUtils.java:60)
at com.saic.r2c2.bo.TestLocation.testLocationInsert(TestLocation.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
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 junit.textui.TestRunner.doRun(TestRunner.java:116)
at junit.textui.TestRunner.doRun(TestRunner.java:109)
at junit.textui.TestRunner.run(TestRunner.java:72)
at junit.textui.TestRunner.run(TestRunner.java:57)
at com.saic.r2c2.bo.TestLocation.main(TestLocation.java:23)
Name and version of the database you are using:
Oracle 10g with Spatial
The generated SQL (show_sql=true):
Debug level Hibernate log excerpt:
|