-->
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.  [ 1 post ] 
Author Message
 Post subject: Composite foreign key causing "object is not an instanc
PostPosted: Fri Sep 19, 2008 12:05 pm 
Newbie

Joined: Fri Sep 19, 2008 11:43 am
Posts: 3
I am using hibernate mapping files to map a couple of classes - twice. I have 2 classes: Event and SubEvent. SubEvent is a child of Event. I am having an issue with the mappings that are using a composite foreign key. When attempting to persist, I am consistently getting an exception with the message:
Quote:
object is not an instance of declaring class
-- More information provided below.

My java classes look like this:

Code:
public class Event implements Serializable
{
    private static final long serialVersionUID = 129372632456748684L;
   
    private String eventId;
    private int version;
    private String title;
    private Date date;
    private List<SubEvent> subEvents;

    public Event() {}

    public String getEventId() {
        return eventId;
    }

    public void setEventId(String eventId) {
        this.eventId = eventId;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getVersion()
    {
        return version;
    }

    public void setVersion(int version)
    {
        this.version = version;
    }

    public List<SubEvent> getSubEvents()
    {
        return subEvents;
    }

    public void setSubEvents(List<SubEvent> subEvents)
    {
        this.subEvents = subEvents;
    }
}


and SubEvent:

Code:
public class SubEvent implements Serializable
{
    private static final long serialVersionUID = 404876620876665712L;
    private String subEventId;
    private String subEventName;
    private Event parent;
   
    public String getSubEventId()
    {
        return subEventId;
    }
    public void setSubEventId(String subEventId)
    {
        this.subEventId = subEventId;
    }
    public String getSubEventName()
    {
        return subEventName;
    }
    public void setSubEventName(String subEventName)
    {
        this.subEventName = subEventName;
    }
    public Event getParent()
    {
        return parent;
    }
    public void setParent(Event parent)
    {
        this.parent = parent;
    }
}


I have two mapping files for the Event class:

Event.xml:

Code:
<?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="com.foo.jpa.hibernate.Event" table="EVENTS">
   <id name="eventId" column="event_id" type="string"/>
   <property name="version" column="version" type="int"/>
    <property name="date" type="timestamp" column="EVENT_DATE"/>
    <property name="title"/>
    <bag name="subEvents" cascade="all" lazy="false">
       <key>
          <column name="event_id" not-null="true"/>
       </key>
       <one-to-many class="com.foo.jpa.hibernate.SubEvent"/>
    </bag>
</class>
</hibernate-mapping>



And the other mapping file:
EventHistory.xml:

Code:
<?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="com.foo.jpa.hibernate.Event" table="EVENTS_HISTORY">
   <composite-id>
      <key-property name="eventId" column="event_id" type="string" length="36"/>
      <key-property name="version" column="version" type="int"/>
   </composite-id>
    <property name="date" type="timestamp" column="EVENT_DATE"/>
    <property name="title" type="string" length="200"/>
    <bag name="subEvents" cascade="all" lazy="false">
       <key>
          <column name="event_id" not-null="true"/>
           <column name="version" not-null="true"/>
       </key>
       <one-to-many class="com.foo.jpa.hibernate.SubEvent"/>
    </bag>
</class>
</hibernate-mapping>


SubEvent also has two mappings:

SubEvent.xml:

Code:
<?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="com.foo.jpa.hibernate.SubEvent" table="SUB_EVENTS">
   <id name="subEventId" column="sub_event_id" type="string"/>
   <many-to-one name="parent" cascade="all" class="com.foo.jpa.hibernate.Event" lazy="false" column="event_id" not-null="true"/>
   <property name="subEventName" column="sub_event_name" type="string"/>
</class>
</hibernate-mapping>


And SubEventHistory.xml:

Code:
<?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="com.foo.jpa.hibernate.SubEvent" table="SUB_EVENTS_HISTORY">
   <id name="subEventId" column="sub_event_id" type="string"/>
   <many-to-one name="parent" cascade="all" class="com.foo.jpa.hibernate.Event" lazy="false">
      <column name="event_id" not-null="true"/>
      <column name="version" not-null="true"/>
   </many-to-one>
   <property name="subEventName" column="sub_event_name" type="string"/>
</class>
</hibernate-mapping>


I am persisting events (with children subevents) and event histories (with children subevent histories) using 2 sessions.

I'm using the hibernate entity manager for persistence. My persistence.xml looks like this:

Code:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
    <persistence-unit name="PU_TEST1" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <mapping-file>Event.xml</mapping-file>
        <mapping-file>SubEvent.xml</mapping-file>
        <properties>
            <property name="hibernate.show_sql" value="false"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.connection.autocommit" value="false"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
            <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:medclaimdb"/>
            <property name="hibernate.connection.username" value="sa" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>           
        </properties>
    </persistence-unit>
    <persistence-unit name="PU_TEST2" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <mapping-file>EventHistory.xml</mapping-file>
        <mapping-file>SubEventHistory.xml</mapping-file>
        <properties>
            <property name="hibernate.show_sql" value="false"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.connection.autocommit" value="false"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
            <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:medclaimdb"/>
            <property name="hibernate.connection.username" value="sa" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
        </properties>
    </persistence-unit>
</persistence>


My persistence code looks similar to this:

Code:
// factory1 is associated with PU_TEST1
// factory 2 is associated with PU_TEST2

// Find the event.
EntityManager em1 = factory1.createEntityManager();
Event event = em1.find(Event.class, id);
em1.close();

// persist the history
EntityManager em2 = factory2.createEntityManager();
em2.getTransaction.begin();
// This line throws an exception!
em2.persist(event);
em2.getTransaction.commit();
em2.close();

// remove the event.
em1 = factory1.createEntityManager();
em1.getTransaction.begin();
em1.remove(event);
em1.getTransaction.commit();
em1.close();


As noted above, the line "em2.persist(event)" is throwing an exception. The stack is posted below:

Code:
javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of com.foo.jpa.hibernate.Event.eventId
   at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:614)
   at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:226)
   at com.foo.jpa.hibernate.EventService.deleteEvent(EventService.java:61)
   at com.foo.jpa.hibernate.EventServiceTest.testDelete(EventServiceTest.java:56)
   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.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
   at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
   at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
   at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
   at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
   at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
   at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
   at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
   at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
   at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
   at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
   at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
   at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of com.foo.jpa.hibernate.Event.eventId
   at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:195)
   at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:87)
   at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValues(AbstractComponentTuplizer.java:93)
   at org.hibernate.tuple.component.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:109)
   at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:376)
   at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:207)
   at org.hibernate.engine.CollectionKey.generateHashCode(CollectionKey.java:78)
   at org.hibernate.engine.CollectionKey.<init>(CollectionKey.java:66)
   at org.hibernate.engine.CollectionKey.<init>(CollectionKey.java:52)
   at org.hibernate.engine.StatefulPersistenceContext.addCollection(StatefulPersistenceContext.java:786)
   at org.hibernate.engine.StatefulPersistenceContext.addInitializedDetachedCollection(StatefulPersistenceContext.java:823)
   at org.hibernate.event.def.ProxyVisitor.reattachCollection(ProxyVisitor.java:88)
   at org.hibernate.event.def.WrapVisitor.processCollection(WrapVisitor.java:68)
   at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:124)
   at org.hibernate.event.def.WrapVisitor.processValue(WrapVisitor.java:121)
   at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:78)
   at org.hibernate.event.def.AbstractSaveEventListener.visitCollectionsBeforeSave(AbstractSaveEventListener.java:394)
   at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:296)
   at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
   at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
   at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:49)
   at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:154)
   at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:110)
   at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)
   at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:645)
   at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:619)
   at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:623)
   at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:220)
   ... 24 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:169)
   ... 51 more


As I said above, I really think this has something to do with the fact that the EventHistory.xml and SubEventHistory.xml uses a composite foreign key. When I removed the composite foreign key and simply used eventId as the foreign key, the code worked as expected. If anyone has any advice for me on what could be causing this I would greatly appreciate it, or if there is a better way to accomplish this same result. I'm not very familiar with using the hibernate mapping files. I was able to successfully use a composite foreign key as described above using JPA annotations (using @OneToMany and @ManyToOne annotations) and now that I am trying to switch over to hibernate mapping files I cannot get past this issue. Oh and before I forget, I am using hibernate-entitymanager-3.4.0.GA. Thanks in advance!


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

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.