Skip to content

Commit a6673e2

Browse files
lrobotbeikov
authored andcommitted
HHH-18282 fix generate error sql in case of @DiscriminatorValue("not null")
1 parent 3d640c0 commit a6673e2

File tree

2 files changed

+142
-1
lines changed

2 files changed

+142
-1
lines changed

hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3222,7 +3222,13 @@ else if ( discriminatorValue == NOT_NULL_DISCRIMINATOR ) {
32223222
return junction;
32233223
}
32243224

3225-
junction.add( new NullnessPredicate( sqlExpression ) );
3225+
if ( hasNonNull ) {
3226+
return new NullnessPredicate( sqlExpression, true );
3227+
}
3228+
else if ( hasNull ) {
3229+
junction.add( new NullnessPredicate( sqlExpression ) );
3230+
}
3231+
32263232
junction.add( predicate );
32273233
return junction;
32283234
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.orm.test.inheritance.discriminator;
8+
9+
import java.sql.Statement;
10+
import java.util.List;
11+
import java.util.Map;
12+
import java.util.function.Function;
13+
import java.util.stream.Collectors;
14+
import jakarta.persistence.DiscriminatorValue;
15+
import jakarta.persistence.Entity;
16+
import jakarta.persistence.Id;
17+
import jakarta.persistence.Inheritance;
18+
import jakarta.persistence.InheritanceType;
19+
import jakarta.persistence.criteria.CriteriaQuery;
20+
import jakarta.persistence.criteria.Root;
21+
22+
import org.hibernate.testing.TestForIssue;
23+
import org.hibernate.testing.orm.junit.DomainModel;
24+
import org.hibernate.testing.orm.junit.SessionFactory;
25+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
26+
import org.junit.jupiter.api.AfterEach;
27+
import org.junit.jupiter.api.Test;
28+
29+
30+
import static org.assertj.core.api.Assertions.assertThat;
31+
/**
32+
33+
* how to run this test case: ./gradlew :hibernate-core:test --tests '*DiscriminatorSuperClassTest'
34+
*/
35+
@TestForIssue(jiraKey = "HHH-18282")
36+
@DomainModel(
37+
annotatedClasses = {
38+
SingleTableNotNullDiscriminatorSuperClassTest.RootEntity.class,
39+
SingleTableNotNullDiscriminatorSuperClassTest.Val1Entity.class,
40+
SingleTableNotNullDiscriminatorSuperClassTest.Val2Entity.class,
41+
SingleTableNotNullDiscriminatorSuperClassTest.OtherEntity.class,
42+
SingleTableNotNullDiscriminatorSuperClassTest.NotNullEntity.class
43+
}
44+
)
45+
@SessionFactory
46+
public class SingleTableNotNullDiscriminatorSuperClassTest {
47+
48+
@AfterEach
49+
public void tearDown(SessionFactoryScope scope) {
50+
scope.inTransaction(
51+
session ->
52+
session.createQuery( "delete from root_ent" ).executeUpdate()
53+
);
54+
}
55+
56+
@Test
57+
public void test(SessionFactoryScope scope) {
58+
scope.inTransaction( session -> {
59+
Val1Entity val1 = new Val1Entity();
60+
val1.setId( 1L );
61+
62+
Val2Entity val2 = new Val2Entity();
63+
val2.setId( 2L );
64+
65+
RootEntity root = new RootEntity();
66+
root.setId( 3L );
67+
68+
OtherEntity otherEntity = new OtherEntity();
69+
otherEntity.setId( 4L );
70+
71+
session.persist( val1 );
72+
session.persist( val2 );
73+
session.persist( root );
74+
session.persist( otherEntity );
75+
76+
} );
77+
78+
scope.inTransaction( session -> {
79+
// can ref more from spring-data: SimpleJpaRepository
80+
final CriteriaQuery<NotNullEntity> criteriaQuery = session.getCriteriaBuilder().createQuery( NotNullEntity.class );
81+
final Root<NotNullEntity> root = criteriaQuery.from( NotNullEntity.class );
82+
criteriaQuery.select( root );
83+
84+
Map<Long, NotNullEntity> entities = session.createQuery( criteriaQuery ).getResultList()
85+
.stream()
86+
.collect( Collectors.toMap( NotNullEntity::getId, Function.identity() ) );
87+
assertThat( entities ).hasSize( 3 ); //select NotNullEntity and all it subclasses only, not select RootEntity
88+
assertThat( entities ).extractingByKey( 1L ).isInstanceOf( Val1Entity.class );
89+
assertThat( entities ).extractingByKey( 2L ).isInstanceOf( Val2Entity.class );
90+
// assertThat( entities ).extractingByKey( 3L ).isInstanceOf( RootEntity.class );
91+
assertThat( entities ).extractingByKey( 4L ).isInstanceOf( NotNullEntity.class );
92+
} );
93+
}
94+
95+
@Entity(name = "root_ent")
96+
@DiscriminatorValue("null")
97+
public static class RootEntity {
98+
99+
@Id
100+
private Long id;
101+
102+
private String name;
103+
104+
public Long getId() {
105+
return id;
106+
}
107+
108+
public void setId(Long id) {
109+
this.id = id;
110+
}
111+
}
112+
113+
@Entity(name = "val1_ent")
114+
@DiscriminatorValue("val1")
115+
public static class Val1Entity extends NotNullEntity {
116+
117+
}
118+
119+
@Entity(name = "val2_ent")
120+
@DiscriminatorValue("val2")
121+
public static class Val2Entity extends NotNullEntity {
122+
123+
}
124+
125+
@Entity(name = "other_ent")
126+
@DiscriminatorValue("other")
127+
public static class OtherEntity extends NotNullEntity {
128+
}
129+
130+
@Entity(name = "notnull_ent")
131+
@DiscriminatorValue("not null")
132+
public static class NotNullEntity extends RootEntity {
133+
134+
}
135+
}

0 commit comments

Comments
 (0)