-->
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.  [ 3 posts ] 
Author Message
 Post subject: one-to-many with property-ref + composite id
PostPosted: Wed Aug 10, 2005 6:25 pm 
Newbie

Joined: Wed Aug 10, 2005 2:36 pm
Posts: 3
Hi,

I afraid I am having problems loading an entity which one-to-many relationship and is composite keyed.

I deliberately map one property in the composite key object just to simplify the example.

After some debugging, it seems that at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:34):
Quote:
field.get(target)

where field is parentCode (property in composite-id), and target is the value of parentName (property-ref in the one-to-many relationship, a String), and hence the
IllegalArgumentException.

Wondering if there is a work around?

Many thanks in advanced.

Hibernate version:
3.0.5 / 3.1beta2

Mapping documents:
Code:
    <class name="spikes.entities.Parent" table="parent" >
<!--   If compsite-id element is replaced normal key, it works perfectly fine.-->
<!--
        <id name="parentCode" access="field">
            <generator class="assigned"/>
        </id>
-->
        <composite-id name="compId" access="field" class="spikes.entities.ParentCompositeId">
            <key-property name="parentCode" length="8" access="field"/>
        </composite-id>
        <property name="parentName" length="100" access="field"/>

        <set name="children" inverse="true" access="field" cascade="all" >
            <key column="parent_name" property-ref="parentName"/>
            <one-to-many class="spikes.entities.Child"/>
        </set>
    </class>

Code:
    <class name="spikes.entities.Child" table="child">
        <id name="childId" access="field">
            <generator class="native"/>
        </id>
        <many-to-one name="parent" column="parent_name" property-ref="parentName" access="field" />
    </class>


Code between sessionFactory.openSession() and session.close():
Code:
    public void testLoadParent() {
        Parent parent = new Parent("Code: "+RandomStringUtils.randomAlphanumeric(3), "Name: "+RandomStringUtils.randomAlphanumeric(10));
        // setting up bidirectional relationship below.
        parent.addChild(new Child());

        Serializable parentId = getHibernateTemplate().save(parent);
        getHibernateTemplate().flush();
        getHibernateTemplate().clear();

        Parent loadedParent = (Parent) getHibernateTemplate().load(Parent.class, parentId);
        // exception happens below when children are loaded
        assertFalse("not empty", loadedParent.getChildren().isEmpty());

    }


Full stack trace of any exception that occurs:
Code:
org.hibernate.PropertyAccessException: could not get a field value by reflection getter of spikes.entities.ParentCompositeId.parentCode
   at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:34)
   at org.hibernate.tuple.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:61)
   at org.hibernate.tuple.AbstractComponentTuplizer.getPropertyValues(AbstractComponentTuplizer.java:67)
   at org.hibernate.tuple.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:50)
   at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:257)
   at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:158)
   at org.hibernate.engine.EntityKey.getHashCode(EntityKey.java:68)
   at org.hibernate.engine.EntityKey.<init>(EntityKey.java:41)
   at  org.hibernate.engine.PersistenceContext.getCollectionOwner(PersistenceContext.java:674)
   at org.hibernate.loader.Loader.readCollectionElement(Loader.java:660)
   at org.hibernate.loader.Loader.readCollectionElements(Loader.java:370)
   at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:314)
   at org.hibernate.loader.Loader.doQuery(Loader.java:412)
   at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:218)
   at org.hibernate.loader.Loader.loadCollection(Loader.java:1434)
   at org.hibernate.loader.collection.OneToManyLoader.initialize(OneToManyLoader.java:111)
   at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:488)
   at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
   at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1430)
   at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:176)
   at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:48)
   at org.hibernate.collection.PersistentSet.isEmpty(PersistentSet.java:118)
   at spikes.entities.ParentHibernateLookupIntegrationTest.testLoadParent(ParentHibernateLookupIntegrationTest.java:20)
Caused by: java.lang.IllegalArgumentException
   at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
   at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:18)
   at java.lang.reflect.Field.get(Field.java:228)
   at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:31)
   ... 45 more


Name and version of the database you are using:
hsqldb


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 12, 2005 6:00 pm 
Senior
Senior

Joined: Tue Jan 11, 2005 5:03 pm
Posts: 137
Location: Montreal, Quebec
The way I would do my test would be like that. I am not sure it is perfect because I didn't validate it.

Code:


public void testLoadParent() {

String code  = "Code: "+RandomStringUtils.randomAlphanumeric(3);
        Parent parent = new Parent(code, "Name: "+RandomStringUtils.randomAlphanumeric(10));
        // setting up bidirectional relationship below.
        parent.addChild(new Child());

  ParentCompositeId parentId = new ParentCompositeId(code); // create a constructor here...
        getHibernateTemplate().flush();
        getHibernateTemplate().clear();

        Parent loadedParent = (Parent) getHibernateTemplate().load(Parent.class, parentId);
        // exception happens below when children are loaded
        assertFalse("not empty", loadedParent.getChildren().isEmpty());

    }



Hope it helped.

Etienne.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Aug 14, 2005 4:27 pm 
Newbie

Joined: Wed Aug 10, 2005 2:36 pm
Posts: 3
etienne,

Thanks very much for your reply. But first of all let me clarify what the test intends to do:
- creates a parent
- add a child to the parent
- save it to the database with code:
Code:
Serializable parentId = getHibernateTemplate().save(parent);

- flush & clear session, make sure Insert is issue to the database, and any load after that would not hit the session cache.
- reload parent, and hopefully I can get the child back.

I believe replacing the save with the line you suggest would not quite help the problem. But I very much appreciate your reply. ;)


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