Skip to content

HHH-19624 Test EDB with EDB drivers #10573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 30 additions & 15 deletions docker_db.sh
Original file line number Diff line number Diff line change
Expand Up @@ -217,37 +217,52 @@ edb() {

edb_13() {
$CONTAINER_CLI rm -f edb || true
# We need to build a derived image because the existing image is mainly made for use by a kubernetes operator
(cd edb; $CONTAINER_CLI build -t edb-test:13 -f edb13.Dockerfile .)
$CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d edb-test:13
if [[ -z "${DB_IMAGE_EDB}" ]]; then
DB_IMAGE_EDB="edb-test:13"
# We need to build a derived image because the existing image is mainly made for use by a kubernetes operator
(cd edb; $CONTAINER_CLI build -t edb-test:13 -f edb13.Dockerfile .)
fi
$CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d $DB_IMAGE_EDB
}

edb_14() {
$CONTAINER_CLI rm -f edb || true
# We need to build a derived image because the existing image is mainly made for use by a kubernetes operator
(cd edb; $CONTAINER_CLI build -t edb-test:14 -f edb14.Dockerfile .)
$CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d edb-test:14
if [[ -z "${DB_IMAGE_EDB}" ]]; then
DB_IMAGE_EDB="edb-test:14"
# We need to build a derived image because the existing image is mainly made for use by a kubernetes operator
(cd edb; $CONTAINER_CLI build -t edb-test:14 -f edb14.Dockerfile .)
fi
$CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d $DB_IMAGE_EDB
}

edb_15() {
$CONTAINER_CLI rm -f edb || true
# We need to build a derived image because the existing image is mainly made for use by a kubernetes operator
(cd edb; $CONTAINER_CLI build -t edb-test:15 -f edb15.Dockerfile .)
$CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d edb-test:15
if [[ -z "${DB_IMAGE_EDB}" ]]; then
DB_IMAGE_EDB="edb-test:15"
# We need to build a derived image because the existing image is mainly made for use by a kubernetes operator
(cd edb; $CONTAINER_CLI build -t edb-test:15 -f edb15.Dockerfile .)
fi
$CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d $DB_IMAGE_EDB
}

edb_16() {
$CONTAINER_CLI rm -f edb || true
# We need to build a derived image because the existing image is mainly made for use by a kubernetes operator
(cd edb; $CONTAINER_CLI build -t edb-test:16 -f edb16.Dockerfile .)
$CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d edb-test:16
if [[ -z "${DB_IMAGE_EDB}" ]]; then
DB_IMAGE_EDB="edb-test:16"
# We need to build a derived image because the existing image is mainly made for use by a kubernetes operator
(cd edb; $CONTAINER_CLI build -t edb-test:16 -f edb16.Dockerfile .)
fi
$CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d $DB_IMAGE_EDB
}

edb_17() {
$CONTAINER_CLI rm -f edb || true
# We need to build a derived image because the existing image is mainly made for use by a kubernetes operator
(cd edb; $CONTAINER_CLI build -t edb-test:17 -f edb17.Dockerfile .)
$CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d edb-test:17
if [[ -z "${DB_IMAGE_EDB}" ]]; then
DB_IMAGE_EDB="edb-test:17"
# We need to build a derived image because the existing image is mainly made for use by a kubernetes operator
(cd edb; $CONTAINER_CLI build -t edb-test:17 -f edb17.Dockerfile .)
fi
$CONTAINER_CLI run --name edb -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p 5444:5444 -d $DB_IMAGE_EDB
}

db2() {
Expand Down
1 change: 1 addition & 0 deletions documentation/documentation.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ dependencies {
javadocClasspath jakartaLibs.jsonbApi
javadocClasspath libs.ant
javadocClasspath jdbcLibs.postgresql
javadocClasspath jdbcLibs.edb
javadocClasspath libs.jackson
javadocClasspath gradleApi()
javadocClasspath libs.jacksonXml
Expand Down
1 change: 1 addition & 0 deletions hibernate-core/hibernate-core.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ dependencies {
compileOnly libs.jackson
compileOnly libs.jacksonXml
compileOnly jdbcLibs.postgresql
compileOnly jdbcLibs.edb

testImplementation project(':hibernate-testing')
testImplementation project(':hibernate-ant')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ private static OptionalTableUpdateStrategy determineOptionalTableUpdateStrategy(
: PostgreSQLDialect::withoutMerge;
}

public PostgreSQLDriverKind getDriverKind() {
return driverKind;
}

@Override
protected DatabaseVersion getMinimumSupportedVersion() {
return MINIMUM_VERSION;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public void appendWriteExpression(
Dialect dialect) {
appender.append( '(' );
appender.append( writeExpression );
appender.append( "*interval'1 second)" );
appender.append( "*interval'1 second')" );
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.boot.spi.MetadataBuilderContributor;
import org.hibernate.boot.spi.MetadataBuilderImplementor;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
import org.hibernate.query.NativeQuery;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.spi.TypeConfiguration;

import org.hibernate.testing.RequiresDialect;

import org.hibernate.orm.test.id.usertype.inet.Inet;
import org.hibernate.orm.test.id.usertype.inet.InetJavaType;
import org.hibernate.orm.test.id.usertype.inet.InetJdbcType;
Expand All @@ -40,7 +39,7 @@
/**
* @author Vlad Mihalcea
*/
@RequiresDialect(PostgreSQLDialect.class)
@RequiresDialectFeature(feature = DialectFeatureChecks.IsPgJdbc.class)
public class PostgreSQLMultipleTypesOtherContributorTest extends BaseEntityManagerFunctionalTestCase {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.spi.MetadataBuilderContributor;
import org.hibernate.boot.spi.MetadataBuilderImplementor;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.type.spi.TypeConfiguration;

import org.hibernate.testing.RequiresDialect;
import org.junit.Test;

import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
Expand All @@ -23,7 +23,7 @@
/**
* @author Vlad Mihalcea
*/
@RequiresDialect(PostgreSQLDialect.class)
@RequiresDialectFeature(feature = DialectFeatureChecks.IsPgJdbc.class)
public class PostgreSQLInetTypesOtherContributorTest extends PostgreSQLInetTypesOtherTest {

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

import org.hibernate.boot.spi.MetadataBuilderContributor;
import org.hibernate.boot.spi.MetadataBuilderImplementor;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
import org.hibernate.query.NativeQuery;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.type.spi.TypeConfiguration;

import org.hibernate.testing.RequiresDialect;
import org.junit.Test;

import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
Expand All @@ -24,7 +24,7 @@
/**
* @author Vlad Mihalcea
*/
@RequiresDialect(PostgreSQLDialect.class)
@RequiresDialectFeature(feature = DialectFeatureChecks.IsPgJdbc.class)
public class PostgreSQLInetTypesOtherTest extends BaseEntityManagerFunctionalTestCase {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.LocalDateTime;
Expand Down Expand Up @@ -234,34 +233,6 @@ public void testFunctionWithJDBC() {
} );
}

@Test
public void testFunctionWithJDBCByName() {
doInJPA( this::entityManagerFactory, entityManager -> {
try {
Session session = entityManager.unwrap( Session.class );
Long phoneCount = session.doReturningWork( connection -> {
CallableStatement function = null;
try {
function = connection.prepareCall( "{ ? = call fn_count_phones(?) }" );
function.registerOutParameter( "phoneCount", Types.BIGINT );
function.setLong( "personId", 1L );
function.execute();
return function.getLong( 1 );
}
finally {
if ( function != null ) {
function.close();
}
}
} );
assertEquals( Long.valueOf( 2 ), phoneCount );
}
catch (Exception e) {
assertEquals( SQLFeatureNotSupportedException.class, e.getCause().getClass() );
}
} );
}

@Test
@JiraKey(value = "HHH-11863")
public void testSysRefCursorAsOutParameter() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.sql.Types;
Expand Down Expand Up @@ -118,34 +117,6 @@ public void testStoredProcedureWithJDBC(EntityManagerFactoryScope scope) {
} );
}

@Test
public void testProcedureWithJDBCByName(EntityManagerFactoryScope scope) {
scope.inTransaction( entityManager -> {
try {
Session session = entityManager.unwrap( Session.class );
Long phoneCount = session.doReturningWork( connection -> {
CallableStatement procedure = null;
try {
procedure = connection.prepareCall( "{ call sp_count_phones(?,?) }" );
procedure.registerOutParameter( "phoneCount", Types.BIGINT );
procedure.setLong( "personId", 1L );
procedure.execute();
return procedure.getLong( 1 );
}
finally {
if ( procedure != null ) {
procedure.close();
}
}
} );
assertEquals( Long.valueOf( 2 ), phoneCount );
}
catch (Exception e) {
assertEquals( SQLFeatureNotSupportedException.class, e.getCause().getClass() );
}
} );
}

@Test
@JiraKey("HHH-11863")
@RequiresDialect(value = PostgreSQLDialect.class, majorVersion = 14, comment = "Stored procedure OUT parameters are only supported since version 14")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.dialect.type.PostgreSQLCastingIntervalSecondJdbcType;
import org.hibernate.dialect.type.PostgreSQLIntervalSecondJdbcType;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
Expand Down Expand Up @@ -59,7 +60,7 @@ public void verifyMappings(SessionFactoryScope scope) {
assertThat( durationJdbcType ).isEqualTo( NumericJdbcType.INSTANCE );

final JdbcType intervalType = jdbcTypeRegistry.getDescriptor( SqlTypes.INTERVAL_SECOND );
assertThat( intervalType ).isOfAnyClassIn( PostgreSQLIntervalSecondJdbcType.class );
assertThat( intervalType ).isOfAnyClassIn( PostgreSQLIntervalSecondJdbcType.class, PostgreSQLCastingIntervalSecondJdbcType.class );

// a simple duration field with no overrides - so should be using a default JdbcType
assertThat( entityDescriptor.findAttributeMapping( "duration" )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,49 @@ else if ( "org.postgresql.Driver".equals( config.driverClassName ) ) {
}
} );
}
else if ( "com.edb.Driver".equals( config.driverClassName ) ) {
validateConnections( c -> {
// Until pgjdbc provides a method for this out of the box, we have to do this manually
// See https://github.com/pgjdbc/pgjdbc/issues/3049
try {
final Class<?> pgConnection = Class.forName( "com.edb.jdbc.PgConnection" );
final Object connection = c.unwrap( pgConnection );
final Object typeInfo = pgConnection.getMethod( "getTypeInfo" ).invoke( connection );
final Class<?> typeInfoCacheClass = Class.forName( "com.edb.jdbc.TypeInfoCache" );
final Field oidToPgNameField = typeInfoCacheClass.getDeclaredField( "oidToPgName" );
final Field pgNameToOidField = typeInfoCacheClass.getDeclaredField( "pgNameToOid" );
final Field pgNameToSQLTypeField = typeInfoCacheClass.getDeclaredField( "pgNameToSQLType" );
final Field oidToSQLTypeField = typeInfoCacheClass.getDeclaredField( "oidToSQLType" );
oidToPgNameField.setAccessible( true );
pgNameToOidField.setAccessible( true );
pgNameToSQLTypeField.setAccessible( true );
oidToSQLTypeField.setAccessible( true );
//noinspection unchecked
final Map<Integer, String> oidToPgName = (Map<Integer, String>) oidToPgNameField.get( typeInfo );
//noinspection unchecked
final Map<String, Integer> pgNameToOid = (Map<String, Integer>) pgNameToOidField.get( typeInfo );
//noinspection unchecked
final Map<String, Integer> pgNameToSQLType = (Map<String, Integer>) pgNameToSQLTypeField.get( typeInfo );
//noinspection unchecked
final Map<Integer, Integer> oidToSQLType = (Map<Integer, Integer>) oidToSQLTypeField.get( typeInfo );
for ( Iterator<Map.Entry<String, Integer>> iter = pgNameToOid.entrySet().iterator(); iter.hasNext(); ) {
Map.Entry<String, Integer> entry = iter.next();
final String typeName = entry.getKey();
if ( !PGJDBC_STANDARD_TYPE_NAMES.contains( typeName ) ) {
final Integer oid = entry.getValue();
oidToPgName.remove( oid );
oidToSQLType.remove( oid );
pgNameToSQLType.remove( typeName );
iter.remove();
}
}
return true;
}
catch (Exception e) {
throw new RuntimeException( e );
}
} );
}
}

public void onDefaultTimeZoneChange() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;

import org.hibernate.dialect.Dialect;
import org.hibernate.internal.util.StringHelper;
Expand All @@ -25,7 +26,9 @@
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.SkipForDialects;
import org.hibernate.testing.orm.junit.DialectContext;
import org.hibernate.testing.orm.junit.DialectFeatureCheck;
import org.hibernate.testing.orm.junit.DialectFilterExtension;
import org.hibernate.testing.orm.junit.RequiresDialectFeatureGroup;
import org.hibernate.testing.orm.junit.SkipForDialectGroup;
import org.junit.BeforeClass;
import org.junit.Ignore;
Expand Down Expand Up @@ -442,6 +445,30 @@ protected Ignore convertSkipToIgnore(FrameworkMethod frameworkMethod) {
}
}

Collection<org.hibernate.testing.orm.junit.RequiresDialectFeature> effectiveRequiresDialectFeatures = Helper.collectAnnotations(
org.hibernate.testing.orm.junit.RequiresDialectFeature.class,
RequiresDialectFeatureGroup.class,
frameworkMethod,
getTestClass()
);

for ( org.hibernate.testing.orm.junit.RequiresDialectFeature effectiveRequiresDialectFeature : effectiveRequiresDialectFeatures ) {
try {
final Class<? extends DialectFeatureCheck> featureClass = effectiveRequiresDialectFeature.feature();
final DialectFeatureCheck featureCheck = featureClass.getConstructor().newInstance();
boolean testResult = featureCheck.apply( dialect );
if ( effectiveRequiresDialectFeature.reverse() ) {
testResult = !testResult;
}
if ( !testResult ) {
return buildIgnore( effectiveRequiresDialectFeature );
}
}
catch (ReflectiveOperationException e) {
throw new RuntimeException( "Unable to instantiate DialectFeatureCheck class", e );
}
}

return null;
}

Expand Down Expand Up @@ -567,6 +594,14 @@ private Ignore buildIgnore(RequiresDialectFeature requiresDialectFeature) {
);
}

private Ignore buildIgnore(org.hibernate.testing.orm.junit.RequiresDialectFeature requiresDialectFeature) {
return buildIgnore(
String.format( Locale.ROOT, "Failed @RequiresDialectFeature [%s]", requiresDialectFeature.feature() ),
requiresDialectFeature.comment(),
requiresDialectFeature.jiraKey()
);
}

private boolean isMatch(Class<? extends Skip.Matcher> condition) {
try {
Skip.Matcher matcher = condition.newInstance();
Expand Down
Loading