Christoph Watzl (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%...
) *updated* an issue
Hibernate ORM (
https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiODMxZjFhMjUw...
) / Bug (
https://hibernate.atlassian.net/browse/HHH-16007?atlOrigin=eyJpIjoiODMxZj...
) HHH-16007 (
https://hibernate.atlassian.net/browse/HHH-16007?atlOrigin=eyJpIjoiODMxZj...
) PropertyAccessException when deleting entities with Embeddables with child collections (
https://hibernate.atlassian.net/browse/HHH-16007?atlOrigin=eyJpIjoiODMxZj...
)
Change By: Christoph Watzl (
https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%...
)
We are currently trying to upgrade a project from Hibernate 5 to 6, which
When using an {{@Embedded}} value object that has a collection with orphan removal, trying
to delete the root entity throws a {{PropertyAccessException}}. The same scenario used to
work without issue in Hibernate 5.
I have prepared an [example test |https://github.com/cwatzl/hhh-16007]project to
demonstrate the issue.
Model:
{code:java}@Entity
public class Parent {
@Id
private final String id;
@Embedded
private final Child child;
// ... ctors & accessors ...
}
@Embeddable
public class Child {
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private final List<Grandchild> grandchildren = new ArrayList<>();
// ... ctors & accessors ...
}
@Entity
public class Grandchild {
@Id
private final String id;
// .. ctors & accessors ...
}{code}
Test case:
{code:java}var parent = new Parent("123", new Child(List.of(new
Grandchild("xyz"))));
entityManager.persist(parent);
entityManager.flush();
entityManager.clear();
entityManager.remove(entityManager.getReference(Parent.class, "123"));
entityManager.flush(); // throws PersistenceException{code}
*Exception thrown*
{noformat}jakarta.persistence.PersistenceException: Converting
`org.hibernate.property.access.spi.PropertyAccessException` to JPA `PersistenceException`
: Error accessing field [private final java.lang.String
org.hibernate.bugs.model.Parent.id] by reflection for persistent property
[org.hibernate.bugs.model.Parent#id] : org.hibernate.bugs.model.Child@77c66a4f
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:165)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:175)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:182)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1429)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1411)
at org.hibernate.bugs.JPAUnitTestCase.hhh123Test(JPAUnitTestCase.java:47)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at
com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at
com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: org.hibernate.property.access.spi.PropertyAccessException: Error accessing
field [private final java.lang.String org.hibernate.bugs.model.Parent.id] by reflection
for persistent property [org.hibernate.bugs.model.Parent#id] :
org.hibernate.bugs.model.Child@77c66a4f
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:48)
at
org.hibernate.metamodel.mapping.internal.BasicEntityIdentifierMappingImpl.getIdentifier(BasicEntityIdentifierMappingImpl.java:147)
at
org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:5254)
at
org.hibernate.engine.internal.Collections.processDereferencedCollection(Collections.java:70)
at
org.hibernate.engine.internal.Collections.processUnreachableCollection(Collections.java:49)
at
org.hibernate.event.internal.AbstractFlushingEventListener.lambda$flushCollections$1(AbstractFlushingEventListener.java:236)
at
org.hibernate.engine.internal.StatefulPersistenceContext.forEachCollectionEntry(StatefulPersistenceContext.java:1127)
at
org.hibernate.event.internal.AbstractFlushingEventListener.flushCollections(AbstractFlushingEventListener.java:233)
at
org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:91)
at
org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:38)
at
org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1425)
... 31 more
Caused by: java.lang.IllegalArgumentException: Can not set final java.lang.String field
org.hibernate.bugs.model.Parent.id to org.hibernate.bugs.model.Child
at
java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at
java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at
java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at
java.base/jdk.internal.reflect.UnsafeQualifiedObjectFieldAccessorImpl.get(UnsafeQualifiedObjectFieldAccessorImpl.java:38)
at java.base/java.lang.reflect.Field.get(Field.java:425)
at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:44)
... 42 more{noformat}
Of particular interest is this message:
{noformat}Can not set final java.lang.String field org.hibernate.bugs.model.Parent.id to
org.hibernate.bugs.model.Child{noformat}
Apparently, for some reason, {{AbstractEntityPersister}} is trying to reflectively access
the id property of the Parent entity but applies the getter to the embeddable child value
type, which makes no sense.
(
https://hibernate.atlassian.net/browse/HHH-16007#add-comment?atlOrigin=ey...
) Add Comment (
https://hibernate.atlassian.net/browse/HHH-16007#add-comment?atlOrigin=ey...
)
Get Jira notifications on your phone! Download the Jira Cloud app for Android (
https://play.google.com/store/apps/details?id=com.atlassian.android.jira....
) or iOS (
https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=Em...
) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100214- sha1:0a999ef )