[hibernate-dev] Issue with unidirectional one-to-many association with a join column that references a column that is not the primary key
Vlad Mihalcea
mihalcea.vlad at gmail.com
Wed Feb 8 15:35:48 EST 2017
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(
> GetterFieldImpl.java:43)
> at
> org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue(
> AbstractComponentTuplizer.java:58)
> at org.hibernate.type.ComponentType.getPropertyValue(
> ComponentType.java:419)
> at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:242)
> at
> org.hibernate.engine.spi.CollectionKey.generateHashCode(
> CollectionKey.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.
> CollectionReferenceInitializerImpl.finishUpRow(
> CollectionReferenceInitializerImpl.java:105)
> at
> org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.readRow(
> AbstractRowReader.java:121)
> at
> org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails$
> EntityLoaderRowReader.readRow(EntityLoadQueryDetails.java:239)
> at
> org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.
> extractResults(ResultSetProcessorImpl.java:122)
> at
> org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.
> executeLoad(AbstractLoadPlanBasedLoader.java:122)
> at
> org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.
> executeLoad(AbstractLoadPlanBasedLoader.java:86)
> at
> org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(
> AbstractLoadPlanBasedEntityLoader.java:167)
> at
> org.hibernate.persister.entity.AbstractEntityPersister.load(
> AbstractEntityPersister.java:3967)
> at
> org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(
> DefaultLoadEventListener.java:508)
> at
> org.hibernate.event.internal.DefaultLoadEventListener.doLoad(
> DefaultLoadEventListener.java:478)
> at
> org.hibernate.event.internal.DefaultLoadEventListener.load(
> DefaultLoadEventListener.java:219)
> at
> org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(
> DefaultLoadEventListener.java:278)
> at
> org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(
> 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.throwSetIllegalArgumentExcepti
> on(UnsafeFieldAccessorImpl.java:164)
> at
> sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentExcepti
> on(UnsafeFieldAccessorImpl.java:168)
> at
> sun.reflect.UnsafeFieldAccessorImpl.ensureObj(
> UnsafeFieldAccessorImpl.java:55)
> at
> sun.reflect.UnsafeObjectFieldAccessorImpl.get(
> UnsafeObjectFieldAccessorImpl.java:36)
> at java.lang.reflect.Field.get(Field.java:379)
> at
> org.hibernate.property.access.spi.GetterFieldImpl.get(
> GetterFieldImpl.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().getCollectionType().
> 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