HHH-15438 Don't fail booting when PostgreSQL JDBC types are inaccessible

This commit is contained in:
Christian Beikov 2022-08-05 16:20:32 +02:00
parent 95a300d7d9
commit 69a5cb3136
5 changed files with 51 additions and 32 deletions

View File

@ -176,17 +176,20 @@ public class CockroachDialect extends Dialect {
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( UUID, "uuid", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOMETRY, "geometry", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOGRAPHY, "geography", this ) );
ddlTypeRegistry.addDescriptor( new Scale6IntervalSecondDdlType( this ) );
if ( PostgreSQLPGObjectJdbcType.isUsable() ) {
// The following DDL types require that the PGobject class is usable/visible
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOMETRY, "geometry", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOGRAPHY, "geography", this ) );
ddlTypeRegistry.addDescriptor( new Scale6IntervalSecondDdlType( this ) );
// Prefer jsonb if possible
if ( getVersion().isSameOrAfter( 20 ) ) {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( INET, "inet", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( JSON, "jsonb", this ) );
}
else {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( JSON, "json", this ) );
// Prefer jsonb if possible
if ( getVersion().isSameOrAfter( 20 ) ) {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( INET, "inet", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( JSON, "jsonb", this ) );
}
else {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( JSON, "json", this ) );
}
}
}
@ -229,14 +232,16 @@ public class CockroachDialect extends Dialect {
jdbcTypeRegistry.addDescriptor( TIMESTAMP_UTC, InstantAsTimestampWithTimeZoneJdbcType.INSTANCE );
if ( driverKind == PostgreSQLDriverKind.PG_JDBC ) {
jdbcTypeRegistry.addDescriptorIfAbsent( UUIDJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLIntervalSecondJdbcType.INSTANCE );
if ( PostgreSQLPGObjectJdbcType.isUsable() ) {
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLIntervalSecondJdbcType.INSTANCE );
if ( getVersion().isSameOrAfter( 20, 0 ) ) {
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLInetJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLJsonbJdbcType.INSTANCE );
}
else {
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLJsonJdbcType.INSTANCE );
if ( getVersion().isSameOrAfter( 20, 0 ) ) {
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLInetJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLJsonbJdbcType.INSTANCE );
}
else {
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLJsonJdbcType.INSTANCE );
}
}
}

View File

@ -221,14 +221,16 @@ public class PostgreSQLDialect extends Dialect {
.build()
);
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( INET, "inet", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOMETRY, "geometry", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOGRAPHY, "geography", this ) );
ddlTypeRegistry.addDescriptor( new Scale6IntervalSecondDdlType( this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( SQLXML, "xml", this ) );
if ( getVersion().isSameOrAfter( 8, 2 ) ) {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( UUID, "uuid", this ) );
}
if ( PostgreSQLPGObjectJdbcType.isUsable() ) {
// The following DDL types require that the PGobject class is usable/visible
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( INET, "inet", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOMETRY, "geometry", this ) );
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( GEOGRAPHY, "geography", this ) );
ddlTypeRegistry.addDescriptor( new Scale6IntervalSecondDdlType( this ) );
if ( getVersion().isSameOrAfter( 9, 2 ) ) {
// Prefer jsonb if possible
@ -1169,14 +1171,18 @@ public class PostgreSQLDialect extends Dialect {
jdbcTypeRegistry.addDescriptor( XmlJdbcType.INSTANCE );
if ( driverKind == PostgreSQLDriverKind.PG_JDBC ) {
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLInetJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLIntervalSecondJdbcType.INSTANCE );
if ( PostgreSQLPGObjectJdbcType.isUsable() ) {
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLInetJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLIntervalSecondJdbcType.INSTANCE );
}
if ( getVersion().isSameOrAfter( 8, 2 ) ) {
// HHH-9562
jdbcTypeRegistry.addDescriptorIfAbsent( UUIDJdbcType.INSTANCE );
if ( getVersion().isSameOrAfter( 9, 2 ) ) {
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLJsonbJdbcType.INSTANCE );
if ( PostgreSQLPGObjectJdbcType.isUsable() ) {
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLJsonbJdbcType.INSTANCE );
}
}
}
}

View File

@ -15,6 +15,8 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
@ -30,14 +32,15 @@ import org.hibernate.type.descriptor.jdbc.JdbcType;
*/
public abstract class PostgreSQLPGObjectJdbcType implements JdbcType {
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( PostgreSQLPGObjectJdbcType.class );
private static final Constructor<Object> PG_OBJECT_CONSTRUCTOR;
private static final Method TYPE_SETTER;
private static final Method VALUE_SETTER;
static {
Constructor<Object> constructor;
Method typeSetter;
Method valueSetter;
Constructor<Object> constructor = null;
Method typeSetter = null;
Method valueSetter = null;
try {
final Class<?> pgObjectClass = ReflectHelper.classForName(
"org.postgresql.util.PGobject",
@ -49,7 +52,7 @@ public abstract class PostgreSQLPGObjectJdbcType implements JdbcType {
valueSetter = ReflectHelper.setterMethodOrNull( pgObjectClass, "value", String.class );
}
catch (Exception e) {
throw new RuntimeException( "Could not initialize PostgreSQLPGObjectJdbcType", e );
LOG.warn( "PostgreSQL JDBC driver classes are inaccessible and thus, certain DDL types like JSONB, JSON, GEOMETRY can not be used!", e );
}
PG_OBJECT_CONSTRUCTOR = constructor;
TYPE_SETTER = typeSetter;
@ -64,6 +67,10 @@ public abstract class PostgreSQLPGObjectJdbcType implements JdbcType {
this.sqlTypeCode = sqlTypeCode;
}
public static boolean isUsable() {
return PG_OBJECT_CONSTRUCTOR != null;
}
@Override
public int getJdbcTypeCode() {
return Types.OTHER;

View File

@ -20,7 +20,7 @@ public class Scale6IntervalSecondDdlType extends DdlTypeImpl {
}
@Override
public String getTypeName(Long size, Integer precision, Integer scale) {
// The maximum scale for `interval second` is 6 unfortunately so we have to use numeric by default
// The maximum scale for `interval second` is 6 unfortunately, so we have to use numeric by default
if ( scale == null || scale > 6 ) {
return DdlTypeImpl.replace( "numeric($p,$s)", size, precision, scale );
}

View File

@ -156,8 +156,9 @@ public class DdlTypeRegistry implements Serializable {
if ( descriptor == null ) {
throw new HibernateException(
String.format(
"No type mapping for java.sql.Types code: %s",
typeCode
"No type mapping for org.hibernate.type.SqlTypes code: %s (%s)",
typeCode,
JdbcTypeNameMapper.getTypeName( typeCode )
)
);
}