I have the following abstracts base classes:
{code:java}@MappedSuperclass public abstract class DomainEntityId implements Serializable {
private final Long value;
protected DomainEntityId() { this.value = RandomGenerator.getDefault().nextLong(); }
public Long getValue() { return value; } }{code}
{code:java}@MappedSuperclass public abstract class DomainEntityModel<ID extends DomainEntityId> {
@EmbeddedId @AttributeOverride(name = "value", column = @Column(name = "id")) private final ID id;
protected DomainEntityModel(ID id) { this.id = id; }
@NonNull public ID getId() { return id; } }{code}
and the following concrete entities:
{code:java}@Embeddable public class CustomerId extends DomainEntityId {}{code}
{noformat}@Entity public class Customer extends DomainEntityModel<CustomerId> {
private Integer code; private String name;
public Customer() { super(new CustomerId()); } // getters, setters, etc public Integer getCode() { return code; }
public void setCode(Integer code) { this.code = code; }
public String getName() { return name; }
public void setName(String name) { this.name = name; } }{ noformat}
{noformat}@Embeddable public class InvoiceId extends DomainEntityId {}{noformat}
{noformat}@Entity public class Invoice extends DomainEntityModel<InvoiceId> {
private Integer number;
@ManyToOne private Customer customer;
public Invoice() { super(new InvoiceId()); }
public Integer getNumber() { // getters, setters, etc return number; }
public void setNumber(Integer number) { this.number = number; }
public Customer getCustomer() { return customer; }
public void setCustomer(Customer customer) { this.customer = customer; } }{ noformat}
When I try to find invoices by customer id, I get the following exception:
{noformat}java.lang.IllegalArgumentException: Argument [org.hibernate.model.CustomerId@311a0b3e] of type [org.hibernate.model.CustomerId] did not match parameter type [org.hibernate.model.InvoiceId (n/a)]
at org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:84) at org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:31) at org.hibernate.query.internal.QueryParameterBindingImpl.validate(QueryParameterBindingImpl.java:339) at org.hibernate.query.internal.QueryParameterBindingImpl.setBindValue(QueryParameterBindingImpl.java:129) at org.hibernate.query.spi.AbstractCommonQueryContract.setParameter(AbstractCommonQueryContract.java:860) at org.hibernate.query.spi.AbstractSelectionQuery.setParameter(AbstractSelectionQuery.java:708) at org.hibernate.query.sqm.internal.QuerySqmImpl.setParameter(QuerySqmImpl.java:1263) at org.hibernate.query.sqm.internal.QuerySqmImpl.setParameter(QuerySqmImpl.java:131) at org.hibernate.bugs.JPAUnitTestCase.findByAssociationIdTest(JPAUnitTestCase.java:47) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) 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){noformat}
I’ve debug as I could and AFAICS, as both concrete entities share the same superclass, there is only one [MappedSuperclass|https://docs.jboss.org/hibernate/orm/6.1/javadocs/org/hibernate/mapping/MappedSuperclass.html] instance and the {{DeclaredIdentifierProperty}} is being replaced with the id of the last entity. After, this id is used to validate the query parameter value and they are incompatibles.
There is a similar problem [https://hibernate.atlassian.net/browse/HHH-11955|https://hibernate.atlassian.net/browse/HHH-11955|smart-link], although I’m not sure that is exactly the same.
Here is a test case demonstrating this issue in Hibernate 6 [https://github.com/franciscosousabr/test-case-template-hibernate-orm6|https://github.com/franciscosousabr/test-case-template-hibernate-orm6|smart-link] and here is a test case demonstrating the same code working in Hibernate 5 [https://github.com/franciscosousabr/test-case-template-hibernate-orm5|https://github.com/franciscosousabr/test-case-template-hibernate-orm5|smart-link] |
|