Skip to content

Commit e02317f

Browse files
committed
HHH-17795 fix an NPE and add a test for 'on conflict on constraint'
1 parent 9b4e61c commit e02317f

File tree

4 files changed

+48
-6
lines changed

4 files changed

+48
-6
lines changed

hibernate-core/src/main/antlr/org/hibernate/grammars/hql/HqlParser.g4

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,18 @@ values
110110
/**
111111
* a 'conflict' clause in an 'insert' statement
112112
*/
113-
conflictClause: ON CONFLICT conflictTarget? conflictAction;
113+
conflictClause
114+
: ON CONFLICT conflictTarget? DO conflictAction
115+
;
116+
114117
conflictTarget
115118
: ON CONSTRAINT identifier
116-
| LEFT_PAREN simplePath (COMMA simplePath)* RIGHT_PAREN;
119+
| LEFT_PAREN simplePath (COMMA simplePath)* RIGHT_PAREN
120+
;
121+
117122
conflictAction
118-
: DO NOTHING
119-
| DO UPDATE setClause whereClause?
123+
: NOTHING
124+
| UPDATE setClause whereClause?
120125
;
121126

122127
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
import org.hibernate.boot.model.IdentifierGeneratorDefinition;
4646
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
4747
import org.hibernate.boot.model.convert.spi.RegisteredConversion;
48-
import org.hibernate.boot.registry.StandardServiceRegistry;
4948
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
5049
import org.hibernate.boot.spi.BootstrapContext;
5150
import org.hibernate.boot.spi.InFlightMetadataCollector;

hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmConflictClause.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public SqmRoot<T> getExcludedRoot() {
7070

7171
@Override
7272
public SqmConflictClause<T> conflictOnConstraint(@Nullable String constraintName) {
73-
if ( !constraintPaths.isEmpty() ) {
73+
if ( constraintPaths != null && !constraintPaths.isEmpty() ) {
7474
throw new IllegalStateException( "Constraint paths were already set: " + constraintPaths );
7575
}
7676
this.constraintName = constraintName;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.hibernate.orm.test.query.hql;
2+
3+
import jakarta.persistence.Entity;
4+
import jakarta.persistence.GeneratedValue;
5+
import jakarta.persistence.Id;
6+
import jakarta.persistence.Table;
7+
import jakarta.persistence.UniqueConstraint;
8+
import org.hibernate.dialect.PostgreSQLDialect;
9+
import org.hibernate.testing.orm.junit.DomainModel;
10+
import org.hibernate.testing.orm.junit.RequiresDialect;
11+
import org.hibernate.testing.orm.junit.SessionFactory;
12+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
13+
import org.junit.jupiter.api.Test;
14+
15+
import static org.junit.jupiter.api.Assertions.assertEquals;
16+
17+
@SessionFactory
18+
@DomainModel(annotatedClasses = InsertConflictOnConstraintTest.Constrained.class)
19+
@RequiresDialect(PostgreSQLDialect.class)
20+
public class InsertConflictOnConstraintTest {
21+
@Test void test(SessionFactoryScope scope) {
22+
scope.inTransaction( s -> s.persist(new Constrained()));
23+
scope.inTransaction( s -> s.createMutationQuery("insert into Constrained(id, name, count) values (4,'Gavin',69) on conflict on constraint constrained_count_name_key do update set count = 96").executeUpdate());
24+
scope.inSession( s -> assertEquals(96, s.createSelectionQuery("select count from Constrained", int.class).getSingleResult()));
25+
26+
}
27+
28+
@Entity(name = "Constrained")
29+
@Table(uniqueConstraints = @UniqueConstraint(columnNames = {"count","name"}))
30+
static class Constrained {
31+
@Id
32+
@GeneratedValue
33+
long id;
34+
String name = "Gavin";
35+
int count = 69;
36+
}
37+
38+
}

0 commit comments

Comments
 (0)