Skip to content

Commit 66d3636

Browse files
a-e-tsvetkovbeikov
authored andcommitted
HHH-18723 Support @SQLRestriction in class marked as @MappedSuperclass
1 parent 94b43af commit 66d3636

File tree

3 files changed

+128
-7
lines changed

3 files changed

+128
-7
lines changed

hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1646,12 +1646,30 @@ private void bindConcreteProxy() {
16461646
}
16471647

16481648
private void bindWhere() {
1649-
final SQLRestriction restriction = getOverridableAnnotation( annotatedClass, SQLRestriction.class, context );
1649+
final SQLRestriction restriction = extractSQLRestriction( annotatedClass, context );
16501650
if ( restriction != null ) {
16511651
this.where = restriction.value();
16521652
}
16531653
}
16541654

1655+
private static SQLRestriction extractSQLRestriction(ClassDetails classDetails, MetadataBuildingContext context) {
1656+
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext();
1657+
final SQLRestriction fromClass = getOverridableAnnotation( classDetails, SQLRestriction.class, context );
1658+
if ( fromClass != null ) {
1659+
return fromClass;
1660+
}
1661+
ClassDetails classToCheck = classDetails.getSuperClass();
1662+
while ( classToCheck != null
1663+
&& classToCheck.hasAnnotationUsage( jakarta.persistence.MappedSuperclass.class, sourceModelContext ) ) {
1664+
final SQLRestriction fromSuper = getOverridableAnnotation( classToCheck, SQLRestriction.class, context );
1665+
if ( fromSuper != null ) {
1666+
return fromSuper;
1667+
}
1668+
classToCheck = classToCheck.getSuperClass();
1669+
}
1670+
return null;
1671+
}
1672+
16551673
private void bindNaturalIdCache() {
16561674
final NaturalIdCache naturalIdCacheAnn =
16571675
annotatedClass.getAnnotationUsage( NaturalIdCache.class, getSourceModelContext() );

hibernate-core/src/test/java/org/hibernate/orm/test/customsql/CustomSqlRestrictionOverridesTest.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.security.NoSuchAlgorithmException;
2828

2929
import static org.junit.jupiter.api.Assertions.assertNotNull;
30+
import static org.junit.jupiter.api.Assertions.assertNull;
3031

3132
@SessionFactory
3233
@DomainModel(annotatedClasses = CustomSqlRestrictionOverridesTest.Secure.class)
@@ -39,12 +40,18 @@
3940
public class CustomSqlRestrictionOverridesTest {
4041
@Test
4142
public void testCustomSql(SessionFactoryScope scope) throws NoSuchAlgorithmException {
42-
Secure sec = new Secure();
43-
sec.hash = MessageDigest.getInstance( "SHA-256" ).digest("hello".getBytes());
44-
scope.inTransaction(s -> s.persist(sec) );
45-
Secure secure = scope.fromTransaction( s -> s.find( Secure.class, sec.id ) );
46-
assertNotNull(secure);
43+
Secure sec1 = new Secure();
44+
sec1.hash = MessageDigest.getInstance( "SHA-256" ).digest( "hello".getBytes() );
45+
scope.inTransaction( s -> s.persist( sec1 ) );
46+
Secure sec2 = new Secure();
47+
sec2.hash = MessageDigest.getInstance( "SHA-256" ).digest( "not hello".getBytes() );
48+
scope.inTransaction( s -> s.persist( sec2 ) );
49+
Secure secure1 = scope.fromTransaction( s -> s.find( Secure.class, sec1.id ) );
50+
assertNotNull( secure1 );
51+
Secure secure2 = scope.fromTransaction( s -> s.find( Secure.class, sec2.id ) );
52+
assertNull( secure2 );
4753
}
54+
4855
@Entity
4956
@Table(name = "SecureTable")
5057
@DialectOverride.SQLRestriction(dialect = H2Dialect.class,
@@ -60,7 +67,8 @@ public void testCustomSql(SessionFactoryScope scope) throws NoSuchAlgorithmExcep
6067
@DialectOverride.SQLRestriction(dialect = OracleDialect.class,
6168
override = @SQLRestriction("hash = standard_hash('hello', 'SHA256')"))
6269
static class Secure {
63-
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
70+
@Id
71+
@GeneratedValue(strategy = GenerationType.IDENTITY)
6472
Long id;
6573
byte[] hash;
6674
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* SPDX-License-Identifier: LGPL-2.1-or-later
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.where.annotations;
6+
7+
import jakarta.persistence.Entity;
8+
import jakarta.persistence.Id;
9+
import jakarta.persistence.MappedSuperclass;
10+
import org.hibernate.annotations.SQLRestriction;
11+
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
12+
import org.hibernate.testing.orm.junit.Jpa;
13+
import org.junit.jupiter.api.AfterEach;
14+
import org.junit.jupiter.api.Test;
15+
16+
import java.util.List;
17+
18+
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
19+
20+
@Jpa(
21+
annotatedClasses = {
22+
MappedSuperclassTest.Child.class,
23+
MappedSuperclassTest.SubClass.class
24+
}
25+
)
26+
public class MappedSuperclassTest {
27+
28+
@AfterEach
29+
public void tearDown(EntityManagerFactoryScope scope) {
30+
scope.inTransaction(
31+
entityManager -> {
32+
entityManager.createQuery( "delete from SubClass" ).executeUpdate();
33+
entityManager.createQuery( "delete from Child" ).executeUpdate();
34+
}
35+
);
36+
}
37+
38+
@Test
39+
public void testFindParent(EntityManagerFactoryScope scope) {
40+
scope.inTransaction(
41+
entityManager -> {
42+
Child child1 = new SubClass( 1L );
43+
child1.state = 1;
44+
entityManager.persist( child1 );
45+
46+
Child child2 = new Child( 2L );
47+
child2.state = 0;
48+
entityManager.persist( child2 );
49+
}
50+
);
51+
scope.inTransaction(
52+
entityManager -> {
53+
List<Child> children = entityManager.createQuery( "select c from Child c", Child.class )
54+
.getResultList();
55+
assertThat( children.size() ).isEqualTo( 1 );
56+
}
57+
);
58+
}
59+
60+
@Entity(name = "Child")
61+
public static class Child extends Intermediate {
62+
@Id
63+
private Long id;
64+
65+
public Child() {
66+
}
67+
68+
public Child(long id) {
69+
this.id = id;
70+
}
71+
}
72+
73+
@Entity(name = "SubClass")
74+
public static class SubClass extends Child {
75+
public SubClass() {
76+
}
77+
78+
public SubClass(long id) {
79+
super( id );
80+
}
81+
}
82+
83+
@MappedSuperclass
84+
public static class Intermediate extends Parent {
85+
}
86+
87+
@MappedSuperclass
88+
@SQLRestriction("state = 0")
89+
public static class Parent {
90+
public Parent() {
91+
}
92+
93+
int state;
94+
}
95+
}

0 commit comments

Comments
 (0)