Hi everybody,
I am working with hibernate 3.3, java 1.4 and oracle 10g.
I have a main class GlAccount.class, which is abstract, that is extended 2 times : LazyGlBsAccount.class and LazyGlPlAccount.class
To differentiate these subclasses, the column "ACCOUNT_TYPE" can be used as discriminator.
Code:
nms_gl_accounts
(gla_id NUMBER(10,0) NOT NULL,
account_type VARCHAR2(4) NOT NULL,
valid_from_date DATE NOT NULL,
valid_until_date DATE,
bf_flag VARCHAR2(2),
monetary_flag VARCHAR2(1),
cic_id NUMBER(10,0),
account_no VARCHAR2(10) NOT NULL,
coa_id NUMBER(10,0),
gla_id_first NUMBER(10,0),
gla_id_second NUMBER(10,0),
gla_id_forex_gain NUMBER(10,0),
gla_id_forex_loss NUMBER(10,0),
gla_id_mapped NUMBER(10,0),
keep_closing_forex VARCHAR2(1),
statutory_option VARCHAR2(5),
oslr_ibnr VARCHAR2(4))
But the problem is : this column may have 10 distinct values ('01AS','02LB','03EQ','03EX','03EY' refer to LazyGlBsAccount.class and '04IN','05EX','06FG','07FL','08FD' to LazyGlPlAccount.class).
So i tried the following solution (after looking at the documentation and several topic on this forum...) :
Code:
<hibernate-mapping>
<class name="com.XXX.XXX.XXX.GlAccount" table="NMS_GL_ACCOUNTS">
<cache usage="read-write"/>
<id name="id" type="long">
<column name="GLA_ID" precision="10" scale="0" />
<generator class="native">
<param name="sequence">NMS.GLACC_SEQ</param>
</generator>
</id>
<discriminator formula="case when ACCOUNT_TYPE in ('01AS','02LB','03EQ','03EX','03EY') then 'BS' else 'PL' end" type="string"/>
<property name="firstAccountIdLong" type="java.lang.Long">
<column name="GLA_ID_FIRST" precision="10" scale="0" />
</property>
<property name="coaIdLong" type="java.lang.Long">
<column name="COA_ID" precision="10" scale="0" />
</property>
<property name="cicIdLong" type="java.lang.Long">
<column name="CIC_ID" precision="10" scale="0" />
</property>
<property name="secondAccountIdLong" type="java.lang.Long">
<column name="GLA_ID_SECOND" precision="10" scale="0" />
</property>
<property name="accountType" type="string">
<column name="ACCOUNT_TYPE" length="4" not-null="true" />
</property>
<property name="validFromDate" type="date">
<column name="VALID_FROM_DATE" length="7" not-null="true" />
</property>
<property name="validUntilDate" type="date">
<column name="VALID_UNTIL_DATE" length="7" />
</property>
<property name="accountNo" type="string">
<column name="ACCOUNT_NO" length="10" not-null="true" />
</property>
<property name="mappedAccountIdLong" type="java.lang.Long">
<column name="GLA_ID_MAPPED" precision="10" scale="0" />
</property>
<property name="keepClosingForexBoolean" type="yes_no">
<column name="KEEP_CLOSING_FOREX" length="1" />
</property>
<property name="statutoryReportFlag" type="string">
<column name="STATUTORY_OPTION" length="5" />
</property>
<property name="oslrOrIbnr" type="string">
<column name="OSLR_IBNR" length="4" />
</property>
<subclass name="com.XXX.XXX.XXX.XXX.LazyGlBsAccount" discriminator-value="BS">
<property name="forexLossAccountIdLong" type="java.lang.Long">
<column name="GLA_ID_FOREX_LOSS" precision="10" scale="0" />
</property>
<property name="forexGainAccountIdLong" type="java.lang.Long">
<column name="GLA_ID_FOREX_GAIN" precision="10" scale="0" />
</property>
<property name="monetaryFlagBoolean" type="yes_no">
<column name="MONETARY_FLAG" length="1" />
</property>
</subclass>
<subclass name="com.XXX.XXX.XXX.XXX.LazyGlPlAccount" discriminator-value="PL">
<property name="bfFlag" type="string">
<column name="BF_FLAG" length="2" />
</property>
</subclass>
</class>
</hibernate-mapping>
And so this error occurs when i try to do a simple select on the table :
Code:
Caused by: java.sql.SQLException: invalid column name
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179)
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:269)
at oracle.jdbc.driver.OracleStatement.get_column_index(OracleStatement.java:5971)
at oracle.jdbc.driver.OracleResultSetImpl.findColumn(OracleResultSetImpl.java:1527)
at oracle.jdbc.driver.OracleResultSet.getString(OracleResultSet.java:1482)
at org.apache.tomcat.dbcp.dbcp.DelegatingResultSet.getString(DelegatingResultSet.java:224)
at org.hibernate.type.StringType.get(StringType.java:18)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:163)
at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:189)
at org.hibernate.loader.Loader.getInstanceClass(Loader.java:1442)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1284)
at org.hibernate.loader.Loader.getRow(Loader.java:1206)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:580)
at org.hibernate.loader.Loader.doQuery(Loader.java:701)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.doList(Loader.java:2220)
... 32 more
I don't know what to do. If someone have an idea for my problem or another way to map my subclass, it would be great.
I think that problem comes from discriminator because, if i modify data in 'ACCOUNT_TYPE' column by removing type '01AS','02LB','03EQ','03EX','03EY' and '04IN','05EX','06FG','07FL','08FD' by these 'BS' and 'PL' values and use a normal discriminator :
Code:
<discriminator type="string" column="ACCOUNT_TYPE"/>
All work fine. Of course modify data in database isn't an option...
Thank you in advance,
Regards
Fabrice