[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-2432) Collection Mapping via "property-ref" on non-pk-column crashes

Oleg Gorobets (JIRA) noreply at atlassian.com
Sun Nov 11 19:45:29 EST 2007


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-2432?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_28781 ] 

Oleg Gorobets commented on HHH-2432:
------------------------------------

The bug still remains with 3.2.5 and tested with Oracle 10g.  I've created test case to reproduce the bug (see attach).

Seems like Hibernate couldn't determine collection owner when owner entity has a composite id and collection references owner with property-ref. 

To reproduce the bug:
1)	auto-create tables with hibernate.hbm2ddl.auto=update option
2)	fill in tables with test data (e.g one preference with several values) 
3)	try to load and read preference values from tables with simple code below (I've done this with Spring hibernate template).
 

UserPreference userPreference = (UserPreference) hibernateTemplate.loadAll(UserPreference.class).get(0);
System.out.println(userPreference.getValues());


Reading preference values will throw an exception:

org.hibernate.PropertyAccessException: could not get a field value by reflection getter of org.sibutu.kernel.security.entity.UserPreference$Id.userId
	at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:35)
	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.doList(Loader.java:2220)
	at org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2136)
	at org.hibernate.loader.Loader.list(Loader.java:2096)
	at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:94)
	at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1569)
	at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
	at org.springframework.orm.hibernate3.HibernateTemplate$5.doInHibernate(HibernateTemplate.java:520)
	at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:366)
	at org.springframework.orm.hibernate3.HibernateTemplate.loadAll(HibernateTemplate.java:516)

...

Caused by: java.lang.IllegalArgumentException
	at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(Unknown Source)
	at sun.reflect.UnsafeObjectFieldAccessorImpl.get(Unknown Source)
	at java.lang.reflect.Field.get(Unknown Source)
	at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:32)
	... 33 more



After some investigation:
When Loader class tries to get owner of collection with 

owner = persistenceContext.getCollectionOwner( collectionRowKey, persister );

at org.hibernate.loader.Loader.readCollectionElement(Loader.java:993)

it passes Long value (which is part of a primary key of AA_USER_PR_VALUES table) as collectionRowKey and then AbstractComponentTuplizer applies composite-id's getters (getUserId(),getKey()) on this Long value causing the exception

at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:64)


> Collection Mapping via "property-ref" on non-pk-column crashes
> --------------------------------------------------------------
>
>                 Key: HHH-2432
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2432
>             Project: Hibernate3
>          Issue Type: Bug
>          Components: core
>         Environment: 3.2.2, Sybase DB
>            Reporter: Stefan Krinkel
>
> Hi,
> when using the following example, Hibernate attempts to pull a "getTownId()" on an Integer!
> 2 Tables, Village and Councillor. Village has a comp. ID (TownId, VillageId), Councillor uses
> just the TownId-Part. To accomplish that, TOWN_ID is mapped twice (first in comp.key, second
> as "townCode"), to be able to do a 'property-ref'.
> When doing an ordinary "village.getCouncillors()" there's an IllegalArgumentException which
> roots to BasicPropertyAccessor.java:145
> 		public Object get(Object target) throws HibernateException {
> 			try {
> 				return method.invoke(target, null);
> 			}
> Here target is  (Integer) townId and method is "VillageId.getTownId".
>         <id name="id" type="integer">
>             <column name="COUNCILLOR_ID" />
>             <generator class="identity"/>
>         </id>
>         <property name="TOWN" type="integer" >
>             <column name="TOWN_ID" not-null="true" />
>         </property>
> ==============================================
>        <composite-id name="VillageId" class="Table1Id">
>             <key-property name="townId" type="integer">
>                 <column name="TOWN_ID" />
>             </key-property>
>             <key-property name="villageId" type="integer">
>                 <column name="VILLAGE_ID" />
>             </key-property>
>         </composite-id>   
> 	<property name="townCode" type="integer" insert="false" update="false">  
>             <column name="TOWN_ID" />
>         </property>
>         <bag name="councillors" outer-join="false" inverse="false"  >
>             <key property-ref="townCode">
>                 <column name="TOWN_ID" not-null="true" />
>             </key>
>             <one-to-many class="COUNCILLOR" />
>         </bag>
> Needless to say, it's a legacy database, so wildly changing tables is out of question for me, it has to
> work with hibernate.
> Thanks

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list