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

View File

@ -221,14 +221,16 @@ public class PostgreSQLDialect extends Dialect {
.build() .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 ) ); ddlTypeRegistry.addDescriptor( new DdlTypeImpl( SQLXML, "xml", this ) );
if ( getVersion().isSameOrAfter( 8, 2 ) ) { if ( getVersion().isSameOrAfter( 8, 2 ) ) {
ddlTypeRegistry.addDescriptor( new DdlTypeImpl( UUID, "uuid", this ) ); 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 ) ) { if ( getVersion().isSameOrAfter( 9, 2 ) ) {
// Prefer jsonb if possible // Prefer jsonb if possible
@ -1169,14 +1171,18 @@ public class PostgreSQLDialect extends Dialect {
jdbcTypeRegistry.addDescriptor( XmlJdbcType.INSTANCE ); jdbcTypeRegistry.addDescriptor( XmlJdbcType.INSTANCE );
if ( driverKind == PostgreSQLDriverKind.PG_JDBC ) { if ( driverKind == PostgreSQLDriverKind.PG_JDBC ) {
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLInetJdbcType.INSTANCE ); if ( PostgreSQLPGObjectJdbcType.isUsable() ) {
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLIntervalSecondJdbcType.INSTANCE ); jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLInetJdbcType.INSTANCE );
jdbcTypeRegistry.addDescriptorIfAbsent( PostgreSQLIntervalSecondJdbcType.INSTANCE );
}
if ( getVersion().isSameOrAfter( 8, 2 ) ) { if ( getVersion().isSameOrAfter( 8, 2 ) ) {
// HHH-9562 // HHH-9562
jdbcTypeRegistry.addDescriptorIfAbsent( UUIDJdbcType.INSTANCE ); jdbcTypeRegistry.addDescriptorIfAbsent( UUIDJdbcType.INSTANCE );
if ( getVersion().isSameOrAfter( 9, 2 ) ) { 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.SQLException;
import java.sql.Types; import java.sql.Types;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.type.descriptor.ValueBinder; import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor; import org.hibernate.type.descriptor.ValueExtractor;
@ -30,14 +32,15 @@ import org.hibernate.type.descriptor.jdbc.JdbcType;
*/ */
public abstract class PostgreSQLPGObjectJdbcType implements 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 Constructor<Object> PG_OBJECT_CONSTRUCTOR;
private static final Method TYPE_SETTER; private static final Method TYPE_SETTER;
private static final Method VALUE_SETTER; private static final Method VALUE_SETTER;
static { static {
Constructor<Object> constructor; Constructor<Object> constructor = null;
Method typeSetter; Method typeSetter = null;
Method valueSetter; Method valueSetter = null;
try { try {
final Class<?> pgObjectClass = ReflectHelper.classForName( final Class<?> pgObjectClass = ReflectHelper.classForName(
"org.postgresql.util.PGobject", "org.postgresql.util.PGobject",
@ -49,7 +52,7 @@ public abstract class PostgreSQLPGObjectJdbcType implements JdbcType {
valueSetter = ReflectHelper.setterMethodOrNull( pgObjectClass, "value", String.class ); valueSetter = ReflectHelper.setterMethodOrNull( pgObjectClass, "value", String.class );
} }
catch (Exception e) { 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; PG_OBJECT_CONSTRUCTOR = constructor;
TYPE_SETTER = typeSetter; TYPE_SETTER = typeSetter;
@ -64,6 +67,10 @@ public abstract class PostgreSQLPGObjectJdbcType implements JdbcType {
this.sqlTypeCode = sqlTypeCode; this.sqlTypeCode = sqlTypeCode;
} }
public static boolean isUsable() {
return PG_OBJECT_CONSTRUCTOR != null;
}
@Override @Override
public int getJdbcTypeCode() { public int getJdbcTypeCode() {
return Types.OTHER; return Types.OTHER;

View File

@ -20,7 +20,7 @@ public class Scale6IntervalSecondDdlType extends DdlTypeImpl {
} }
@Override @Override
public String getTypeName(Long size, Integer precision, Integer scale) { 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 ) { if ( scale == null || scale > 6 ) {
return DdlTypeImpl.replace( "numeric($p,$s)", size, precision, scale ); return DdlTypeImpl.replace( "numeric($p,$s)", size, precision, scale );
} }

View File

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