-->
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.  [ 2 posts ] 
Author Message
 Post subject: foreign key referencing nonprimary key issue with composites
PostPosted: Thu Jan 31, 2008 10:30 am 
Newbie

Joined: Thu Jan 31, 2008 7:45 am
Posts: 1
I've been trying to map part of a legacy database and have run across a problem when using a one-to-many mapping with a foreign key referencing a non-primary key.

All is fine as long as the class containing the collection uses a single primary key. When the class uses a composite key however the following stack trace occurs:

Quote:
org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of com.ri3k.domain.Foo$Id.id
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:86)
at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:353)
at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:184)
at org.hibernate.engine.EntityKey.generateHashCode(EntityKey.java:104)
at org.hibernate.engine.EntityKey.<init>(EntityKey.java:48)
at org.hibernate.engine.StatefulPersistenceContext.getCollectionOwner(StatefulPersistenceContext.java:678)
at org.hibernate.loader.Loader.readCollectionElement(Loader.java:993)
at org.hibernate.loader.Loader.readCollectionElements(Loader.java:646)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:591)
at org.hibernate.loader.Loader.doQuery(Loader.java:701)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1994)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:454)
at org.hibernate.engine.StatefulPersistenceContext.initializeNonLazyCollections(StatefulPersistenceContext.java:797)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:241)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1860)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:42)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3044)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:395)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:375)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:139)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:195)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:103)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:815)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:808)
at com.ri3k.dao.SyndicateLineDaoImpl.findFooById(SyndicateLineDaoImpl.java:17)
at com.ri3k.dao.FooBarDaoIntTest.testMappingForFooBarWorksCorrectly(FooBarDaoIntTest.java:40)
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 junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:81)
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: 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)
... 54 more



My failing test classes and their mappings are:

Failing foo class

Code:
public class Foo {
   
    public static class Id implements Serializable{
        private static final long serialVersionUID = 865226439037071749L;
               
        private Long id;
        private Long id2;
       
        public Id(Long id, Long id2){
            this.id = id;
            this.id2 = id2;
        }
       
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public Long getId2() {
            return id2;
        }
        public void setId2(Long id2) {
            this.id2 = id2;
        }
       
       
    }
   
    private Id id;
    private Set<Bar> foobar;
    private Long foobarId;

    public Long getFoobarId() {
        return foobarId;
    }

    public Set<Bar> getFoobar() {
        return foobar;
    }

    public void setFoobar(Set<Bar> foobar) {
        this.foobar = foobar;
    }

    public Id getId() {
        return id;
    }

    public void setId(Id id) {
        this.id = id;
    }
   

}


failing Foo mapping:

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

<hibernate-mapping package="com.ri3k.domain">

   <class name="Foo" table="foo">
      <composite-id name="id" class="com.ri3k.domain.Foo$Id">
         <key-property name="id" column="id" type="java.lang.Long"/>
         <key-property name="id2" column="id2" type="java.lang.Long"/>
      </composite-id>
      
      <set name="foobar" inverse="true" lazy="false" cascade="save-update">
         <key column="group_id" property-ref="foobarId"/>
         <one-to-many class="com.ri3k.domain.Bar"/>
      </set>
      
      <property name="foobarId" column="group_id" not-null="true" generated="insert" insert="false" update="false" access="field"/>
      
   </class>
      
</hibernate-mapping>



Bar class:

Code:
public class Bar {
   
    private Long fooBarId;
    private Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getFooBarId() {
        return fooBarId;
    }

    public void setFooBarId(Long fooBarId) {
        this.fooBarId = fooBarId;
    }

}


Bar mapping:

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

<hibernate-mapping>

   <class name="com.ri3k.domain.Bar" table="bar">
      
      <id name="id" column="id" type="java.lang.Long">
         <generator class="sequence">
            <param name="sequence">bar_seq</param>
         </generator>
      </id>
      
      <property name="fooBarId" column="group_id" />
      
   </class>
      
</hibernate-mapping>


and the successful versions of foo:



Code:
public class Foo {
   
    private Long id;
   
    private Set<Bar> foobar;
    private Long foobarId;

    public Long getFoobarId() {
        return foobarId;
    }

    public Set<Bar> getFoobar() {
        return foobar;
    }

    public void setFoobar(Set<Bar> foobar) {
        this.foobar = foobar;
    }

    public Long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }
   

}


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

<hibernate-mapping package="com.ri3k.domain">

   <class name="Foo" table="foo">
      <id name="id" column="id" type="java.lang.Long">
         <generator class="sequence">
            <param name="sequence">foo_seq</param>
         </generator>
      </id>
      
      <set name="foobar" inverse="true" lazy="false" cascade="save-update">
         <key column="group_id" property-ref="foobarId"/>
         <one-to-many class="com.ri3k.domain.Bar"/>
      </set>
      
      <property name="foobarId" column="group_id" not-null="true" generated="insert" insert="false" update="false" access="field"/>
      
   </class>
      
</hibernate-mapping>


Failing test case:

Code:
public class FooBarDaoIntTest extends AbstractDaoIntTest{
   
    FooBarDao fooBarDao = null;
   
    public void testMappingForFooBarWorksCorrectly() throws Exception {
        Long id = 1L;
        Long id2 = 4L;
        Long barId = 3L;
       
        Id fooId = new Foo.Id(id, id2);
       
        Foo foo= fooBarDao.findFooById(fooId);
        assertEquals(1, foo.getFoobar().size());
        assertEquals(barId, foo.getFoobar().iterator().next().getId());
    }
   
    public void setFooBarDao(FooBarDao fooBarDao) {
        this.fooBarDao = fooBarDao;
    }

}


Thanks for any help with this one


Top
 Profile  
 
 Post subject: Re: foreign key referencing nonprimary key issue with composites
PostPosted: Wed Jul 29, 2009 1:14 am 
Newbie

Joined: Tue Dec 09, 2008 6:55 am
Posts: 12
Hi,

I'm facing the same issue in Hibernate 3.3.1 GA. I was able to proceed on removing the not-null="true" attribute from the <key> element.

<bag name="addressList" cascade="delete" inverse="false">
<key property-ref="test" not-null="true">
<column name="CLIENTTYPECD" precision="20" scale="0"></column>
<column name="GENDERCD" precision="20" scale="0"></column>
</key>
<one-to-many class="com.hibernate.test.ClientAddressVO" />
</bag>

Should an issue be logged in Jira? I think this is a bug.


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