[hibernate-dev] Issue with unidirectional one-to-many association with a join column that references a column that is not the primary key

Marcello Romano marcello74 at gmail.com
Wed Feb 8 19:25:15 EST 2017


Hi Vlad,

I have created the following pull request with the test case:
https://github.com/hibernate/hibernate-orm/pull/1786

Thanks,
Marcello

On 8 February 2017 at 15:35, Vlad Mihalcea <mihalcea.vlad at gmail.com> wrote:

> Hi,
>
> You can send us a Pull Request on GitHub with a test case that replicates
> it, so we can discuss and integrate it.
>
> Vlad
>
> On Wed, Feb 8, 2017 at 10:11 PM, Marcello Romano <marcello74 at gmail.com>
> wrote:
>
>> Hi,
>>
>> A one-to-many association is causing Hibernate to
>> throw the following exception when loading an entity via
>> Session.get(domainClass, identifier), under the following conditions:
>>
>> 1. the association collection is annotated with @Fetch(FetchMode.JOIN)
>> 2. the association's join column is referencing a non-primary key of the
>> owning entity
>> 3. the association's join column value is referencing a non-existing
>> record
>> of the associated table (the "many" side).
>>
>> Caused by: org.hibernate.property.access.spi.PropertyAccessException:
>> Error
>> accessing field [protected java.lang.Long ...] by reflection for
>> persistent
>> property [...] : 1GBE4E1E04
>> at
>> org.hibernate.property.access.spi.GetterFieldImpl.get(Getter
>> FieldImpl.java:43)
>> at
>> org.hibernate.tuple.component.AbstractComponentTuplizer.getP
>> ropertyValue(AbstractComponentTuplizer.java:58)
>> at org.hibernate.type.ComponentType.getPropertyValue(ComponentT
>> ype.java:419)
>> at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:242)
>> at
>> org.hibernate.engine.spi.CollectionKey.generateHashCode(Coll
>> ectionKey.java:64)
>> at org.hibernate.engine.spi.CollectionKey.<init>(CollectionKey.java:58)
>> at org.hibernate.engine.spi.CollectionKey.<init>(CollectionKey.java:43)
>> at
>> org.hibernate.engine.loading.internal.CollectionLoadContext.
>> getLoadingCollection(CollectionLoadContext.java:95)
>> at
>> org.hibernate.loader.plan.exec.process.internal.CollectionRe
>> ferenceInitializerImpl.finishUpRow(CollectionReferenc
>> eInitializerImpl.java:105)
>> at
>> org.hibernate.loader.plan.exec.process.internal.AbstractRowR
>> eader.readRow(AbstractRowReader.java:121)
>> at
>> org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetai
>> ls$EntityLoaderRowReader.readRow(EntityLoadQueryDetails.java:239)
>> at
>> org.hibernate.loader.plan.exec.process.internal.ResultSetPro
>> cessorImpl.extractResults(ResultSetProcessorImpl.java:122)
>> at
>> org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBase
>> dLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122)
>> at
>> org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBase
>> dLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86)
>> at
>> org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntity
>> Loader.load(AbstractLoadPlanBasedEntityLoader.java:167)
>> at
>> org.hibernate.persister.entity.AbstractEntityPersister.load(
>> AbstractEntityPersister.java:3967)
>> at
>> org.hibernate.event.internal.DefaultLoadEventListener.loadFr
>> omDatasource(DefaultLoadEventListener.java:508)
>> at
>> org.hibernate.event.internal.DefaultLoadEventListener.doLoad
>> (DefaultLoadEventListener.java:478)
>> at
>> org.hibernate.event.internal.DefaultLoadEventListener.load(D
>> efaultLoadEventListener.java:219)
>> at
>> org.hibernate.event.internal.DefaultLoadEventListener.proxyO
>> rLoad(DefaultLoadEventListener.java:278)
>> at
>> org.hibernate.event.internal.DefaultLoadEventListener.doOnLo
>> ad(DefaultLoadEventListener.java:121)
>> at
>> org.hibernate.event.internal.DefaultLoadEventListener.onLoad
>> (DefaultLoadEventListener.java:89)
>> at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1129)
>> at org.hibernate.internal.SessionImpl.access$2600(SessionImpl.java:164)
>> at
>> org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.
>> load(SessionImpl.java:2696)
>> at org.hibernate.internal.SessionImpl.get(SessionImpl.java:975)
>> ...
>> Caused by: java.lang.IllegalArgumentException: Can not set ... to
>> java.lang.String
>> at
>> sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(
>> UnsafeFieldAccessorImpl.java:164)
>> at
>> sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(
>> UnsafeFieldAccessorImpl.java:168)
>> at
>> sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAcc
>> essorImpl.java:55)
>> at
>> sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFi
>> eldAccessorImpl.java:36)
>> at java.lang.reflect.Field.get(Field.java:379)
>> at
>> org.hibernate.property.access.spi.GetterFieldImpl.get(Getter
>> FieldImpl.java:39)
>> ... 44 more
>>
>>
>> The problem is that when initializing the collection, Hibernate is not
>> able
>> to retrieve the association key value in
>> CollectionReferenceInitializerImpl.finishUpRow and will fall back to use
>> the entity owner's primary key instead, causing the
>> IllegalArgumentException.
>>
>> We have noticed that there is a related open issue:
>> https://hibernate.atlassian.net/browse/HHH-9370
>>
>> We have worked around this issue by changing the way optionalKey is
>> retrieved in CollectionReferenceInitializerImpl.finishUpRow,
>> foreignKeyPropertyName );
>>
>> ResultSetProcessingContext.EntityReferenceProcessingState ownerState =
>> context.getOwnerProcessingState( (Fetch) collectionReference );
>> Serializable optionalKey =
>> collectionReference.getCollectionPersister().getCollectionTy
>> pe().getKeyOfOwner(ownerState.getEntityInstance(),
>> context.getSession());
>>
>>
>> Although this seems to work for us, we would like to collaborate to have
>> this fixed upstream, if you believe this is actually caused by a bug and
>> not by using Hibernate associations in the wrong way.
>>
>> Thanks,
>> Marcello
>> _______________________________________________
>> hibernate-dev mailing list
>> hibernate-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>
>
>


More information about the hibernate-dev mailing list