Having had no success with a "one to zero or one" mapping, I am hoping someone out there can explain where I am going wrong.
I have simplified the code down to the bare bones of 2 tables Tia00571 and Tia00573 which have an identical composite id of CLAIM_CASE_NUMBER and CNTR_ID.
When I try and get data from Tia00571 with the following...
Code:
Session session = null;
Transaction tran = null;
String query = "from myapp.Tia00571 as tia00571"; // order by tia00571.prodId
List rows = null;
int j = 50;
try {
session = HibernateUtil.currentSession();
tran = session.beginTransaction();
rows = session.find(query);
for (Iterator i = rows.iterator(); i.hasNext();) {
Tia00571 row = (Tia00571)i.next();
if (j-- > 0) {
log.debug(row.getComp_id() + " : " + row.getInceptionDate());
}
}
log.debug("...Maximum of 50 rows printed, there may be more.");
}
catch (HibernateException e) {
tran.rollback();
log.error("HibernateException caught ", e);
throw new RuntimeException("HibernateException caught: " + e);
}
finally {
tran.commit();
HibernateUtil.closeSession();
}
...,I get the following exception...
Code:
18:30:24,453 DEBUG - Entered Tia00571TestCase.testGetAllRows()
18:30:24,484 INFO - Hibernate 2.1.2
18:30:24,484 INFO - loaded properties from resource hibernate.properties: {hibernate.cglib.use_reflection_optimizer=false}
18:30:24,484 INFO - JVM does not support Statement.getGeneratedKeys()
18:30:24,484 INFO - JVM does not support LinkedHasMap, LinkedHashSet - ordered maps and sets disabled
18:30:24,484 INFO - using workaround for JVM bug in java.sql.Timestamp
18:30:24,484 INFO - configuring from resource: /hibernate.cfg.xml
18:30:24,484 INFO - Configuration resource: /hibernate.cfg.xml
18:30:25,531 INFO - Mapping resource: myapp/Tia00571.hbm.xml
18:30:26,469 INFO - Mapping class: myapp.hibernate.Tia00571 -> TIA00571
18:30:26,719 INFO - Mapping resource: myapp/Tia00573.hbm.xml
18:30:27,406 INFO - Mapping class: myapp.Tia00573 -> TIA00573
18:30:27,438 INFO - Configured SessionFactory: hibernate/SessionFactory
18:30:27,438 INFO - processing one-to-many association mappings
18:30:27,438 INFO - processing one-to-one association property references
18:30:27,438 INFO - processing foreign key constraints
18:30:27,484 INFO - Using dialect: net.sf.hibernate.dialect.DB2Dialect
18:30:27,484 INFO - Use outer join fetching: false
18:30:27,484 INFO - JNDI InitialContext properties:{}
18:30:28,438 INFO - Using datasource: jdbc/myapp/MYAPP_DS
18:30:28,438 INFO - instantiating TransactionManagerLookup: net.sf.hibernate.transaction.WebSphereTransactionManagerLookup
18:30:28,453 INFO - instantiated TransactionManagerLookup
18:30:30,047 INFO - Use scrollable result sets: true
18:30:30,047 INFO - Use JDBC3 getGeneratedKeys(): false
18:30:30,047 INFO - Optimize cache for minimal puts: false
18:30:30,047 INFO - Query language substitutions: {}
18:30:30,047 INFO - cache provider: net.sf.ehcache.hibernate.Provider
18:30:30,047 INFO - instantiating and configuring caches
18:30:30,078 INFO - building session factory
18:30:31,625 INFO - Factory name: hibernate/SessionFactory
18:30:31,625 INFO - JNDI InitialContext properties:{}
18:30:31,641 INFO - Bound factory to JNDI name: hibernate/SessionFactory
18:30:31,641 WARN - InitialContext did not implement EventContext
18:30:31,688 INFO - WebSphere 4
18:30:31,906 ERROR - IllegalArgumentException in class: myapp.Tia00573PK, getter method of property: claimCaseNumber
18:30:31,938 ERROR - HibernateException caught
net.sf.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of myapp.Tia00573PK.claimCaseNumber
at net.sf.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:110)
at net.sf.hibernate.type.ComponentType.getPropertyValue(ComponentType.java:179)
at net.sf.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:205)
at net.sf.hibernate.type.ComponentType.nullSafeGetValues(ComponentType.java:164)
at net.sf.hibernate.type.ComponentType.nullSafeSet(ComponentType.java:151)
at net.sf.hibernate.loader.Loader.bindPositionalParameters(Loader.java:674)
at net.sf.hibernate.loader.Loader.prepareQueryStatement(Loader.java:713)
...more
at myapp.test.Tia00571TestCase.main(Tia00571TestCase.java:307)
Caused by:
java.lang.IllegalArgumentException: object is not an instance of declaring class
at java.lang.reflect.Method.invoke(Native Method)
at net.sf.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:96)
... 42 more
18:30:31,953 DEBUG - Entered Tia00571TestCase.testCountAllRows()
18:30:31,953 DEBUG - Tia00571 rows = 59
I am stumped as to the reason it's failing. I have debugged it and it is failing when calling the
getClaimCaseNumber() method on myapp.Tia00573PK, which to me is a valid method.
When method.invoke(target, null); on net.sf.hibernate.property.BasicGetter().get(Object target) is called
the following values are to be found...
method=public java.lang.Integer myapp.Tia00573PK.getClaimCaseNumber()
target=myapp.Tia00571PK
I have provided the 2 mapping files and the 2 generated PK files.
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin
http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->
<class
name="myapp.Tia00571"
table="TIA00571"
schema="MYAPP"
proxy="myapp.Tia00571"
>
<composite-id name="comp_id" class="myapp.Tia00571PK">
<key-property name="claimCaseNumber" column="CLAIM_CASE_NUMBER" type="java.lang.Integer" length="10"/>
<key-property name="cntrId" column="CNTR_ID" type="java.lang.String" length="10"/>
</composite-id>
<!-- associations -->
<!-- bi-directional one-to-one association to Tia00573 -->
<one-to-one name="tia00573" class="myapp.Tia00573" outer-join="auto"
/>
</class>
</hibernate-mapping>
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin
http://boss.bekk.no/boss/middlegen/
http://hibernate.sourceforge.net/
-->
<class
name="myapp.Tia00573"
table="TIA00573"
schema="MYAPP"
proxy="myapp.Tia00573"
>
<composite-id name="comp_id" class="myapp.Tia00573PK">
<key-property name="claimCaseNumber" column="CLAIM_CASE_NUMBER" type="java.lang.Integer" length="10"/>
<key-property name="cntrId" column="CNTR_ID" type="java.lang.String" length="10"/>
</composite-id>
<!-- associations -->
<!-- bi-directional one-to-one association to Tia00571 -->
<one-to-one name="tia00571" class="myapp.Tia00571" outer-join="auto" constrained="true"/>
</class>
</hibernate-mapping>
Code:
package myapp.hibernate;
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
/** @author Hibernate CodeGenerator */
public class Tia00571PK implements Serializable {
/** identifier field */
private Integer claimCaseNumber;
/** identifier field */
private String cntrId;
/** full constructor */
public Tia00571PK(Integer claimCaseNumber, String cntrId) {
this.claimCaseNumber = claimCaseNumber;
this.cntrId = cntrId;
}
/** default constructor */
public Tia00571PK() {
}
public Integer getClaimCaseNumber() {
return this.claimCaseNumber;
}
public void setClaimCaseNumber(Integer claimCaseNumber) {
this.claimCaseNumber = claimCaseNumber;
}
public String getCntrId() {
return this.cntrId;
}
public void setCntrId(String cntrId) {
this.cntrId = cntrId;
}
public String toString() {
return new ToStringBuilder(this)
.append("claimCaseNumber", getClaimCaseNumber())
.append("cntrId", getCntrId())
.toString();
}
public boolean equals(Object other) {
if ( !(other instanceof Tia00571PK) ) return false;
Tia00571PK castOther = (Tia00571PK) other;
return new EqualsBuilder()
.append(this.getClaimCaseNumber(), castOther.getClaimCaseNumber())
.append(this.getCntrId(), castOther.getCntrId())
.isEquals();
}
public int hashCode() {
return new HashCodeBuilder()
.append(getClaimCaseNumber())
.append(getCntrId())
.toHashCode();
}
}
Code:
package myapp.hibernate;
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
/** @author Hibernate CodeGenerator */
public class Tia00573PK implements Serializable {
/** identifier field */
private Integer claimCaseNumber;
/** identifier field */
private String cntrId;
/** full constructor */
public Tia00573PK(Integer claimCaseNumber, String cntrId) {
this.claimCaseNumber = claimCaseNumber;
this.cntrId = cntrId;
}
/** default constructor */
public Tia00573PK() {
}
public Integer getClaimCaseNumber() {
return this.claimCaseNumber;
}
public void setClaimCaseNumber(Integer claimCaseNumber) {
this.claimCaseNumber = claimCaseNumber;
}
public String getCntrId() {
return this.cntrId;
}
public void setCntrId(String cntrId) {
this.cntrId = cntrId;
}
public String toString() {
return new ToStringBuilder(this)
.append("claimCaseNumber", getClaimCaseNumber())
.append("cntrId", getCntrId())
.toString();
}
public boolean equals(Object other) {
if ( !(other instanceof Tia00573PK) ) return false;
Tia00573PK castOther = (Tia00573PK) other;
return new EqualsBuilder()
.append(this.getClaimCaseNumber(), castOther.getClaimCaseNumber())
.append(this.getCntrId(), castOther.getCntrId())
.isEquals();
}
public int hashCode() {
return new HashCodeBuilder()
.append(getClaimCaseNumber())
.append(getCntrId())
.toHashCode();
}
}
Could someone reproduce this and let me know if I have something set incorrectly.
Best Regards
Chris