-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 
Author Message
 Post subject: IllegalArgumentException in One-to-one-or-zero mapping
PostPosted: Fri Mar 19, 2004 2:49 pm 
Beginner
Beginner

Joined: Mon Nov 24, 2003 12:44 pm
Posts: 40
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


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 19, 2004 2:52 pm 
Beginner
Beginner

Joined: Mon Nov 24, 2003 12:44 pm
Posts: 40
I forgot to mention that if a row exists on TIA00573 there will always be a matching row on TIA00571 for that key, but not vice versa.
Basically TIA00573 is an extension table for TIA00571.

Chris


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 22, 2004 5:56 am 
Beginner
Beginner

Joined: Mon Nov 24, 2003 12:44 pm
Posts: 40
I think I have solved it. I made the composite-id class of Tia00573 the same class as the composite-id of Tia00571. i.e. They share the same class... myapp.Tia00571PK.

Code:
<class
    name="myapp.Tia00573"
    table="TIA00573"
    schema="MYAPP"
    proxy="myapp.Tia00573"
>

    <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>   


My tests now work. Is this the correct solution or is it a strange workaround I have stumbled upon?

Regards
Chris


Top
 Profile  
 
 Post subject:
PostPosted: Wed Sep 29, 2004 7:19 am 
Newbie

Joined: Wed Sep 01, 2004 9:04 am
Posts: 18
Location: Enschede, Netherlands
I've had the same problem and searched for the solution for some hours now.

I have two objects (A and B) with a one-to-one relation. Both have a composite-id as primary key. Middlegen generates two different PK classes, but using CGLIB I get a PropertyAccessException caused by a ClassCastException.

Having the two objects use the same PK class for the composite-id solves the problem.

Is that the correct way to solve the problem? (It makes sense to me that a one-to-one relation requires both composite-id's to be the same class.)


Top
 Profile  
 
 Post subject: Similar, but different issue
PostPosted: Wed Mar 08, 2006 11:26 am 
Regular
Regular

Joined: Wed Dec 21, 2005 6:57 pm
Posts: 70
I had a similar error (in jdk5/Hibernate 3 it is a ClassCastException when invoking the method) when I built a query or criterion wrong.

I meant to query on "A.B.uniqueID", but instead used a field "A.B" in the query. This resulted in hibernate using reflection to invoke the getUniqueID() method on java.lang.String.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.