-->
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.  [ 6 posts ] 
Author Message
 Post subject: IllegalArgumentException with component natural key
PostPosted: Tue Sep 11, 2007 12:24 am 
Regular
Regular

Joined: Thu Jul 29, 2004 11:55 pm
Posts: 75
We are using 3.2.3GA. This error is confounding us because the code works in our unit tests against HSQLDB, but gives an error under tomcat with oracle. I know there was a bug filed and it was rejected for similar symptoms. The error changes as we change the order of the fields and is always against the first field.

Mapping:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
  <class name="Flight" table="FLIGHT">
    <!-- The surrogate id -->
    <id name="surrogateId" column="mbl_flight_id" access="field">
      <generator class="sequence">
        <param name="sequence">FLIGHT_SEQ</param>
      </generator>
    </id>

    <!-- The flight key is the natural id -->
    <natural-id>
      <component name="flightKey" class="FlightKey" unique="true">
        <property name="airportCode" column="airport_code" not-null="true"/>
        <property name="airlineCode" column="airline_code" not-null="true"/>
                <property name="flightNumber" column="flight_number" not-null="true"/>
        <property name="departureDate" column="departure_date" not-null="true"/>
      </component>
    </natural-id>

    <!-- The current status reference into the status history -->
    <many-to-one name="currentStatus" column="flight_status_fk" access="field" foreign-key="flight_status_id"/>

    <!-- The flight status history -->
    <bag name="statusHistory" table="FLIGHT_STATUS" inverse="true" cascade="all" access="field">
      <key column="flight_fk" not-null="true"/>
      <one-to-many class="FlightStatus"/>
    </bag>

    <!-- one side of the many-to-many flight mapped with to customer flight as  id bag for cf id -->
    <bag name="customers" table="customer_flight" inverse="true">
      <key column="flight_fk"/>
      <one-to-many class="CustomerFlight"/>
    </bag>

  </class>
</hibernate-mapping>



FlightKey

Code:
public class FlightKey implements Serializable {
    /**
     * The airlince code.
     */
    private String airlineCode;
    /**
     * The flight number.
     */
    private int flightNumber;
    /**
     * The departure date.
     */
    private Date departureDate;
    /**
     * The departure airport code.
     */
    private String airportCode;


    public String getAirlineCode() {
        return airlineCode;
    }

    public void setAirlineCode(String airlineCode) {
        this.airlineCode = airlineCode;
    }

    public int getFlightNumber() {
        return flightNumber;
    }

    public void setFlightNumber(int flightNumber) {
        this.flightNumber = flightNumber;
    }

    public Date getDepartureDate() {
        return departureDate;
    }

    public void setDepartureDate(Date departureDate) {
        this.departureDate = departureDate;
    }

    public String getAirportCode() {
        return airportCode;
    }

    public void setAirportCode(String airportCode) {
        this.airportCode = airportCode;
    }
}


Code:
return get(Flight.class, createNaturalIdentifier().set("flightKey", flightKey));



Code:
Caused by: org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of FlightKey.airportCode
        at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:171)
        at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:64)
        at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValues(AbstractComponentTuplizer.java:70)
        at org.hibernate.tuple.component.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:83)
        at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:353)
        at org.hibernate.type.ComponentType.isEqual(ComponentType.java:123)
        at org.hibernate.event.def.DefaultFlushEntityEventListener.checkNaturalId(DefaultFlushEntityEventListener.java:86)
        at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:162)
        at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:113)
        at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:196)
        at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.j
ava:76)
        at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:35)
        at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:969)
        at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1562)
        at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
        at org.springframework.orm.hibernate3.HibernateTemplate$35.doInHibernate(HibernateTemplate.java:984)
        at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:372)
        ... 41 more
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
        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:585)
        at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:145)
        ... 57 more
                                                                                                          991,2-9       Bot

[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 11, 2007 3:23 am 
Regular
Regular

Joined: Thu Jul 29, 2004 11:55 pm
Posts: 75
I think this is a bug. After adding some extra debugging to the hibernate code, Hibernate is passing in an array of of the properties and trying to call the getter on the array instead of the containing object. Hopefully, I can show this with the stack trace:

Code:
[00:07:27.864] [WARN ] BasicPropertyAccessor - ON instance class FlightKey
ON instance class FlightKey
Property [0] is airlineCode
Property [1] is airportCode
Property [2] is flightNumber
Property [3] is departureDate
[00:07:27.864] [WARN ] BasicPropertyAccessor - Invoking method public java.lang.String FlightKey.getAirlineCode()
[00:07:27.864] [WARN ] BasicPropertyAccessor - from class class  FlightKey
[00:07:27.864] [WARN ] BasicPropertyAccessor - and property airlineCode
[00:07:27.864] [WARN ] BasicPropertyAccessor - ON instance class java.lang.String
[00:07:27.865] [WARN ] BasicPropertyAccessor - ON instance class java.lang.String
[00:07:27.865] [WARN ] BasicPropertyAccessor - ON instance class java.lang.Integer
[00:07:27.865] [WARN ] BasicPropertyAccessor - ON instance class java.sql.Timestamp
[00:07:27.865] [ERROR] BasicPropertyAccessor - IllegalArgumentException in class: FlightKey, getter method of property: airlineCode
[00:07:27.867] [DEBUG] JDBCTransaction - rollback
[00:07:27.873] [DEBUG] JDBCTransaction - re-enabling autocommit
[00:07:27.873] [DEBUG] JDBCTransaction - rolled back JDBC Connection
[00:07:27.873] [DEBUG] JDBCContext - after transaction completion
[00:07:27.873] [DEBUG] ConnectionManager - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
[00:07:27.874] [DEBUG] ConnectionManager - performing cleanup
[00:07:27.874] [DEBUG] ConnectionManager - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
[00:07:27.874] [DEBUG] JDBCContext - after transaction completion
[00:07:27.874] [DEBUG] ConnectionManager - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
[00:07:27.876] [ERROR] UpdateRequestProcessorChain - Error processing request
org.springframework.orm.hibernate3.HibernateSystemException: IllegalArgumentException occurred calling getter of FlightKey.airlineCode; nested exception is org.hibernate.PropertyAccessExce
Caused by:
org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of FlightKey.airlineCode
        at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:187)
        at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:66)
        at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValues(AbstractComponentTuplizer.java:79)
        at org.hibernate.tuple.component.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:86)
        at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:353)
        at org.hibernate.type.ComponentType.isEqual(ComponentType.java:123)
        at org.hibernate.event.def.DefaultFlushEntityEventListener.checkNaturalId(DefaultFlushEntityEventListener.java:93)
        at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:169)
        at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:120)
        at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:196)
        at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:76)
        at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:35)
        at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:969)
        at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1562)
        at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
        at org.springframework.orm.hibernate3.HibernateTemplate$35.doInHibernate(HibernateTemplate.java:984)
        at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:372)
        at org.springframework.orm.hibernate3.HibernateTemplate.findByCriteria(HibernateTemplate.java:974)
        at org.springframework.orm.hibernate3.HibernateTemplate.findByCriteria(HibernateTemplate.java:967)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
        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:585)
        at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:161)
        ... 57 more




The debugging code is this (pardon the lack of niceness):

BasicPropertyAccessor

Code:
      public Object get(Object target) throws HibernateException {
         try {
             log.warn("Invoking method " + method);
                log.warn("from class " + clazz);
                log.warn("and property " + propertyName);
                if (target.getClass().isArray()) {
                    for (Object targetx : (Object[])target) {
                       log.warn("ON instance " + targetx.getClass());
                    }
                } else {
                    log.warn("ON instance " + target.getClass());
                }

                return method.invoke(target, null);
         }
         catch (InvocationTargetException ite) {
            throw new PropertyAccessException(
                  ite,
                  "Exception occurred inside",
                  false,
                  clazz,
                  propertyName
               );
         }
         catch (IllegalAccessException iae) {
            throw new PropertyAccessException(
                  iae,
                  "IllegalAccessException occurred while calling",
                  false,
                  clazz,
                  propertyName
               );
            //cannot occur
         }
         catch (IllegalArgumentException iae) {
            log.error(
                  "IllegalArgumentException in class: " + clazz.getName() +
                  ", getter method of property: " + propertyName
               );
            throw new PropertyAccessException(
                  iae,
                  "IllegalArgumentException occurred calling",
                  false,
                  clazz,
                  propertyName
               );
         }
      }



AbstractComponentTuplizer:

Code:
       protected Component component;

   protected AbstractComponentTuplizer(Component component) {
        this.component = component;
        propertySpan = component.getPropertySpan();
      getters = new Getter[propertySpan];
      setters = new Setter[propertySpan];

      Iterator iter = component.getPropertyIterator();
      boolean foundCustomAccessor=false;
      int i = 0;
      while ( iter.hasNext() ) {
         Property prop = ( Property ) iter.next();
         getters[i] = buildGetter( component, prop );
         setters[i] = buildSetter( component, prop );
         if ( !prop.isBasicPropertyAccessor() ) {
            foundCustomAccessor = true;
         }
         i++;
      }
      hasCustomAccessors = foundCustomAccessor;

      String[] getterNames = new String[propertySpan];
      String[] setterNames = new String[propertySpan];
      Class[] propTypes = new Class[propertySpan];
      for ( int j = 0; j < propertySpan; j++ ) {
         getterNames[j] = getters[j].getMethodName();
         setterNames[j] = setters[j].getMethodName();
         propTypes[j] = getters[j].getReturnType();
      }
      instantiator = buildInstantiator( component );
   }


   public Object[] getPropertyValues(Object component) throws HibernateException {
        Iterator iter = this.component.getPropertyIterator();
        int j = 0;
        while ( iter.hasNext() ) {
            Property prop = ( Property ) iter.next();
            System.err.println("Property [" + j++ + "] is " + prop.getName());
        }

        Object[] values = new Object[propertySpan];
      for ( int i = 0; i < propertySpan; i++ ) {
         values[i] = getPropertyValue( component, i );
      }
      return values;
   }



Top
 Profile  
 
 Post subject:
PostPosted: Fri Apr 04, 2008 1:19 pm 
Newbie

Joined: Fri Feb 01, 2008 9:30 am
Posts: 2
I've just got hit by the issue with the same stack trace. Any ideas how to work around or fix it..?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 24, 2008 11:36 am 
Regular
Regular

Joined: Thu Jul 29, 2004 11:55 pm
Posts: 75
We decided not to cache on the natural id so we removed it and just modeled it as a component.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 08, 2008 1:56 am 
Newbie

Joined: Wed Oct 08, 2008 1:54 am
Posts: 14
Well this clearly seems to be a Bug or Issue in Hibernate to me - I came accross the same Problem and wondered if there is already a Bug/Task for which one can vote?


Top
 Profile  
 
 Post subject: Re: IllegalArgumentException with component natural key
PostPosted: Thu Aug 19, 2010 4:17 am 
Newbie

Joined: Fri Sep 09, 2005 11:09 am
Posts: 7
Location: Clermont-Ferrand
Hi,
did you find a solution? I've had the same issue... natura-id with a nested component doesn't work.
Did Hibernate team find a solution?
I'll have to remove the natural-id and keep the component.
Thanks

_________________
Mickael Gervais
Agaetis


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 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.