Skip to content

Commit

Permalink
HHH-14358 - Added test and fix to support null binding for PostgreSQL
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Schatteman <[email protected]>
  • Loading branch information
jrenaat authored and beikov committed Dec 22, 2023
1 parent 3ac0b8c commit ec60a5a
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeConstructor;
import org.hibernate.type.descriptor.jdbc.ObjectNullAsBinaryTypeJdbcType;
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
import org.hibernate.type.descriptor.jdbc.VarbinaryJdbcType;
import org.hibernate.type.descriptor.jdbc.VarcharJdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
Expand Down Expand Up @@ -352,7 +351,7 @@ protected void contributeCockroachTypes(TypeContributions typeContributions, Ser
// Don't use this type due to https://github.com/pgjdbc/pgjdbc/issues/2862
//jdbcTypeRegistry.addDescriptor( TimestampUtcAsOffsetDateTimeJdbcType.INSTANCE );
if ( driverKind == PostgreSQLDriverKind.PG_JDBC ) {
jdbcTypeRegistry.addDescriptorIfAbsent( UUIDJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLUUIDJdbcType.INSTANCE );
if ( PgJdbcHelper.isUsable( serviceRegistry ) ) {
jdbcTypeRegistry.addDescriptorIfAbsent( PgJdbcHelper.getIntervalJdbcType( serviceRegistry ) );

Expand All @@ -376,7 +375,7 @@ protected void contributeCockroachTypes(TypeContributions typeContributions, Ser
}
}
else {
jdbcTypeRegistry.addDescriptorIfAbsent( UUIDJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLUUIDJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLCastingIntervalSecondJdbcType.INSTANCE );
if ( getVersion().isSameOrAfter( 20, 0 ) ) {
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLCastingInetJdbcType.INSTANCE );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.dialect.unique.CreateTableUniqueDelegate;
import org.hibernate.dialect.unique.UniqueDelegate;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.jdbc.env.spi.IdentifierCaseStrategy;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
Expand Down Expand Up @@ -83,7 +82,6 @@
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeConstructor;
import org.hibernate.type.descriptor.jdbc.ObjectNullAsBinaryTypeJdbcType;
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
import org.hibernate.type.descriptor.jdbc.XmlJdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl;
Expand Down Expand Up @@ -1370,8 +1368,8 @@ protected void contributePostgreSQLTypes(TypeContributions typeContributions, Se
}

if ( getVersion().isSameOrAfter( 8, 2 ) ) {
// HHH-9562
jdbcTypeRegistry.addDescriptorIfAbsent( UUIDJdbcType.INSTANCE );
// HHH-9562 / HHH-14358
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLUUIDJdbcType.INSTANCE );
if ( getVersion().isSameOrAfter( 9, 2 ) ) {
if ( getVersion().isSameOrAfter( 9, 4 ) ) {
if ( PgJdbcHelper.isUsable( serviceRegistry ) ) {
Expand All @@ -1398,7 +1396,7 @@ protected void contributePostgreSQLTypes(TypeContributions typeContributions, Se
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLStructCastingJdbcType.INSTANCE );

if ( getVersion().isSameOrAfter( 8, 2 ) ) {
jdbcTypeRegistry.addDescriptorIfAbsent( UUIDJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLUUIDJdbcType.INSTANCE );
if ( getVersion().isSameOrAfter( 9, 2 ) ) {
if ( getVersion().isSameOrAfter( 9, 4 ) ) {
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLCastingJsonJdbcType.JSONB_INSTANCE );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ protected void contributeCockroachTypes(TypeContributions typeContributions, Ser
// Don't use this type due to https://github.com/pgjdbc/pgjdbc/issues/2862
//jdbcTypeRegistry.addDescriptor( TimestampUtcAsOffsetDateTimeJdbcType.INSTANCE );
if ( driverKind == PostgreSQLDriverKind.PG_JDBC ) {
jdbcTypeRegistry.addDescriptorIfAbsent( UUIDJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLUUIDJdbcType.INSTANCE );
if ( PgJdbcHelper.isUsable( serviceRegistry ) ) {
jdbcTypeRegistry.addDescriptorIfAbsent( PgJdbcHelper.getIntervalJdbcType( serviceRegistry ) );
jdbcTypeRegistry.addDescriptorIfAbsent( PgJdbcHelper.getInetJdbcType( serviceRegistry ) );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeConstructor;
import org.hibernate.type.descriptor.jdbc.ObjectNullAsBinaryTypeJdbcType;
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
import org.hibernate.type.descriptor.jdbc.XmlJdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl;
Expand Down Expand Up @@ -1417,7 +1416,6 @@ protected void contributePostgreSQLTypes(TypeContributions typeContributions, Se
//jdbcTypeRegistry.addDescriptor( TimestampUtcAsOffsetDateTimeJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptor( XmlJdbcType.INSTANCE );

jdbcTypeRegistry.addDescriptorIfAbsent( UUIDJdbcType.INSTANCE ); // HHH-9562
if ( driverKind == PostgreSQLDriverKind.PG_JDBC ) {
if ( PgJdbcHelper.isUsable( serviceRegistry ) ) {
jdbcTypeRegistry.addDescriptorIfAbsent( PgJdbcHelper.getInetJdbcType( serviceRegistry ) );
Expand Down Expand Up @@ -1453,6 +1451,7 @@ protected void contributePostgreSQLTypes(TypeContributions typeContributions, Se
);

jdbcTypeRegistry.addDescriptor( new PostgreSQLEnumJdbcType() );
jdbcTypeRegistry.addDescriptor( PostgreSQLUUIDJdbcType.INSTANCE );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.dialect;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.UUID;

import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaType;
import org.hibernate.type.descriptor.jdbc.BasicBinder;
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;

/**
* @author Jan Schatteman
*/
public class PostgreSQLUUIDJdbcType extends UUIDJdbcType {

/**
* Singleton access
*/
public static final PostgreSQLUUIDJdbcType INSTANCE = new PostgreSQLUUIDJdbcType();

@Override
public <X> ValueBinder<X> getBinder(JavaType<X> javaType) {
return new BasicBinder<>( javaType, this ) {
@Override
protected void doBindNull(PreparedStatement st, int index, WrapperOptions options) throws SQLException {
st.setNull( index, getJdbcType().getJdbcTypeCode(), "uuid" );
}

@Override
protected void doBindNull(CallableStatement st, String name, WrapperOptions options) throws SQLException {
st.setNull( name, getJdbcType().getJdbcTypeCode(), "uuid" );
}

@Override
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
throws SQLException {
st.setObject( index, getJavaType().unwrap( value, UUID.class, options ) );
}

@Override
protected void doBind(CallableStatement st, X value, String name, WrapperOptions options)
throws SQLException {
st.setObject( name, getJavaType().unwrap( value, UUID.class, options ) );
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,19 @@
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Query;

import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.query.NativeQuery;
import org.hibernate.type.StandardBasicTypes;

import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.RequiresDialect;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

Expand All @@ -31,9 +35,9 @@
* @author Vlad Mihalcea
*/
@RequiresDialect(value = PostgreSQLDialect.class)
@DomainModel(annotatedClasses = { PostgreSQLUUIDGeneratedValueTest.Book.class })
@DomainModel(annotatedClasses = { PostgreSQLUUIDTest.Book.class })
@SessionFactory
public class PostgreSQLUUIDGeneratedValueTest {
public class PostgreSQLUUIDTest {

private UUID id;

Expand All @@ -49,6 +53,15 @@ void setUp(SessionFactoryScope scope) {
assertThat( id, notNullValue() );
}

@AfterEach
void tearDown(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
session.createMutationQuery( "delete from Book" ).executeUpdate();
}
);
}

@Test
public void testJPQL(SessionFactoryScope scope) {
scope.inTransaction( session -> {
Expand Down Expand Up @@ -77,6 +90,20 @@ public void testNativeSQL(SessionFactoryScope scope) {
} );
}

@Test
@JiraKey( value = "HHH-14358" )
public void testUUIDNullBinding(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
Query query = session.createQuery( "SELECT b FROM Book b WHERE :id is null or b.id = :id", Book.class );
query.setParameter("id", null);
List<?> results = Assertions.assertDoesNotThrow( query::getResultList,
"Should not throw a PSQLException of type \"could not determine data type of parameter\" " );
Assertions.assertEquals( 1, results.size() );
}
);
}

@Entity(name = "Book")
static class Book {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.CockroachDialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.dialect.PostgreSQLUUIDJdbcType;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
Expand Down Expand Up @@ -55,7 +55,7 @@ public void verifyMappingsUUid(SessionFactoryScope scope) {
assertThat( uuidJdbcType ).isEqualTo( CharJdbcType.INSTANCE );

final JdbcType uuidType = jdbcTypeRegistry.getDescriptor( SqlTypes.UUID );
assertThat( uuidType ).isOfAnyClassIn( UUIDJdbcType.class );
assertThat( uuidType ).isOfAnyClassIn( UUIDJdbcType.class, PostgreSQLUUIDJdbcType.class );

// a simple duration field with no overrides - so should be using a default JdbcType
assertThat( entityDescriptor.findAttributeMapping( "uuid" )
Expand Down

0 comments on commit ec60a5a

Please sign in to comment.