Skip to content

Commit cbf255e

Browse files
maedagbadner
authored andcommitted
HHH-9707 - Nulls first behavior on SQLServer database
(cherry picked from commit 6f37a2e) Conflicts: hibernate-core/src/main/java/org/hibernate/dialect/SQLServer2012Dialect.java HHH-9707 - Nulls first behavior on SQLServer database (cherry picked from commit 046426b) Conflicts: hibernate-core/src/main/java/org/hibernate/dialect/SQLServer2012Dialect.java
1 parent 37964f1 commit cbf255e

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

hibernate-core/src/main/java/org/hibernate/dialect/SQLServer2008Dialect.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import java.sql.Types;
1010

11+
import org.hibernate.NullPrecedence;
1112
import org.hibernate.dialect.function.NoArgSQLFunction;
1213
import org.hibernate.type.StandardBasicTypes;
1314

@@ -29,4 +30,26 @@ public SQLServer2008Dialect() {
2930
"current_timestamp", new NoArgSQLFunction( "current_timestamp", StandardBasicTypes.TIMESTAMP, false )
3031
);
3132
}
33+
34+
@Override
35+
public String renderOrderByElement(String expression, String collation, String order, NullPrecedence nulls) {
36+
final StringBuilder orderByElement = new StringBuilder();
37+
38+
if ( nulls != null && !NullPrecedence.NONE.equals( nulls ) ) {
39+
// Workaround for NULLS FIRST / LAST support.
40+
orderByElement.append( "case when " ).append( expression ).append( " is null then " );
41+
if ( NullPrecedence.FIRST.equals( nulls ) ) {
42+
orderByElement.append( "0 else 1" );
43+
}
44+
else {
45+
orderByElement.append( "1 else 0" );
46+
}
47+
orderByElement.append( " end, " );
48+
}
49+
50+
// Nulls precedence has already been handled so passing NONE value.
51+
orderByElement.append( super.renderOrderByElement( expression, collation, order, NullPrecedence.NONE ) );
52+
53+
return orderByElement.toString();
54+
}
3255
}

hibernate-core/src/main/java/org/hibernate/dialect/SQLServerDialect.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,5 +203,6 @@ protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
203203
public int getInExpressionCountLimit() {
204204
return PARAM_LIST_SIZE_LIMIT;
205205
}
206+
206207
}
207208

hibernate-core/src/test/java/org/hibernate/test/annotations/onetomany/OrderByTest.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
import org.hibernate.dialect.H2Dialect;
2727
import org.hibernate.dialect.MySQLDialect;
2828
import org.hibernate.dialect.Oracle8iDialect;
29+
import org.hibernate.dialect.SQLServer2008Dialect;
30+
import org.hibernate.dialect.SQLServer2012Dialect;
31+
import org.hibernate.dialect.SQLServerDialect;
2932
import org.hibernate.engine.spi.SessionImplementor;
3033
import org.hibernate.persister.collection.CollectionPersister;
3134
import org.hibernate.persister.collection.QueryableCollection;
@@ -80,10 +83,10 @@ public void testOrderByOnIdClassProperties() throws Exception {
8083

8184
@Test
8285
@TestForIssue(jiraKey = "HHH-465")
83-
@RequiresDialect(value = { H2Dialect.class, MySQLDialect.class },
86+
@RequiresDialect(value = { H2Dialect.class, MySQLDialect.class, SQLServer2008Dialect.class },
8487
comment = "By default H2 places NULL values first, so testing 'NULLS LAST' expression. " +
85-
"For MySQL testing overridden Dialect#renderOrderByElement(String, String, String, NullPrecedence) method. " +
86-
"MySQL does not support NULLS FIRST / LAST syntax at the moment, so transforming the expression to 'CASE WHEN ...'.")
88+
"For MySQL and SQL Server 2008 testing overridden Dialect#renderOrderByElement(String, String, String, NullPrecedence) method. " +
89+
"MySQL and SQLServer 2008 does not support NULLS FIRST / LAST syntax at the moment, so transforming the expression to 'CASE WHEN ...'.")
8790
public void testAnnotationNullsFirstLast() {
8891
Session session = openSession();
8992

@@ -139,10 +142,10 @@ public void testAnnotationNullsFirstLast() {
139142

140143
@Test
141144
@TestForIssue(jiraKey = "HHH-465")
142-
@RequiresDialect(value = { H2Dialect.class, MySQLDialect.class },
145+
@RequiresDialect(value = { H2Dialect.class, MySQLDialect.class, SQLServer2008Dialect.class },
143146
comment = "By default H2 places NULL values first, so testing 'NULLS LAST' expression. " +
144-
"For MySQL testing overridden Dialect#renderOrderByElement(String, String, String, NullPrecedence) method. " +
145-
"MySQL does not support NULLS FIRST / LAST syntax at the moment, so transforming the expression to 'CASE WHEN ...'.")
147+
"For MySQL and SQL Server 2008 testing overridden Dialect#renderOrderByElement(String, String, String, NullPrecedence) method. " +
148+
"MySQL and SQL Server 2008 does not support NULLS FIRST / LAST syntax at the moment, so transforming the expression to 'CASE WHEN ...'.")
146149
public void testCriteriaNullsFirstLast() {
147150
Session session = openSession();
148151

@@ -177,10 +180,10 @@ public void testCriteriaNullsFirstLast() {
177180

178181
@Test
179182
@TestForIssue(jiraKey = "HHH-465")
180-
@RequiresDialect(value = { H2Dialect.class, MySQLDialect.class },
183+
@RequiresDialect(value = { H2Dialect.class, MySQLDialect.class, SQLServer2008Dialect.class },
181184
comment = "By default H2 places NULL values first, so testing 'NULLS LAST' expression. " +
182-
"For MySQL testing overridden Dialect#renderOrderByElement(String, String, String, NullPrecedence) method. " +
183-
"MySQL does not support NULLS FIRST / LAST syntax at the moment, so transforming the expression to 'CASE WHEN ...'.")
185+
"For MySQL and SQL Server 2008 testing overridden Dialect#renderOrderByElement(String, String, String, NullPrecedence) method. " +
186+
"MySQL and SQL Server 2008 does not support NULLS FIRST / LAST syntax at the moment, so transforming the expression to 'CASE WHEN ...'.")
184187
public void testNullsFirstLastSpawnMultipleColumns() {
185188
Session session = openSession();
186189

@@ -226,10 +229,10 @@ public void testNullsFirstLastSpawnMultipleColumns() {
226229

227230
@Test
228231
@TestForIssue(jiraKey = "HHH-465")
229-
@RequiresDialect(value = { H2Dialect.class, MySQLDialect.class },
232+
@RequiresDialect(value = { H2Dialect.class, MySQLDialect.class, SQLServer2008Dialect.class },
230233
comment = "By default H2 places NULL values first, so testing 'NULLS LAST' expression. " +
231-
"For MySQL testing overridden Dialect#renderOrderByElement(String, String, String, NullPrecedence) method. " +
232-
"MySQL does not support NULLS FIRST / LAST syntax at the moment, so transforming the expression to 'CASE WHEN ...'.")
234+
"For MySQL and SQL Server 2008 testing overridden Dialect#renderOrderByElement(String, String, String, NullPrecedence) method. " +
235+
"MySQL and SQL Server 2008 does not support NULLS FIRST / LAST syntax at the moment, so transforming the expression to 'CASE WHEN ...'.")
233236
public void testHqlNullsFirstLast() {
234237
Session session = openSession();
235238

0 commit comments

Comments
 (0)