Given
* An EntityA with OneToMany mapping to an EntityB * EntityB has 2 subclasses which maps the same column to different types and uses @Type annotation
When
* Loading EntityA and lazy loading EntityB collection
Then
* PropertyAccessException
{code:java}@Entity @Table(name = "ENTITY_A") public class EntityA {
@Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "ID") Integer id;
@OneToMany(mappedBy = "entityA") List<AbstractEntityB> entities = new ArrayList<>(); }{code}
{code:java}@Entity @Table(name = "ENTITY_B") @DiscriminatorColumn(name = "DISC_COL", discriminatorType = DiscriminatorType.INTEGER) public class AbstractEntityB {
@Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "ID") Integer id;
@JoinColumn(name = "ENTITY_A") @ManyToOne EntityA entityA; }{code}
{code:java}@Entity @DiscriminatorValue("1") public class EntityBChildOne extends AbstractEntityB {
@Column(name = "ACTION") @Type(ChildOneActionUserType.class) private ChildOneAction action;
public ChildOneAction getAction() { return action; }
public void setAction(ChildOneAction action) { this.action = action; }
public static enum ChildOneAction { ACTION_1, ACTION_2 }
public static class ChildOneActionUserType extends AbstractUserType<ChildOneAction> {
public ChildOneActionUserType() { super(ChildOneAction.class); } } }{code}
{code:java}@Entity @DiscriminatorValue("2") public class EntityBChildTwo extends AbstractEntityB {
@Column(name = "ACTION") @Type(ChildTwoActionUserType.class) private ChildTwoAction action;
public ChildTwoAction getAction() { return action; }
public void setAction(ChildTwoAction action) { this.action = action; }
static enum ChildTwoAction { ACTION_10, ACTION_20 }
public static class ChildTwoActionUserType extends AbstractUserType<ChildTwoAction> {
public ChildTwoActionUserType() { super(ChildTwoAction.class); } } }{code}
{code:java} @Test public void hhhXXXTest() throws Exception { // BaseCoreFunctionalTestCase automatically creates the SessionFactory and // provides the Session. try (Session s = openSession()) { Transaction tx = s.beginTransaction(); EntityA entityA1 = new EntityA(); EntityBChildOne childOne = new EntityBChildOne(); childOne.setAction(EntityBChildOne.ChildOneAction.ACTION_1); childOne.entityA = entityA1; entityA1.entities.add(childOne);
EntityA entityA2 = new EntityA(); EntityBChildTwo childTwo = new EntityBChildTwo(); childTwo.setAction(EntityBChildTwo.ChildTwoAction.ACTION_20); childTwo.entityA = entityA2; entityA2.entities.add(childTwo);
s.persist(entityA1); s.persist(childOne); s.persist(entityA2); s.persist(childTwo); tx.commit(); }
try (Session s = openSession()) { s.getSessionFactory().getCache().evictAllRegions(); Query<EntityA> query = s.createQuery("select c from EntityA c", EntityA.class); List<EntityA> actual = query.list();
assertThat(actual).hasSize(2); assertThat(actual.get(0).entities).hasSize(1); assertThat(actual.get(1).entities).hasSize(1); } }{code}
{noformat}bernate.PropertyAccessException: Could not set value of type [org.hibernate.bugs.EntityBChildOne$ChildOneAction] : `org.hibernate.bugs.EntityBChildTwo.action` (setter) at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:81) at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:4176) at org.hibernate.sql.results.graph.entity.AbstractEntityInitializer.initializeEntityInstance(AbstractEntityInitializer.java:832) at org.hibernate.sql.results.graph.entity.AbstractEntityInitializer.initializeEntity(AbstractEntityInitializer.java:792) at org.hibernate.sql.results.graph.entity.AbstractEntityInitializer.initializeInstance(AbstractEntityInitializer.java:778) at org.hibernate.sql.results.internal.InitializersList.initializeInstance(InitializersList.java:69) at org.hibernate.sql.results.internal.StandardRowReader.coordinateInitializers(StandardRowReader.java:111) at org.hibernate.sql.results.internal.StandardRowReader.readRow(StandardRowReader.java:87) at org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:179) at org.hibernate.sql.results.spi.ListResultsConsumer.consume(ListResultsConsumer.java:33) at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.doExecuteQuery(JdbcSelectExecutorStandardImpl.java:362) at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.executeQuery(JdbcSelectExecutorStandardImpl.java:168) at org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl.list(JdbcSelectExecutorStandardImpl.java:93) at org.hibernate.sql.exec.spi.JdbcSelectExecutor.list(JdbcSelectExecutor.java:31) at org.hibernate.loader.ast.internal.CollectionLoaderSingleKey.load(CollectionLoaderSingleKey.java:117) at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:702) at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:75) at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127) at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:1697) at org.hibernate.collection.spi.AbstractPersistentCollection.lambda$initialize$3(AbstractPersistentCollection.java:617) at org.hibernate.collection.spi.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:265) at org.hibernate.collection.spi.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:615) at org.hibernate.collection.spi.AbstractPersistentCollection.read(AbstractPersistentCollection.java:136) at org.hibernate.collection.spi.AbstractPersistentCollection.lambda$readSize$0(AbstractPersistentCollection.java:163) at org.hibernate.collection.spi.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:265) at org.hibernate.collection.spi.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:148) at org.hibernate.collection.spi.PersistentBag.size(PersistentBag.java:354) at org.assertj.core.util.IterableUtil.sizeOf(IterableUtil.java:50) at org.assertj.core.internal.Iterables.assertHasSize(Iterables.java:202) at org.assertj.core.api.AbstractIterableAssert.hasSize(AbstractIterableAssert.java:151) at org.hibernate.bugs.ORMUnitTestCase.hhhXXXTest(ORMUnitTestCase.java:91) 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.hibernate.testing.junit4.ExtendedFrameworkMethod.invokeExplosively(ExtendedFrameworkMethod.java:45) 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.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:299) at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:293) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: java.lang.IllegalArgumentException: Can not set org.hibernate.bugs.EntityBChildTwo$ChildTwoAction field org.hibernate.bugs.EntityBChildTwo.action to org.hibernate.bugs.EntityBChildOne$ChildOneAction 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.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) at java.base/java.lang.reflect.Field.set(Field.java:799) at org.hibernate.property.access.spi.SetterFieldImpl.set(SetterFieldImpl.java:53) ... 45 more {noformat}
Failing test scenario to be attached and also available here [https://github.com/ratoaq2/HHH-16398|https://github.com/ratoaq2/HHH-16398|smart-link] |
|