[JIRA] (HHH-15972) entitygraph load error when Inheritance JOINED is used in 6.1.6
by Theodoros Papatheodorou (JIRA)
Theodoros Papatheodorou ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=70121%3... ) *updated* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiODZlMjc0MGVk... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-15972?atlOrigin=eyJpIjoiODZlMj... ) HHH-15972 ( https://hibernate.atlassian.net/browse/HHH-15972?atlOrigin=eyJpIjoiODZlMj... ) entitygraph load error when Inheritance JOINED is used in 6.1.6 ( https://hibernate.atlassian.net/browse/HHH-15972?atlOrigin=eyJpIjoiODZlMj... )
Change By: Theodoros Papatheodorou ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=70121%3... )
Exception occurs with the use of entitygraph loadgraph in case InheritanceType.JOINED is used and the parent class is queried (testcase attached).
{noformat}java.lang.IllegalArgumentException: org.hibernate.query.SemanticException: Could not resolve attribute 'status' of 'org.hibernate.bugs.Account' due to the attribute being declared in multiple sub types: ['org.hibernate.bugs.Account1', 'org.hibernate.bugs.Account2']
at org.hibernate.metamodel.model.domain.AbstractManagedType.findAttribute(AbstractManagedType.java:178)
at org.hibernate.metamodel.model.domain.internal.EntityTypeImpl.findAttribute(EntityTypeImpl.java:143)
at org.hibernate.graph.internal.AbstractGraph.findAttributeNode(AbstractGraph.java:142)
at org.hibernate.sql.results.internal.StandardEntityGraphTraversalStateImpl.traverse(StandardEntityGraphTraversalStateImpl.java:54)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.addFetch(BaseSqmToSqlAstConverter.java:6937)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitFetches(BaseSqmToSqlAstConverter.java:7099)
at org.hibernate.sql.results.graph.AbstractFetchParent.afterInitialize(AbstractFetchParent.java:32)
at org.hibernate.sql.results.graph.entity.AbstractEntityResultGraphNode.afterInitialize(AbstractEntityResultGraphNode.java:100)
at org.hibernate.persister.entity.JoinedSubclassEntityPersister.createDomainResult(JoinedSubclassEntityPersister.java:1225)
at org.hibernate.query.sqm.sql.internal.AbstractSqmPathInterpretation.createDomainResult(AbstractSqmPathInterpretation.java:55)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.lambda$visitSelection$25(BaseSqmToSqlAstConverter.java:2053)
at java.base/java.util.Collections$SingletonList.forEach(Collections.java:4966)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitSelection(BaseSqmToSqlAstConverter.java:2048)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitSelectClause(BaseSqmToSqlAstConverter.java:1951)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQuerySpec(BaseSqmToSqlAstConverter.java:1819)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQuerySpec(BaseSqmToSqlAstConverter.java:416)
at org.hibernate.query.sqm.tree.select.SqmQuerySpec.accept(SqmQuerySpec.java:122)
at org.hibernate.query.sqm.spi.BaseSemanticQueryWalker.visitQueryPart(BaseSemanticQueryWalker.java:213)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitQueryPart(BaseSqmToSqlAstConverter.java:1679)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitSelectStatement(BaseSqmToSqlAstConverter.java:1477)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.visitSelectStatement(BaseSqmToSqlAstConverter.java:416)
at org.hibernate.query.sqm.tree.select.SqmSelectStatement.accept(SqmSelectStatement.java:213)
at org.hibernate.query.sqm.sql.BaseSqmToSqlAstConverter.translate(BaseSqmToSqlAstConverter.java:711)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.buildCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:380)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:300)
at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performList(ConcreteSqmSelectQueryPlan.java:276)
at org.hibernate.query.sqm.internal.QuerySqmImpl.doList(QuerySqmImpl.java:571)
at org.hibernate.query.spi.AbstractSelectionQuery.list(AbstractSelectionQuery.java:363)
at org.hibernate.query.sqm.internal.QuerySqmImpl.list(QuerySqmImpl.java:1073)
at org.hibernate.query.Query.getResultList(Query.java:94)
at org.hibernate.bugs.JPAUnitTestCase.hhh123Test(JPAUnitTestCase.java: 89 70 )
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.query.SemanticException: Could not resolve attribute 'status' of 'org.hibernate.bugs.Account' due to the attribute being declared in multiple sub types: ['org.hibernate.bugs.Account1', 'org.hibernate.bugs.Account2']
... 60 more
{noformat}
( https://hibernate.atlassian.net/browse/HHH-15972#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-15972#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=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100214- sha1:771690a )
1 year, 8 months
[JIRA] (HHH-16054) JPA / Hibernate, duplicate pkey error when updating entity that is a subclass of a base class that uses IdClass for composite primary key
by Cui Pengfei (JIRA)
Cui Pengfei ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *updated* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiMmNkMjVmYjU3... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-16054?atlOrigin=eyJpIjoiMmNkMj... ) HHH-16054 ( https://hibernate.atlassian.net/browse/HHH-16054?atlOrigin=eyJpIjoiMmNkMj... ) JPA / Hibernate, duplicate pkey error when updating entity that is a subclass of a base class that uses IdClass for composite primary key ( https://hibernate.atlassian.net/browse/HHH-16054?atlOrigin=eyJpIjoiMmNkMj... )
Change By: Cui Pengfei ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... )
h1. How to reproduce this issue
[https://github.com/cuipengfei/Spikes/tree/master/jpa/ClassIdUpdateIssue|h...]
this code can reproduce the issue, just run the main method then the error will happen.
h1. Issue Description
There is a base class like this:
{code:java}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorFormula("case when vip_number is not null then 'vip' else 'normal' end")
@DiscriminatorValue("normal")
@IdClass(CustomerPK.class)
public class CustomerWithIdClass implements Serializable {
private String firstName;
private String lastName;
@Id
private Long versionId;
@Id
private Long unitId;
protected CustomerWithIdClass() {
}
// getter and setters ......
}{code}
Its IdClass is like this:
{code:java}@NoArgsConstructor
@EqualsAndHashCode
@Embeddable
public class CustomerPK implements Serializable {
private Long unitId;
private Long versionId;
public void setUnitId(Long unitId) {
this.unitId = unitId;
}
public void setVersionId(Long versionId) {
this.versionId = versionId;
}
}{code}
Then it has a subclass:
{code:java}@Entity
@DiscriminatorValue("vip")
public class VipCustomerWithIdClass extends CustomerWithIdClass {
private String vipNumber;
public VipCustomerWithIdClass() {
}
public VipCustomerWithIdClass(String firstName, String lastName, String vipNumber) {
super(firstName, lastName);
this.vipNumber = vipNumber;
}
public String getVipNumber() {
return vipNumber;
}
public void setVipNumber(String vipNumber) {
this.vipNumber = vipNumber;
}
}
{code}
The subclass only adds one additional field, nothing else fancy.
Then when I try to persist an instance of the subclass like this:
{code:java} CustomerWithIdClass customer = new CustomerWithIdClass("a", "b");
customer.setVersionId(123L);
customer.setUnitId(456L);
repository.save(customer);//save object of base class, ok
customer.setFirstName("a2");
repository.save(customer);//modify object of base class and save again, ok
VipCustomerWithIdClass vipCustomer = new VipCustomerWithIdClass("a", "b", "888");
vipCustomer.setVersionId(987L);
vipCustomer.setUnitId(654L);
repository.save(vipCustomer);//save object of subclass, ok
vipCustomer.setVipNumber("999");
repository.save(vipCustomer);//modify object of subclass and save again, NOT OK
// ↑ THIS FAILS BECAUSE OF PRIMARY KEY CONFLICT. INSERT STATEMENT WAS USED INSTEAD OF UPDATE, WHY?
// this failure only happens when:
// 1. base class uses IdClass for composite primary key
// 2. saving an instance of the subclass for the second time after modification
{code}
h1. The Error
Then there will be an *error of duplicate pkey* when I try to save the instance of the *subclass* for the *second time* *after some modification*.
The error seems to be related with the @*IdClass* annotation, because I have tried using @*EmbeddedId* and @*Embeddable* for composite pkey, then the error does not happen.
h1. The question
What is the root reason of this issue? Is @IdClass not supposed to be used for this scenario?
h1. links
[https://stackoverflow.com/questions/75147518/jpa-hibernate-duplicate-pkey...]
[https://github.com/spring-projects/spring-data-jpa/issues/2767|https://gi...]
( https://hibernate.atlassian.net/browse/HHH-16054#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16054#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=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100214- sha1:771690a )
1 year, 8 months
[JIRA] (HHH-16054) JPA / Hibernate, duplicate pkey error when updating entity that is a subclass of a base class that uses IdClass for composite primary key
by Cui Pengfei (JIRA)
Cui Pengfei ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *created* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiY2I3NTA4MGY0... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-16054?atlOrigin=eyJpIjoiY2I3NT... ) HHH-16054 ( https://hibernate.atlassian.net/browse/HHH-16054?atlOrigin=eyJpIjoiY2I3NT... ) JPA / Hibernate, duplicate pkey error when updating entity that is a subclass of a base class that uses IdClass for composite primary key ( https://hibernate.atlassian.net/browse/HHH-16054?atlOrigin=eyJpIjoiY2I3NT... )
Issue Type: Bug Affects Versions: 5.6.14 Assignee: Unassigned Components: hibernate-core Created: 17/Jan/2023 06:12 AM Environment: Hibernate libraries:
hibernate-core-5.6.14.Final.jar
hibernate-commons-annotations-5.1.2.Final.jar
JVM:
openjdk 16
operating system,
mac 12.6.2 and windows 10
database platform
pg and mysql
Priority: Major Reporter: Cui Pengfei ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... )
***************************
How to reproduce this issue
***************************
https://github.com/cuipengfei/Spikes/tree/master/jpa/ClassIdUpdateIssue ( https://github.com/cuipengfei/Spikes/tree/master/jpa/ClassIdUpdateIssue )
this code can reproduce the issue, just run the main method then the error will happen.
*****************
Issue Description
*****************
There is a base class like this:
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorFormula( " case when vip_number is not null then 'vip' else 'normal' end" )
@DiscriminatorValue( "normal" )
@IdClass(CustomerPK.class)
public class CustomerWithIdClass implements Serializable {
private String firstName;
private String lastName;
@Id
private Long versionId;
@Id
private Long unitId;
protected CustomerWithIdClass() {
}
// getter and setters ......
}
Its IdClass is like this:
@NoArgsConstructor
@EqualsAndHashCode
@Embeddable
public class CustomerPK implements Serializable {
private Long unitId;
private Long versionId;
public void setUnitId( Long unitId) {
this.unitId = unitId;
}
public void setVersionId( Long versionId) {
this.versionId = versionId;
}
}
Then it has a subclass:
@Entity
@DiscriminatorValue( "vip" )
public class VipCustomerWithIdClass extends CustomerWithIdClass {
private String vipNumber;
public VipCustomerWithIdClass() {
}
public VipCustomerWithIdClass( String firstName, String lastName, String vipNumber) {
super (firstName, lastName);
this.vipNumber = vipNumber;
}
public String getVipNumber() {
return vipNumber;
}
public void setVipNumber( String vipNumber) {
this.vipNumber = vipNumber;
}
}
The subclass only adds one additional field, nothing else fancy.
Then when I try to persist an instance of the subclass like this:
CustomerWithIdClass customer = new CustomerWithIdClass( "a" , "b" );
customer.setVersionId(123L);
customer.setUnitId(456L);
repository.save(customer); //save object of base class, ok
customer.setFirstName( "a2" );
repository.save(customer); //modify object of base class and save again, ok
VipCustomerWithIdClass vipCustomer = new VipCustomerWithIdClass( "a" , "b" , "888" );
vipCustomer.setVersionId(987L);
vipCustomer.setUnitId(654L);
repository.save(vipCustomer); //save object of subclass, ok
vipCustomer.setVipNumber( "999" );
repository.save(vipCustomer); //modify object of subclass and save again, NOT OK
// ↑ THIS FAILS BECAUSE OF PRIMARY KEY CONFLICT. INSERT STATEMENT WAS USED INSTEAD OF UPDATE, WHY?
// this failure only happens when:
// 1. base class uses IdClass for composite primary key
// 2. saving an instance of the subclass for the second time after modification
*********
The Error
*********
Then there will be an *error of duplicate pkey* when I try to save the instance of the *subclass* for the *second time* *after some modification*.
The error seems to be related with the @ *IdClass* annotation, because I have tried using @ *EmbeddedId* and @ *Embeddable* for composite pkey, then the error does not happen.
************
The question
************
What is the root reason of this issue? Is @IdClass not supposed to be used for this scenario?
*****
links
*****
https://stackoverflow.com/questions/75147518/jpa-hibernate-duplicate-pkey... ( https://stackoverflow.com/questions/75147518/jpa-hibernate-duplicate-pkey... )
( https://hibernate.atlassian.net/browse/HHH-16054#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16054#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=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100214- sha1:771690a )
1 year, 8 months