Skip to content

Commit b77345b

Browse files
committed
HHH-18723 Support @SQLRestriction in class marked as @MappedSuperclass
1 parent bcac1e3 commit b77345b

File tree

2 files changed

+115
-5
lines changed

2 files changed

+115
-5
lines changed

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

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -323,18 +323,25 @@ private static SoftDelete extractSoftDelete(ClassDetails classDetails, MetadataB
323323
if ( fromClass != null ) {
324324
return fromClass;
325325
}
326+
SoftDelete fromSuper = extractAnnotationFromMappedSuperclass( classDetails, SoftDelete.class, sourceModelContext );
327+
if ( fromSuper != null ) {
328+
return fromSuper;
329+
}
330+
return extractFromPackage( SoftDelete.class, classDetails, context );
331+
}
326332

333+
private static <A extends Annotation> A extractAnnotationFromMappedSuperclass(ClassDetails classDetails, Class<A> annotationClass, SourceModelBuildingContext sourceModelContext) {
327334
ClassDetails classToCheck = classDetails.getSuperClass();
328335
while ( classToCheck != null ) {
329-
final SoftDelete fromSuper = classToCheck.getAnnotationUsage( SoftDelete.class, sourceModelContext );
330-
if ( fromSuper != null && classToCheck.hasAnnotationUsage( jakarta.persistence.MappedSuperclass.class, sourceModelContext ) ) {
336+
final A fromSuper = classToCheck.getAnnotationUsage( annotationClass, sourceModelContext );
337+
if ( fromSuper != null
338+
&& classToCheck.hasAnnotationUsage( jakarta.persistence.MappedSuperclass.class, sourceModelContext ) ) {
331339
return fromSuper;
332340
}
333341

334342
classToCheck = classToCheck.getSuperClass();
335343
}
336-
337-
return extractFromPackage( SoftDelete.class, classDetails, context );
344+
return null;
338345
}
339346

340347
private void handleCheckConstraints() {
@@ -1594,12 +1601,21 @@ public void bindConcreteProxy() {
15941601
}
15951602

15961603
public void bindWhere() {
1597-
final SQLRestriction restriction = getOverridableAnnotation( annotatedClass, SQLRestriction.class, context );
1604+
final SQLRestriction restriction = extractSQLRestriction( annotatedClass, context );
15981605
if ( restriction != null ) {
15991606
this.where = restriction.value();
16001607
}
16011608
}
16021609

1610+
private static SQLRestriction extractSQLRestriction(ClassDetails classDetails, MetadataBuildingContext context) {
1611+
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext();
1612+
final SQLRestriction fromClass = classDetails.getAnnotationUsage( SQLRestriction.class, sourceModelContext );
1613+
if ( fromClass != null ) {
1614+
return fromClass;
1615+
}
1616+
return extractAnnotationFromMappedSuperclass( classDetails, SQLRestriction.class, sourceModelContext );
1617+
}
1618+
16031619
public void setWrapIdsInEmbeddedComponents(boolean wrapIdsInEmbeddedComponents) {
16041620
this.wrapIdsInEmbeddedComponents = wrapIdsInEmbeddedComponents;
16051621
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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.flag = true;
44+
entityManager.persist( child1 );
45+
46+
Child child2 = new Child( 2L );
47+
child2.flag = false;
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+
public static class Intermediate extends Parent {
84+
}
85+
86+
@MappedSuperclass
87+
@SQLRestriction("flag = false")
88+
public static class Parent {
89+
public Parent() {
90+
}
91+
92+
boolean flag;
93+
}
94+
}

0 commit comments

Comments
 (0)