From 2279fd10a43ef75bc6acc6181a55c3fe93986d2e Mon Sep 17 00:00:00 2001 From: Peter Bambazek Date: Sat, 17 May 2025 19:28:54 +0200 Subject: [PATCH] HHH-18813: Fix of generated Insert-Query in CteUpdateHandler --- .../internal/cte/CteUpdateHandler.java | 6 +- .../orm/test/secondarytable/HHH18813Test.java | 120 ++++++++++++++++++ 2 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/secondarytable/HHH18813Test.java diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteUpdateHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteUpdateHandler.java index 28c82a7b5384..749706d28ec4 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteUpdateHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteUpdateHandler.java @@ -153,8 +153,8 @@ protected void addDmlCtes( tableExpression, true ); - final List assignmentList = assignmentsByTable.get( updatingTableReference ); - if ( assignmentList == null ) { + final List assignmentsForInsert = assignmentsByTable.get( updatingTableReference ); + if ( assignmentsForInsert == null ) { continue; } final String insertCteTableName = getInsertCteTableName( tableExpression ); @@ -229,7 +229,7 @@ protected void addDmlCtes( // Collect the target column references from the key expressions final List targetColumnReferences = new ArrayList<>( existsKeyColumns ); // And transform assignments to target column references and selections - for ( Assignment assignment : assignments ) { + for ( Assignment assignment : assignmentsForInsert ) { targetColumnReferences.addAll( assignment.getAssignable().getColumnReferences() ); querySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/secondarytable/HHH18813Test.java b/hibernate-core/src/test/java/org/hibernate/orm/test/secondarytable/HHH18813Test.java new file mode 100644 index 000000000000..741bd8bf3199 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/secondarytable/HHH18813Test.java @@ -0,0 +1,120 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.secondarytable; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.persistence.Inheritance; +import jakarta.persistence.InheritanceType; +import jakarta.persistence.SecondaryTable; +import org.hibernate.testing.orm.junit.DomainModel; +import org.hibernate.testing.orm.junit.JiraKey; +import org.hibernate.testing.orm.junit.SessionFactory; +import org.hibernate.testing.orm.junit.SessionFactoryScope; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + + +/** + * Test for a Bugfix described in HHH-18813. + * The CteUpdateHandler generated an Insert-Query, + * which contained columns that do not exist in the target table. + * + * @author Peter Bambazek + */ +@JiraKey(value = "HHH-18813") +@DomainModel( + annotatedClasses = {HHH18813Test.SecondaryTableEntitySub.class, HHH18813Test.SecondaryTableEntityBase.class}) +@SessionFactory +class HHH18813Test { + + @Test + void hhh18813Test(SessionFactoryScope scope) { + + // prepare + scope.inTransaction( session -> { + SecondaryTableEntitySub entitySub = new SecondaryTableEntitySub(); + entitySub.setB( 111L ); + entitySub.setC( 222L ); + session.persist( entitySub ); + } ); + + // asset before + scope.inTransaction( session -> { + SecondaryTableEntitySub entitySub = session.createQuery( + "select s from SecondaryTableEntitySub s", + SecondaryTableEntitySub.class ).getSingleResult(); + assertNotNull( entitySub ); + assertEquals( 111L, entitySub.getB() ); + assertEquals( 222L, entitySub.getC() ); + } ); + + // update + scope.inTransaction( session -> { + session.createMutationQuery( "update SecondaryTableEntitySub e set e.b=:b, e.c=:c" ) + .setParameter( "b", 333L ) + .setParameter( "c", 444L ) + .executeUpdate(); + } ); + + // asset after + scope.inTransaction( session -> { + SecondaryTableEntitySub entitySub = session.createQuery( "select s from SecondaryTableEntitySub s", + SecondaryTableEntitySub.class ).getSingleResult(); + assertNotNull( entitySub ); + assertEquals( 333L, entitySub.getB() ); + assertEquals( 444L, entitySub.getC() ); + } ); + } + + @Entity(name = "SecondaryTableEntitySub") + @Inheritance(strategy = InheritanceType.JOINED) + @SecondaryTable(name = "test") + public static class SecondaryTableEntitySub extends SecondaryTableEntityBase { + + @Column + private Long b; + + @Column(table = "test") + private Long c; + + public Long getB() { + return b; + } + + public void setB(Long b) { + this.b = b; + } + + public Long getC() { + return c; + } + + public void setC(Long c) { + this.c = c; + } + } + + @Entity + @Inheritance(strategy = InheritanceType.JOINED) + public static class SecondaryTableEntityBase { + + @Id + @GeneratedValue + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + } +}