Merge remote-tracking branch 'upstream/main' into wip/6.0
This commit is contained in:
commit
6d59fec436
|
@ -926,6 +926,7 @@ Valid options are defined by the `strategy` value of the https://docs.jboss.org/
|
||||||
|
|
||||||
`*hibernate.hbm2ddl.delimiter*` (e.g. `;`)::
|
`*hibernate.hbm2ddl.delimiter*` (e.g. `;`)::
|
||||||
Identifies the delimiter to use to separate schema management statements in script outputs.
|
Identifies the delimiter to use to separate schema management statements in script outputs.
|
||||||
|
The default value is `;`.
|
||||||
|
|
||||||
`*hibernate.schema_management_tool*` (e.g. A schema name)::
|
`*hibernate.schema_management_tool*` (e.g. A schema name)::
|
||||||
Used to specify the `SchemaManagementTool` to use for performing schema management. The default is to use `HibernateSchemaManagementTool`.
|
Used to specify the `SchemaManagementTool` to use for performing schema management. The default is to use `HibernateSchemaManagementTool`.
|
||||||
|
|
|
@ -1967,7 +1967,8 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings {
|
||||||
String HBM2DDL_JDBC_METADATA_EXTRACTOR_STRATEGY = "hibernate.hbm2ddl.jdbc_metadata_extraction_strategy";
|
String HBM2DDL_JDBC_METADATA_EXTRACTOR_STRATEGY = "hibernate.hbm2ddl.jdbc_metadata_extraction_strategy";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies the delimiter to use to separate schema management statements in script outputs
|
* Identifies the delimiter to use to separate schema management statements in script outputs.
|
||||||
|
* The default value is <code>;</code>.
|
||||||
*/
|
*/
|
||||||
String HBM2DDL_DELIMITER = "hibernate.hbm2ddl.delimiter";
|
String HBM2DDL_DELIMITER = "hibernate.hbm2ddl.delimiter";
|
||||||
|
|
||||||
|
|
|
@ -3298,13 +3298,15 @@ public abstract class AbstractEntityPersister
|
||||||
* without resolving associations or collections. Question: should
|
* without resolving associations or collections. Question: should
|
||||||
* this really be here, or should it be sent back to Loader?
|
* this really be here, or should it be sent back to Loader?
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Object[] hydrate(
|
public Object[] hydrate(
|
||||||
final ResultSet rs,
|
final ResultSet rs,
|
||||||
final Object id,
|
final Object id,
|
||||||
final Object object,
|
final Object object,
|
||||||
final Loadable rootLoadable,
|
final Loadable rootLoadable,
|
||||||
final String[][] suffixedPropertyColumns,
|
final String[][] suffixedPropertyColumns,
|
||||||
final boolean allProperties,
|
final boolean forceEager,
|
||||||
|
final boolean[] propertiesForceEager,
|
||||||
final SharedSessionContractImplementor session) throws SQLException, HibernateException {
|
final SharedSessionContractImplementor session) throws SQLException, HibernateException {
|
||||||
|
|
||||||
if ( LOG.isTraceEnabled() ) {
|
if ( LOG.isTraceEnabled() ) {
|
||||||
|
@ -3366,7 +3368,7 @@ public abstract class AbstractEntityPersister
|
||||||
if ( !propertySelectable[i] ) {
|
if ( !propertySelectable[i] ) {
|
||||||
values[i] = PropertyAccessStrategyBackRefImpl.UNKNOWN;
|
values[i] = PropertyAccessStrategyBackRefImpl.UNKNOWN;
|
||||||
}
|
}
|
||||||
else if ( allProperties || !laziness[i] ) {
|
else if ( forceEager || !laziness[i] || propertiesForceEager != null && propertiesForceEager[i] ) {
|
||||||
//decide which ResultSet to get the property value from:
|
//decide which ResultSet to get the property value from:
|
||||||
final boolean propertyIsDeferred = hasDeferred &&
|
final boolean propertyIsDeferred = hasDeferred &&
|
||||||
rootPersister.isSubclassPropertyDeferred( propNames[i], propSubclassNames[i] );
|
rootPersister.isSubclassPropertyDeferred( propNames[i], propSubclassNames[i] );
|
||||||
|
|
|
@ -79,6 +79,20 @@ public interface Loadable extends EntityPersister {
|
||||||
*/
|
*/
|
||||||
boolean hasRowId();
|
boolean hasRowId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve property values from one row of a result set
|
||||||
|
*/
|
||||||
|
default Object[] hydrate(
|
||||||
|
ResultSet rs,
|
||||||
|
Object id,
|
||||||
|
Object object,
|
||||||
|
Loadable rootLoadable,
|
||||||
|
String[][] suffixedPropertyColumns,
|
||||||
|
boolean forceEager,
|
||||||
|
SharedSessionContractImplementor session) throws SQLException, HibernateException {
|
||||||
|
return hydrate( rs, id, object, rootLoadable, suffixedPropertyColumns, forceEager, null, session );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve property values from one row of a result set
|
* Retrieve property values from one row of a result set
|
||||||
*/
|
*/
|
||||||
|
@ -88,7 +102,8 @@ public interface Loadable extends EntityPersister {
|
||||||
Object object,
|
Object object,
|
||||||
Loadable rootLoadable,
|
Loadable rootLoadable,
|
||||||
String[][] suffixedPropertyColumns,
|
String[][] suffixedPropertyColumns,
|
||||||
boolean allProperties,
|
boolean forceEager,
|
||||||
|
boolean[] propertiesForceEager,
|
||||||
SharedSessionContractImplementor session) throws SQLException, HibernateException;
|
SharedSessionContractImplementor session) throws SQLException, HibernateException;
|
||||||
|
|
||||||
boolean isAbstract();
|
boolean isAbstract();
|
||||||
|
|
|
@ -224,7 +224,7 @@ public class StatisticsImpl implements StatisticsImplementor, Service, Manageabl
|
||||||
public EntityStatisticsImpl getEntityStatistics(String entityName) {
|
public EntityStatisticsImpl getEntityStatistics(String entityName) {
|
||||||
return entityStatsMap.getOrCompute(
|
return entityStatsMap.getOrCompute(
|
||||||
entityName,
|
entityName,
|
||||||
s -> new EntityStatisticsImpl( metamodel.entityPersister( s ) )
|
this::instantiateEntityStatistics
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ public class StatisticsImpl implements StatisticsImplementor, Service, Manageabl
|
||||||
public CollectionStatisticsImpl getCollectionStatistics(String role) {
|
public CollectionStatisticsImpl getCollectionStatistics(String role) {
|
||||||
return collectionStatsMap.getOrCompute(
|
return collectionStatsMap.getOrCompute(
|
||||||
role,
|
role,
|
||||||
s -> new CollectionStatisticsImpl( metamodel.collectionPersister( s ) )
|
this::instantiateCollectionStatistics
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,13 +416,7 @@ public class StatisticsImpl implements StatisticsImplementor, Service, Manageabl
|
||||||
public NaturalIdStatisticsImpl getNaturalIdStatistics(String rootEntityName) {
|
public NaturalIdStatisticsImpl getNaturalIdStatistics(String rootEntityName) {
|
||||||
return naturalIdQueryStatsMap.getOrCompute(
|
return naturalIdQueryStatsMap.getOrCompute(
|
||||||
rootEntityName,
|
rootEntityName,
|
||||||
s -> {
|
this::instantiateNaturalStatistics
|
||||||
final EntityPersister entityDescriptor = metamodel.entityPersister( s );
|
|
||||||
if ( !entityDescriptor.hasNaturalIdentifier() ) {
|
|
||||||
throw new IllegalArgumentException( "Given entity [" + s + "] does not define natural-id" );
|
|
||||||
}
|
|
||||||
return new NaturalIdStatisticsImpl( entityDescriptor );
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,10 +425,7 @@ public class StatisticsImpl implements StatisticsImplementor, Service, Manageabl
|
||||||
final String key = cache.unqualifyRegionName( regionName );
|
final String key = cache.unqualifyRegionName( regionName );
|
||||||
return deprecatedNaturalIdStatsMap.getOrCompute(
|
return deprecatedNaturalIdStatsMap.getOrCompute(
|
||||||
key,
|
key,
|
||||||
unqualifiedRegionName -> new DeprecatedNaturalIdCacheStatisticsImpl(
|
this::instantiateDeprecatedNaturalIdCacheStatistics
|
||||||
unqualifiedRegionName,
|
|
||||||
cache.getNaturalIdAccessesInRegion( unqualifiedRegionName )
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,21 +554,7 @@ public class StatisticsImpl implements StatisticsImplementor, Service, Manageabl
|
||||||
public CacheRegionStatisticsImpl getDomainDataRegionStatistics(String regionName) {
|
public CacheRegionStatisticsImpl getDomainDataRegionStatistics(String regionName) {
|
||||||
return l2CacheStatsMap.getOrCompute(
|
return l2CacheStatsMap.getOrCompute(
|
||||||
regionName,
|
regionName,
|
||||||
s -> {
|
this::instantiateCacheRegionStatistics
|
||||||
final Region region = cache.getRegion( s );
|
|
||||||
|
|
||||||
if ( region == null ) {
|
|
||||||
throw new IllegalArgumentException( "Unknown cache region : " + s );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( region instanceof QueryResultsRegion ) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Region name [" + s + "] referred to a query result region, not a domain data region"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new CacheRegionStatisticsImpl( region );
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,22 +585,7 @@ public class StatisticsImpl implements StatisticsImplementor, Service, Manageabl
|
||||||
|
|
||||||
return l2CacheStatsMap.getOrCompute(
|
return l2CacheStatsMap.getOrCompute(
|
||||||
regionName,
|
regionName,
|
||||||
s -> {
|
this::createCacheRegionStatistics
|
||||||
Region region = cache.getRegion( s );
|
|
||||||
|
|
||||||
if ( region == null ) {
|
|
||||||
|
|
||||||
if ( ! queryCacheEnabled ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is the pre-5.3 behavior. and since this is a pre-5.3 method it should behave consistently
|
|
||||||
// NOTE that this method is deprecated
|
|
||||||
region = cache.getQueryResultsCache( s ).getRegion();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new CacheRegionStatisticsImpl( region );
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -816,7 +778,7 @@ public class StatisticsImpl implements StatisticsImplementor, Service, Manageabl
|
||||||
private CacheRegionStatisticsImpl getQueryRegionStats(String regionName) {
|
private CacheRegionStatisticsImpl getQueryRegionStats(String regionName) {
|
||||||
return l2CacheStatsMap.getOrCompute(
|
return l2CacheStatsMap.getOrCompute(
|
||||||
regionName,
|
regionName,
|
||||||
s -> new CacheRegionStatisticsImpl( cache.getQueryResultsCache( regionName ).getRegion() )
|
this::instantiateCacheRegionStatsForQueryResults
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -989,4 +951,64 @@ public class StatisticsImpl implements StatisticsImplementor, Service, Manageabl
|
||||||
.append( ']' )
|
.append( ']' )
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private EntityStatisticsImpl instantiateEntityStatistics(final String entityName) {
|
||||||
|
return new EntityStatisticsImpl( metamodel.entityPersister( entityName ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private CollectionStatisticsImpl instantiateCollectionStatistics(final String role) {
|
||||||
|
return new CollectionStatisticsImpl( metamodel.collectionPersister( role ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private NaturalIdStatisticsImpl instantiateNaturalStatistics(final String entityName) {
|
||||||
|
final EntityPersister entityDescriptor = metamodel.entityPersister( entityName );
|
||||||
|
if ( !entityDescriptor.hasNaturalIdentifier() ) {
|
||||||
|
throw new IllegalArgumentException( "Given entity [" + entityName + "] does not define natural-id" );
|
||||||
|
}
|
||||||
|
return new NaturalIdStatisticsImpl( entityDescriptor );
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeprecatedNaturalIdCacheStatisticsImpl instantiateDeprecatedNaturalIdCacheStatistics(final String unqualifiedRegionName) {
|
||||||
|
return new DeprecatedNaturalIdCacheStatisticsImpl(
|
||||||
|
unqualifiedRegionName,
|
||||||
|
cache.getNaturalIdAccessesInRegion( unqualifiedRegionName )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CacheRegionStatisticsImpl instantiateCacheRegionStatistics(final String regionName) {
|
||||||
|
final Region region = cache.getRegion( regionName );
|
||||||
|
|
||||||
|
if ( region == null ) {
|
||||||
|
throw new IllegalArgumentException( "Unknown cache region : " + regionName );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( region instanceof QueryResultsRegion ) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Region name [" + regionName + "] referred to a query result region, not a domain data region"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CacheRegionStatisticsImpl( region );
|
||||||
|
}
|
||||||
|
|
||||||
|
private CacheRegionStatisticsImpl instantiateCacheRegionStatsForQueryResults(final String regionName) {
|
||||||
|
return new CacheRegionStatisticsImpl( cache.getQueryResultsCache( regionName ).getRegion() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private CacheRegionStatisticsImpl createCacheRegionStatistics(final String regionName) {
|
||||||
|
Region region = cache.getRegion( regionName );
|
||||||
|
|
||||||
|
if ( region == null ) {
|
||||||
|
|
||||||
|
if ( !queryCacheEnabled ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is the pre-5.3 behavior. and since this is a pre-5.3 method it should behave consistently
|
||||||
|
// NOTE that this method is deprecated
|
||||||
|
region = cache.getQueryResultsCache( regionName ).getRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CacheRegionStatisticsImpl( region );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,7 +123,7 @@ public class HibernateSchemaManagementTool implements SchemaManagementTool, Serv
|
||||||
JdbcContext jdbcContext,
|
JdbcContext jdbcContext,
|
||||||
Map options,
|
Map options,
|
||||||
boolean needsAutoCommit) {
|
boolean needsAutoCommit) {
|
||||||
final String scriptDelimiter = ConfigurationHelper.getString( HBM2DDL_DELIMITER, options );
|
final String scriptDelimiter = ConfigurationHelper.getString( HBM2DDL_DELIMITER, options, ";" );
|
||||||
|
|
||||||
final GenerationTarget[] targets = new GenerationTarget[ targetDescriptor.getTargetTypes().size() ];
|
final GenerationTarget[] targets = new GenerationTarget[ targetDescriptor.getTargetTypes().size() ];
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ public class HibernateSchemaManagementTool implements SchemaManagementTool, Serv
|
||||||
TargetDescriptor targetDescriptor,
|
TargetDescriptor targetDescriptor,
|
||||||
DdlTransactionIsolator ddlTransactionIsolator,
|
DdlTransactionIsolator ddlTransactionIsolator,
|
||||||
Map options) {
|
Map options) {
|
||||||
final String scriptDelimiter = ConfigurationHelper.getString( HBM2DDL_DELIMITER, options );
|
final String scriptDelimiter = ConfigurationHelper.getString( HBM2DDL_DELIMITER, options, ";" );
|
||||||
|
|
||||||
final GenerationTarget[] targets = new GenerationTarget[ targetDescriptor.getTargetTypes().size() ];
|
final GenerationTarget[] targets = new GenerationTarget[ targetDescriptor.getTargetTypes().size() ];
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class PostgreSQLMultipleSchemaSequenceTest extends BaseUnitTestCase {
|
||||||
);
|
);
|
||||||
try(Statement statement = ddlTransactionIsolator1.getIsolatedConnection().createStatement()) {
|
try(Statement statement = ddlTransactionIsolator1.getIsolatedConnection().createStatement()) {
|
||||||
statement.execute( String.format( "DROP SCHEMA IF EXISTS %s CASCADE", extraSchemaName ) );
|
statement.execute( String.format( "DROP SCHEMA IF EXISTS %s CASCADE", extraSchemaName ) );
|
||||||
statement.execute( String.format( "CREATE SCHEMA %s", extraSchemaName ) );
|
statement.execute( String.format( "CREATE SCHEMA %s;", extraSchemaName ) );
|
||||||
|
|
||||||
try(ResultSet resultSet = statement.executeQuery( "SELECT NEXTVAL('SEQ_TEST')" )) {
|
try(ResultSet resultSet = statement.executeQuery( "SELECT NEXTVAL('SEQ_TEST')" )) {
|
||||||
while ( resultSet.next() ) {
|
while ( resultSet.next() ) {
|
||||||
|
@ -156,7 +156,7 @@ public class PostgreSQLMultipleSchemaSequenceTest extends BaseUnitTestCase {
|
||||||
assertEquals( 2 ,
|
assertEquals( 2 ,
|
||||||
sqlLines
|
sqlLines
|
||||||
.stream()
|
.stream()
|
||||||
.filter( s -> s.equalsIgnoreCase( "create sequence SEQ_TEST start with 1 increment by 1" ) )
|
.filter( s -> s.equalsIgnoreCase( "create sequence SEQ_TEST start with 1 increment by 1;" ) )
|
||||||
.count()
|
.count()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class TableCommentTest extends BaseNonConfigCoreFunctionalTestCase {
|
||||||
final String tableName = getTableName();
|
final String tableName = getTableName();
|
||||||
for ( String sqlStatement : sqlLines ) {
|
for ( String sqlStatement : sqlLines ) {
|
||||||
if ( sqlStatement.toLowerCase()
|
if ( sqlStatement.toLowerCase()
|
||||||
.equals( "comment on table " + tableName.toLowerCase() + " is 'comment snippet'" ) ) {
|
.equals( "comment on table " + tableName.toLowerCase() + " is 'comment snippet';" ) ) {
|
||||||
if ( getDialect().supportsCommentOn() ) {
|
if ( getDialect().supportsCommentOn() ) {
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,12 +68,12 @@ public class SequenceGenerationTest extends BaseUnitTestCase {
|
||||||
List<String> commands = Files.readAllLines( output.toPath() );
|
List<String> commands = Files.readAllLines( output.toPath() );
|
||||||
|
|
||||||
assertThat(
|
assertThat(
|
||||||
isCommandGenerated( commands, "create table test_entity \\(id .*, primary key \\(id\\)\\)" ),
|
isCommandGenerated( commands, "create table test_entity \\(id .*, primary key \\(id\\)\\);" ),
|
||||||
is( true )
|
is( true )
|
||||||
);
|
);
|
||||||
|
|
||||||
assertThat(
|
assertThat(
|
||||||
isCommandGenerated( commands, "create sequence sequence_generator start with 5 increment by 3" ),
|
isCommandGenerated( commands, "create sequence sequence_generator start with 5 increment by 3;" ),
|
||||||
is( true )
|
is( true )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,12 +70,12 @@ public class SequenceGeneratorsTest extends BaseUnitTestCase {
|
||||||
List<String> commands = Files.readAllLines( output.toPath() );
|
List<String> commands = Files.readAllLines( output.toPath() );
|
||||||
|
|
||||||
assertThat(
|
assertThat(
|
||||||
isCommandGenerated( commands, "CREATE TABLE TEST_ENTITY \\(ID .*, PRIMARY KEY \\(ID\\)\\)" ),
|
isCommandGenerated( commands, "CREATE TABLE TEST_ENTITY \\(ID .*, PRIMARY KEY \\(ID\\)\\);" ),
|
||||||
is( true )
|
is( true )
|
||||||
);
|
);
|
||||||
|
|
||||||
assertThat(
|
assertThat(
|
||||||
isCommandGenerated( commands, "CREATE SEQUENCE SEQUENCE_GENERATOR START WITH 5 INCREMENT BY 3" ),
|
isCommandGenerated( commands, "CREATE SEQUENCE SEQUENCE_GENERATOR START WITH 5 INCREMENT BY 3;" ),
|
||||||
is( true )
|
is( true )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,13 +71,13 @@ public class TableGeneratorTest extends BaseUnitTestCase {
|
||||||
|
|
||||||
final List<String> commands = Files.readAllLines( output.toPath() );
|
final List<String> commands = Files.readAllLines( output.toPath() );
|
||||||
|
|
||||||
final String expectedTestEntityTableCreationCommand = "CREATE TABLE TEST_ENTITY \\(ID .*, PRIMARY KEY \\(ID\\)\\)";
|
final String expectedTestEntityTableCreationCommand = "CREATE TABLE TEST_ENTITY \\(ID .*, PRIMARY KEY \\(ID\\)\\);";
|
||||||
assertTrue(
|
assertTrue(
|
||||||
"The command '" + expectedTestEntityTableCreationCommand + "' has not been correctly generated",
|
"The command '" + expectedTestEntityTableCreationCommand + "' has not been correctly generated",
|
||||||
isCommandGenerated( commands, expectedTestEntityTableCreationCommand )
|
isCommandGenerated( commands, expectedTestEntityTableCreationCommand )
|
||||||
);
|
);
|
||||||
|
|
||||||
final String expectedIdTableGeneratorCreationCommand = "CREATE TABLE ID_TABLE_GENERATOR \\(PK .*, VALUE .*, PRIMARY KEY \\(PK\\)\\)";
|
final String expectedIdTableGeneratorCreationCommand = "CREATE TABLE ID_TABLE_GENERATOR \\(PK .*, VALUE .*, PRIMARY KEY \\(PK\\)\\);";
|
||||||
|
|
||||||
assertTrue(
|
assertTrue(
|
||||||
"The command '" + expectedIdTableGeneratorCreationCommand + "' has not been correctly generated",
|
"The command '" + expectedIdTableGeneratorCreationCommand + "' has not been correctly generated",
|
||||||
|
@ -88,7 +88,7 @@ public class TableGeneratorTest extends BaseUnitTestCase {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
final String expectedInsertIntoTableGeneratorCommand = "INSERT INTO ID_TABLE_GENERATOR\\(PK, VALUE\\) VALUES \\('TEST_ENTITY_ID'," + EXPECTED_DB_INSERTED_VALUE + "\\)";
|
final String expectedInsertIntoTableGeneratorCommand = "INSERT INTO ID_TABLE_GENERATOR\\(PK, VALUE\\) VALUES \\('TEST_ENTITY_ID'," + EXPECTED_DB_INSERTED_VALUE + "\\);";
|
||||||
|
|
||||||
assertTrue(
|
assertTrue(
|
||||||
"The command '" + expectedInsertIntoTableGeneratorCommand + "' has not been correctly generated",
|
"The command '" + expectedInsertIntoTableGeneratorCommand + "' has not been correctly generated",
|
||||||
|
|
|
@ -72,13 +72,13 @@ public class TableGeneratorsTest extends BaseUnitTestCase {
|
||||||
|
|
||||||
final List<String> commands = Files.readAllLines( output.toPath() );
|
final List<String> commands = Files.readAllLines( output.toPath() );
|
||||||
|
|
||||||
final String expectedTestEntityTableCreationCommand = "CREATE TABLE TEST_ENTITY \\(ID .*, PRIMARY KEY \\(ID\\)\\)";
|
final String expectedTestEntityTableCreationCommand = "CREATE TABLE TEST_ENTITY \\(ID .*, PRIMARY KEY \\(ID\\)\\);";
|
||||||
assertTrue(
|
assertTrue(
|
||||||
"The command '" + expectedTestEntityTableCreationCommand + "' has not been correctly generated",
|
"The command '" + expectedTestEntityTableCreationCommand + "' has not been correctly generated",
|
||||||
isCommandGenerated( commands, expectedTestEntityTableCreationCommand )
|
isCommandGenerated( commands, expectedTestEntityTableCreationCommand )
|
||||||
);
|
);
|
||||||
|
|
||||||
final String expectedIdTableGeneratorCreationCommand = "CREATE TABLE ID_TABLE_GENERATOR \\(PK .*, VALUE .*, PRIMARY KEY \\(PK\\)\\)";
|
final String expectedIdTableGeneratorCreationCommand = "CREATE TABLE ID_TABLE_GENERATOR \\(PK .*, VALUE .*, PRIMARY KEY \\(PK\\)\\);";
|
||||||
|
|
||||||
assertTrue(
|
assertTrue(
|
||||||
"The command '" + expectedIdTableGeneratorCreationCommand + "' has not been correctly generated",
|
"The command '" + expectedIdTableGeneratorCreationCommand + "' has not been correctly generated",
|
||||||
|
@ -89,7 +89,7 @@ public class TableGeneratorsTest extends BaseUnitTestCase {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
final String expectedInsertIntoTableGeneratorCommand = "INSERT INTO ID_TABLE_GENERATOR\\(PK, VALUE\\) VALUES \\('TEST_ENTITY_ID'," + EXPECTED_DB_INSERTED_VALUE + "\\)";
|
final String expectedInsertIntoTableGeneratorCommand = "INSERT INTO ID_TABLE_GENERATOR\\(PK, VALUE\\) VALUES \\('TEST_ENTITY_ID'," + EXPECTED_DB_INSERTED_VALUE + "\\);";
|
||||||
|
|
||||||
assertTrue(
|
assertTrue(
|
||||||
"The command '" + expectedInsertIntoTableGeneratorCommand + "' has not been correctly generated",
|
"The command '" + expectedInsertIntoTableGeneratorCommand + "' has not been correctly generated",
|
||||||
|
|
|
@ -93,7 +93,7 @@ public class UniqueConstraintGenerationTest {
|
||||||
|
|
||||||
private boolean isUniqueConstraintGenerated(String tableName, String columnName) throws IOException {
|
private boolean isUniqueConstraintGenerated(String tableName, String columnName) throws IOException {
|
||||||
boolean matches = false;
|
boolean matches = false;
|
||||||
final String regex = getDialect().getAlterTableString( tableName ) + " add constraint uk_(.)* unique \\(" + columnName + "\\)";
|
final String regex = getDialect().getAlterTableString( tableName ) + " add constraint uk_(.)* unique \\(" + columnName + "\\);";
|
||||||
|
|
||||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase();
|
final String fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase();
|
||||||
final String[] split = fileContent.split( System.lineSeparator() );
|
final String[] split = fileContent.split( System.lineSeparator() );
|
||||||
|
@ -109,7 +109,7 @@ public class UniqueConstraintGenerationTest {
|
||||||
|
|
||||||
private boolean isCreateUniqueIndexGenerated(String tableName, String columnName) throws IOException {
|
private boolean isCreateUniqueIndexGenerated(String tableName, String columnName) throws IOException {
|
||||||
boolean matches = false;
|
boolean matches = false;
|
||||||
String regex = "create unique index uk_(.)* on " + tableName + " \\(" + columnName + "\\)";
|
String regex = "create unique index uk_(.)* on " + tableName + " \\(" + columnName + "\\);";
|
||||||
|
|
||||||
final String fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase();
|
final String fileContent = new String( Files.readAllBytes( output.toPath() ) ).toLowerCase();
|
||||||
final String[] split = fileContent.split( System.lineSeparator() );
|
final String[] split = fileContent.split( System.lineSeparator() );
|
||||||
|
|
|
@ -26,6 +26,7 @@ import javax.persistence.criteria.JoinType;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.hibernate.Hibernate.isInitialized;
|
import static org.hibernate.Hibernate.isInitialized;
|
||||||
|
import static org.hibernate.Hibernate.isPropertyInitialized;
|
||||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
@ -142,6 +143,11 @@ public class HHH3949Test extends BaseCoreFunctionalTestCase {
|
||||||
for ( Person person : persons ) {
|
for ( Person person : persons ) {
|
||||||
assertTrue( isInitialized( person ) );
|
assertTrue( isInitialized( person ) );
|
||||||
if ( shouldHaveVehicle( person ) ) {
|
if ( shouldHaveVehicle( person ) ) {
|
||||||
|
// We used a "join fetch", so the vehicle must be initialized
|
||||||
|
// before we even call the getter
|
||||||
|
// (which could trigger lazy initialization if the join fetch didn't work).
|
||||||
|
assertTrue( isPropertyInitialized( person, "vehicle" ) );
|
||||||
|
|
||||||
assertNotNull( person.getVehicle() );
|
assertNotNull( person.getVehicle() );
|
||||||
assertTrue( isInitialized( person.getVehicle() ) );
|
assertTrue( isInitialized( person.getVehicle() ) );
|
||||||
assertNotNull( person.getVehicle().getDriver() );
|
assertNotNull( person.getVehicle().getDriver() );
|
||||||
|
@ -157,6 +163,11 @@ public class HHH3949Test extends BaseCoreFunctionalTestCase {
|
||||||
}
|
}
|
||||||
for ( Vehicle vehicle : vehicles ) {
|
for ( Vehicle vehicle : vehicles ) {
|
||||||
if ( shouldHaveDriver( vehicle ) ) {
|
if ( shouldHaveDriver( vehicle ) ) {
|
||||||
|
// We used a "join fetch", so the drover must be initialized
|
||||||
|
// before we even call the getter
|
||||||
|
// (which could trigger lazy initialization if the join fetch didn't work).
|
||||||
|
assertTrue( isPropertyInitialized( vehicle, "driver" ) );
|
||||||
|
|
||||||
assertNotNull( vehicle.getDriver() );
|
assertNotNull( vehicle.getDriver() );
|
||||||
assertNotNull( vehicle.getDriver().getVehicle() );
|
assertNotNull( vehicle.getDriver().getVehicle() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,17 @@ import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInter
|
||||||
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
|
import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLazinessInterceptor;
|
||||||
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.BeforeClassOnce;
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||||
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@ -36,6 +41,7 @@ import static org.hamcrest.CoreMatchers.not;
|
||||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hibernate.annotations.FetchMode.JOIN;
|
import static org.hibernate.annotations.FetchMode.JOIN;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for lazy uni-directional to-one (with JOIN fetching) when enhanced proxies are allowed
|
* Test for lazy uni-directional to-one (with JOIN fetching) when enhanced proxies are allowed
|
||||||
|
@ -61,17 +67,6 @@ public class JoinFetchedManyToOneAllowProxyTests extends BaseNonConfigCoreFuncti
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOwnerIsProxy() {
|
public void testOwnerIsProxy() {
|
||||||
inTransaction(
|
|
||||||
(session) -> {
|
|
||||||
final Customer customer = new Customer( 1, "Acme Brick" );
|
|
||||||
session.persist( customer );
|
|
||||||
final Order order = new Order( 1, customer, BigDecimal.ONE );
|
|
||||||
session.persist( order );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
sqlStatementInterceptor.clear();
|
|
||||||
|
|
||||||
final EntityPersister orderDescriptor = sessionFactory().getMetamodel().entityPersister( Order.class );
|
final EntityPersister orderDescriptor = sessionFactory().getMetamodel().entityPersister( Order.class );
|
||||||
final BytecodeEnhancementMetadata orderEnhancementMetadata = orderDescriptor.getBytecodeEnhancementMetadata();
|
final BytecodeEnhancementMetadata orderEnhancementMetadata = orderDescriptor.getBytecodeEnhancementMetadata();
|
||||||
assertThat( orderEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
assertThat( orderEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
||||||
|
@ -116,6 +111,50 @@ public class JoinFetchedManyToOneAllowProxyTests extends BaseNonConfigCoreFuncti
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14659")
|
||||||
|
public void testQueryJoinFetch() {
|
||||||
|
Order order = fromTransaction( (session) -> {
|
||||||
|
final Order result = session.createQuery(
|
||||||
|
"select o from Order o join fetch o.customer",
|
||||||
|
Order.class )
|
||||||
|
.uniqueResult();
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
return result;
|
||||||
|
} );
|
||||||
|
|
||||||
|
// The "join fetch" should have already initialized the property,
|
||||||
|
// so that the getter can safely be called outside of a session.
|
||||||
|
assertTrue( Hibernate.isPropertyInitialized( order, "customer" ) );
|
||||||
|
// The "join fetch" should have already initialized the associated entity.
|
||||||
|
Customer customer = order.getCustomer();
|
||||||
|
assertTrue( Hibernate.isInitialized( customer ) );
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void createTestData() {
|
||||||
|
inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
final Customer customer = new Customer( 1, "Acme Brick" );
|
||||||
|
session.persist( customer );
|
||||||
|
final Order order = new Order( 1, customer, BigDecimal.ONE );
|
||||||
|
session.persist( order );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
sqlStatementInterceptor.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void dropTestData() {
|
||||||
|
inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
session.createQuery( "delete Order" ).executeUpdate();
|
||||||
|
session.createQuery( "delete Customer" ).executeUpdate();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Entity( name = "Customer" )
|
@Entity( name = "Customer" )
|
||||||
@Table( name = "customer" )
|
@Table( name = "customer" )
|
||||||
public static class Customer {
|
public static class Customer {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import javax.persistence.Id;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
import org.hibernate.boot.MetadataSources;
|
import org.hibernate.boot.MetadataSources;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
|
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
|
||||||
|
@ -19,8 +20,10 @@ import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementAsProxyLaziness
|
||||||
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
|
import org.hibernate.bytecode.enhance.spi.interceptor.LazyAttributeLoadingInterceptor;
|
||||||
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||||
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
|
@ -36,6 +39,7 @@ import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.CoreMatchers.not;
|
import static org.hamcrest.CoreMatchers.not;
|
||||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for lazy uni-directional to-one (with SELECT fetching) when enhanced proxies are allowed
|
* Test for lazy uni-directional to-one (with SELECT fetching) when enhanced proxies are allowed
|
||||||
|
@ -61,8 +65,6 @@ public class ManyToOneAllowProxyTests extends BaseNonConfigCoreFunctionalTestCas
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOwnerIsProxy() {
|
public void testOwnerIsProxy() {
|
||||||
sqlStatementInterceptor.clear();
|
|
||||||
|
|
||||||
final EntityPersister orderDescriptor = sessionFactory().getMetamodel().entityPersister( Order.class );
|
final EntityPersister orderDescriptor = sessionFactory().getMetamodel().entityPersister( Order.class );
|
||||||
final BytecodeEnhancementMetadata orderEnhancementMetadata = orderDescriptor.getBytecodeEnhancementMetadata();
|
final BytecodeEnhancementMetadata orderEnhancementMetadata = orderDescriptor.getBytecodeEnhancementMetadata();
|
||||||
assertThat( orderEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
assertThat( orderEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
||||||
|
@ -115,6 +117,27 @@ public class ManyToOneAllowProxyTests extends BaseNonConfigCoreFunctionalTestCas
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14659")
|
||||||
|
public void testQueryJoinFetch() {
|
||||||
|
Order order = fromTransaction( (session) -> {
|
||||||
|
final Order result = session.createQuery(
|
||||||
|
"select o from Order o join fetch o.customer",
|
||||||
|
Order.class )
|
||||||
|
.uniqueResult();
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
return result;
|
||||||
|
} );
|
||||||
|
|
||||||
|
// The "join fetch" should have already initialized the property,
|
||||||
|
// so that the getter can safely be called outside of a session.
|
||||||
|
assertTrue( Hibernate.isPropertyInitialized( order, "customer" ) );
|
||||||
|
// The "join fetch" should have already initialized the associated entity.
|
||||||
|
Customer customer = order.getCustomer();
|
||||||
|
assertTrue( Hibernate.isInitialized( customer ) );
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void createTestData() {
|
public void createTestData() {
|
||||||
inTransaction(
|
inTransaction(
|
||||||
|
@ -125,6 +148,7 @@ public class ManyToOneAllowProxyTests extends BaseNonConfigCoreFunctionalTestCas
|
||||||
session.persist( order );
|
session.persist( order );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
sqlStatementInterceptor.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|
|
@ -12,6 +12,7 @@ import javax.persistence.Id;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
import org.hibernate.annotations.LazyToOne;
|
import org.hibernate.annotations.LazyToOne;
|
||||||
import org.hibernate.boot.MetadataSources;
|
import org.hibernate.boot.MetadataSources;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
@ -22,11 +23,13 @@ import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||||
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@ -37,6 +40,7 @@ import static org.hamcrest.CoreMatchers.not;
|
||||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hibernate.annotations.LazyToOneOption.NO_PROXY;
|
import static org.hibernate.annotations.LazyToOneOption.NO_PROXY;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Baseline test for uni-directional to-one, using an explicit @LazyToOne(NO_PROXY)
|
* Baseline test for uni-directional to-one, using an explicit @LazyToOne(NO_PROXY)
|
||||||
|
@ -64,17 +68,6 @@ public class ManyToOneExplicitOptionTests extends BaseNonConfigCoreFunctionalTes
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOwnerIsProxy() {
|
public void testOwnerIsProxy() {
|
||||||
inTransaction(
|
|
||||||
(session) -> {
|
|
||||||
final Customer customer = new Customer( 1, "Acme Brick" );
|
|
||||||
session.persist( customer );
|
|
||||||
final Order order = new Order( 1, customer, BigDecimal.ONE );
|
|
||||||
session.persist( order );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
sqlStatementInterceptor.clear();
|
|
||||||
|
|
||||||
final EntityPersister orderDescriptor = sessionFactory().getMetamodel().entityPersister( Order.class );
|
final EntityPersister orderDescriptor = sessionFactory().getMetamodel().entityPersister( Order.class );
|
||||||
final BytecodeEnhancementMetadata orderEnhancementMetadata = orderDescriptor.getBytecodeEnhancementMetadata();
|
final BytecodeEnhancementMetadata orderEnhancementMetadata = orderDescriptor.getBytecodeEnhancementMetadata();
|
||||||
assertThat( orderEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
assertThat( orderEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
||||||
|
@ -127,6 +120,40 @@ public class ManyToOneExplicitOptionTests extends BaseNonConfigCoreFunctionalTes
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14659")
|
||||||
|
public void testQueryJoinFetch() {
|
||||||
|
Order order = fromTransaction( (session) -> {
|
||||||
|
final Order result = session.createQuery(
|
||||||
|
"select o from Order o join fetch o.customer",
|
||||||
|
Order.class )
|
||||||
|
.uniqueResult();
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
return result;
|
||||||
|
} );
|
||||||
|
|
||||||
|
// The "join fetch" should have already initialized the property,
|
||||||
|
// so that the getter can safely be called outside of a session.
|
||||||
|
assertTrue( Hibernate.isPropertyInitialized( order, "customer" ) );
|
||||||
|
// The "join fetch" should have already initialized the associated entity.
|
||||||
|
Customer customer = order.getCustomer();
|
||||||
|
assertTrue( Hibernate.isInitialized( customer ) );
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void createTestData() {
|
||||||
|
inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
final Customer customer = new Customer( 1, "Acme Brick" );
|
||||||
|
session.persist( customer );
|
||||||
|
final Order order = new Order( 1, customer, BigDecimal.ONE );
|
||||||
|
session.persist( order );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
sqlStatementInterceptor.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void dropTestData() {
|
public void dropTestData() {
|
||||||
inTransaction(
|
inTransaction(
|
||||||
|
|
|
@ -11,6 +11,7 @@ import javax.persistence.Id;
|
||||||
import javax.persistence.OneToOne;
|
import javax.persistence.OneToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
import org.hibernate.boot.MetadataSources;
|
import org.hibernate.boot.MetadataSources;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
|
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
|
||||||
|
@ -20,6 +21,7 @@ import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||||
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
|
@ -35,6 +37,7 @@ import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.CoreMatchers.not;
|
import static org.hamcrest.CoreMatchers.not;
|
||||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -60,8 +63,6 @@ public class InverseToOneAllowProxyTests extends BaseNonConfigCoreFunctionalTest
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOwnerIsProxy() {
|
public void testOwnerIsProxy() {
|
||||||
sqlStatementInterceptor.clear();
|
|
||||||
|
|
||||||
final EntityPersister supplementalInfoDescriptor = sessionFactory().getMetamodel().entityPersister( SupplementalInfo.class );
|
final EntityPersister supplementalInfoDescriptor = sessionFactory().getMetamodel().entityPersister( SupplementalInfo.class );
|
||||||
final BytecodeEnhancementMetadata supplementalInfoEnhancementMetadata = supplementalInfoDescriptor.getBytecodeEnhancementMetadata();
|
final BytecodeEnhancementMetadata supplementalInfoEnhancementMetadata = supplementalInfoDescriptor.getBytecodeEnhancementMetadata();
|
||||||
assertThat( supplementalInfoEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
assertThat( supplementalInfoEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
||||||
|
@ -113,6 +114,27 @@ public class InverseToOneAllowProxyTests extends BaseNonConfigCoreFunctionalTest
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14659")
|
||||||
|
public void testQueryJoinFetch() {
|
||||||
|
SupplementalInfo info = fromTransaction( (session) -> {
|
||||||
|
final SupplementalInfo result = session.createQuery(
|
||||||
|
"select s from SupplementalInfo s join fetch s.customer",
|
||||||
|
SupplementalInfo.class )
|
||||||
|
.uniqueResult();
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
return result;
|
||||||
|
} );
|
||||||
|
|
||||||
|
// The "join fetch" should have already initialized the property,
|
||||||
|
// so that the getter can safely be called outside of a session.
|
||||||
|
assertTrue( Hibernate.isPropertyInitialized( info, "customer" ) );
|
||||||
|
// The "join fetch" should have already initialized the associated entity.
|
||||||
|
Customer customer = info.getCustomer();
|
||||||
|
assertTrue( Hibernate.isInitialized( customer ) );
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void createTestData() {
|
public void createTestData() {
|
||||||
inTransaction(
|
inTransaction(
|
||||||
|
@ -123,6 +145,7 @@ public class InverseToOneAllowProxyTests extends BaseNonConfigCoreFunctionalTest
|
||||||
session.persist( supplementalInfo );
|
session.persist( supplementalInfo );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
sqlStatementInterceptor.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|
|
@ -11,6 +11,7 @@ import javax.persistence.Id;
|
||||||
import javax.persistence.OneToOne;
|
import javax.persistence.OneToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
import org.hibernate.annotations.LazyToOne;
|
import org.hibernate.annotations.LazyToOne;
|
||||||
import org.hibernate.boot.MetadataSources;
|
import org.hibernate.boot.MetadataSources;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
@ -20,11 +21,13 @@ import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||||
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@ -33,6 +36,7 @@ import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hibernate.annotations.LazyToOneOption.NO_PROXY;
|
import static org.hibernate.annotations.LazyToOneOption.NO_PROXY;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Baseline test for inverse (mappedBy) to-one, using an explicit @LazyToOne(NO_PROXY)
|
* Baseline test for inverse (mappedBy) to-one, using an explicit @LazyToOne(NO_PROXY)
|
||||||
|
@ -58,17 +62,6 @@ public class InverseToOneExplicitOptionTests extends BaseNonConfigCoreFunctional
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOwnerIsProxy() {
|
public void testOwnerIsProxy() {
|
||||||
inTransaction(
|
|
||||||
(session) -> {
|
|
||||||
final Customer customer = new Customer( 1, "Acme Brick" );
|
|
||||||
session.persist( customer );
|
|
||||||
final SupplementalInfo supplementalInfo = new SupplementalInfo( 1, customer, "extra details" );
|
|
||||||
session.persist( supplementalInfo );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
sqlStatementInterceptor.clear();
|
|
||||||
|
|
||||||
final EntityPersister supplementalInfoDescriptor = sessionFactory().getMetamodel().entityPersister( SupplementalInfo.class );
|
final EntityPersister supplementalInfoDescriptor = sessionFactory().getMetamodel().entityPersister( SupplementalInfo.class );
|
||||||
final BytecodeEnhancementMetadata supplementalInfoEnhancementMetadata = supplementalInfoDescriptor.getBytecodeEnhancementMetadata();
|
final BytecodeEnhancementMetadata supplementalInfoEnhancementMetadata = supplementalInfoDescriptor.getBytecodeEnhancementMetadata();
|
||||||
assertThat( supplementalInfoEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
assertThat( supplementalInfoEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
||||||
|
@ -140,6 +133,40 @@ public class InverseToOneExplicitOptionTests extends BaseNonConfigCoreFunctional
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14659")
|
||||||
|
public void testQueryJoinFetch() {
|
||||||
|
SupplementalInfo info = fromTransaction( (session) -> {
|
||||||
|
final SupplementalInfo result = session.createQuery(
|
||||||
|
"select s from SupplementalInfo s join fetch s.customer",
|
||||||
|
SupplementalInfo.class )
|
||||||
|
.uniqueResult();
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
return result;
|
||||||
|
} );
|
||||||
|
|
||||||
|
// The "join fetch" should have already initialized the property,
|
||||||
|
// so that the getter can safely be called outside of a session.
|
||||||
|
assertTrue( Hibernate.isPropertyInitialized( info, "customer" ) );
|
||||||
|
// The "join fetch" should have already initialized the associated entity.
|
||||||
|
Customer customer = info.getCustomer();
|
||||||
|
assertTrue( Hibernate.isInitialized( customer ) );
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void createTestData() {
|
||||||
|
inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
final Customer customer = new Customer( 1, "Acme Brick" );
|
||||||
|
session.persist( customer );
|
||||||
|
final SupplementalInfo supplementalInfo = new SupplementalInfo( 1, customer, "extra details" );
|
||||||
|
session.persist( supplementalInfo );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
sqlStatementInterceptor.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void dropTestData() {
|
public void dropTestData() {
|
||||||
inTransaction(
|
inTransaction(
|
||||||
|
|
|
@ -11,6 +11,7 @@ import javax.persistence.Id;
|
||||||
import javax.persistence.OneToOne;
|
import javax.persistence.OneToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
import org.hibernate.annotations.Fetch;
|
import org.hibernate.annotations.Fetch;
|
||||||
import org.hibernate.boot.MetadataSources;
|
import org.hibernate.boot.MetadataSources;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
@ -21,6 +22,7 @@ import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||||
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
|
@ -37,6 +39,7 @@ import static org.hamcrest.CoreMatchers.not;
|
||||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hibernate.annotations.FetchMode.JOIN;
|
import static org.hibernate.annotations.FetchMode.JOIN;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -62,8 +65,6 @@ public class JoinFetchedInverseToOneAllowProxyTests extends BaseNonConfigCoreFun
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOwnerIsProxy() {
|
public void testOwnerIsProxy() {
|
||||||
sqlStatementInterceptor.clear();
|
|
||||||
|
|
||||||
final EntityPersister supplementalInfoDescriptor = sessionFactory().getMetamodel().entityPersister( SupplementalInfo.class );
|
final EntityPersister supplementalInfoDescriptor = sessionFactory().getMetamodel().entityPersister( SupplementalInfo.class );
|
||||||
final BytecodeEnhancementMetadata supplementalInfoEnhancementMetadata = supplementalInfoDescriptor.getBytecodeEnhancementMetadata();
|
final BytecodeEnhancementMetadata supplementalInfoEnhancementMetadata = supplementalInfoDescriptor.getBytecodeEnhancementMetadata();
|
||||||
assertThat( supplementalInfoEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
assertThat( supplementalInfoEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
||||||
|
@ -110,6 +111,27 @@ public class JoinFetchedInverseToOneAllowProxyTests extends BaseNonConfigCoreFun
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14659")
|
||||||
|
public void testQueryJoinFetch() {
|
||||||
|
SupplementalInfo info = fromTransaction( (session) -> {
|
||||||
|
final SupplementalInfo result = session.createQuery(
|
||||||
|
"select s from SupplementalInfo s join fetch s.customer",
|
||||||
|
SupplementalInfo.class )
|
||||||
|
.uniqueResult();
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
return result;
|
||||||
|
} );
|
||||||
|
|
||||||
|
// The "join fetch" should have already initialized the property,
|
||||||
|
// so that the getter can safely be called outside of a session.
|
||||||
|
assertTrue( Hibernate.isPropertyInitialized( info, "customer" ) );
|
||||||
|
// The "join fetch" should have already initialized the associated entity.
|
||||||
|
Customer customer = info.getCustomer();
|
||||||
|
assertTrue( Hibernate.isInitialized( customer ) );
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void createTestData() {
|
public void createTestData() {
|
||||||
inTransaction(
|
inTransaction(
|
||||||
|
@ -120,6 +142,7 @@ public class JoinFetchedInverseToOneAllowProxyTests extends BaseNonConfigCoreFun
|
||||||
session.persist( supplementalInfo );
|
session.persist( supplementalInfo );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
sqlStatementInterceptor.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|
|
@ -11,6 +11,7 @@ import javax.persistence.Id;
|
||||||
import javax.persistence.OneToOne;
|
import javax.persistence.OneToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
import org.hibernate.annotations.Fetch;
|
import org.hibernate.annotations.Fetch;
|
||||||
import org.hibernate.boot.MetadataSources;
|
import org.hibernate.boot.MetadataSources;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
@ -18,6 +19,7 @@ import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||||
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
|
@ -31,6 +33,7 @@ import static javax.persistence.FetchType.LAZY;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hibernate.annotations.FetchMode.JOIN;
|
import static org.hibernate.annotations.FetchMode.JOIN;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -56,8 +59,6 @@ public class JoinFetchedOneToOneAllowProxyTests extends BaseNonConfigCoreFunctio
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOwnerIsProxy() {
|
public void testOwnerIsProxy() {
|
||||||
sqlStatementInterceptor.clear();
|
|
||||||
|
|
||||||
final EntityPersister supplementalInfoDescriptor = sessionFactory().getMetamodel().entityPersister( SupplementalInfo.class );
|
final EntityPersister supplementalInfoDescriptor = sessionFactory().getMetamodel().entityPersister( SupplementalInfo.class );
|
||||||
final BytecodeEnhancementMetadata supplementalInfoEnhancementMetadata = supplementalInfoDescriptor.getBytecodeEnhancementMetadata();
|
final BytecodeEnhancementMetadata supplementalInfoEnhancementMetadata = supplementalInfoDescriptor.getBytecodeEnhancementMetadata();
|
||||||
assertThat( supplementalInfoEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
assertThat( supplementalInfoEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
||||||
|
@ -94,6 +95,27 @@ public class JoinFetchedOneToOneAllowProxyTests extends BaseNonConfigCoreFunctio
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14659")
|
||||||
|
public void testQueryJoinFetch() {
|
||||||
|
SupplementalInfo info = fromTransaction( (session) -> {
|
||||||
|
final SupplementalInfo result = session.createQuery(
|
||||||
|
"select s from SupplementalInfo s join fetch s.customer",
|
||||||
|
SupplementalInfo.class )
|
||||||
|
.uniqueResult();
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
return result;
|
||||||
|
} );
|
||||||
|
|
||||||
|
// The "join fetch" should have already initialized the property,
|
||||||
|
// so that the getter can safely be called outside of a session.
|
||||||
|
assertTrue( Hibernate.isPropertyInitialized( info, "customer" ) );
|
||||||
|
// The "join fetch" should have already initialized the associated entity.
|
||||||
|
Customer customer = info.getCustomer();
|
||||||
|
assertTrue( Hibernate.isInitialized( customer ) );
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void createTestData() {
|
public void createTestData() {
|
||||||
inTransaction(
|
inTransaction(
|
||||||
|
@ -104,6 +126,7 @@ public class JoinFetchedOneToOneAllowProxyTests extends BaseNonConfigCoreFunctio
|
||||||
session.persist( supplementalInfo );
|
session.persist( supplementalInfo );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
sqlStatementInterceptor.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|
|
@ -11,6 +11,7 @@ import javax.persistence.Id;
|
||||||
import javax.persistence.OneToOne;
|
import javax.persistence.OneToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
import org.hibernate.boot.MetadataSources;
|
import org.hibernate.boot.MetadataSources;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
|
import org.hibernate.bytecode.enhance.spi.interceptor.BytecodeLazyAttributeInterceptor;
|
||||||
|
@ -20,6 +21,7 @@ import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||||
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
|
@ -35,6 +37,7 @@ import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.CoreMatchers.not;
|
import static org.hamcrest.CoreMatchers.not;
|
||||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -60,8 +63,6 @@ public class OneToOneAllowProxyTests extends BaseNonConfigCoreFunctionalTestCase
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOwnerIsProxy() {
|
public void testOwnerIsProxy() {
|
||||||
sqlStatementInterceptor.clear();
|
|
||||||
|
|
||||||
final EntityPersister supplementalInfoDescriptor = sessionFactory().getMetamodel().entityPersister( SupplementalInfo.class );
|
final EntityPersister supplementalInfoDescriptor = sessionFactory().getMetamodel().entityPersister( SupplementalInfo.class );
|
||||||
final BytecodeEnhancementMetadata supplementalInfoEnhancementMetadata = supplementalInfoDescriptor.getBytecodeEnhancementMetadata();
|
final BytecodeEnhancementMetadata supplementalInfoEnhancementMetadata = supplementalInfoDescriptor.getBytecodeEnhancementMetadata();
|
||||||
assertThat( supplementalInfoEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
assertThat( supplementalInfoEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
||||||
|
@ -114,6 +115,27 @@ public class OneToOneAllowProxyTests extends BaseNonConfigCoreFunctionalTestCase
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14659")
|
||||||
|
public void testQueryJoinFetch() {
|
||||||
|
SupplementalInfo info = fromTransaction( (session) -> {
|
||||||
|
final SupplementalInfo result = session.createQuery(
|
||||||
|
"select s from SupplementalInfo s join fetch s.customer",
|
||||||
|
SupplementalInfo.class )
|
||||||
|
.uniqueResult();
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
return result;
|
||||||
|
} );
|
||||||
|
|
||||||
|
// The "join fetch" should have already initialized the property,
|
||||||
|
// so that the getter can safely be called outside of a session.
|
||||||
|
assertTrue( Hibernate.isPropertyInitialized( info, "customer" ) );
|
||||||
|
// The "join fetch" should have already initialized the associated entity.
|
||||||
|
Customer customer = info.getCustomer();
|
||||||
|
assertTrue( Hibernate.isInitialized( customer ) );
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void createTestData() {
|
public void createTestData() {
|
||||||
inTransaction(
|
inTransaction(
|
||||||
|
@ -124,6 +146,7 @@ public class OneToOneAllowProxyTests extends BaseNonConfigCoreFunctionalTestCase
|
||||||
session.persist( supplementalInfo );
|
session.persist( supplementalInfo );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
sqlStatementInterceptor.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|
|
@ -11,6 +11,7 @@ import javax.persistence.Id;
|
||||||
import javax.persistence.OneToOne;
|
import javax.persistence.OneToOne;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
import org.hibernate.annotations.LazyToOne;
|
import org.hibernate.annotations.LazyToOne;
|
||||||
import org.hibernate.boot.MetadataSources;
|
import org.hibernate.boot.MetadataSources;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
@ -21,6 +22,7 @@ import org.hibernate.bytecode.spi.BytecodeEnhancementMetadata;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||||
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
|
@ -37,6 +39,7 @@ import static org.hamcrest.CoreMatchers.not;
|
||||||
import static org.hamcrest.CoreMatchers.sameInstance;
|
import static org.hamcrest.CoreMatchers.sameInstance;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hibernate.annotations.LazyToOneOption.NO_PROXY;
|
import static org.hibernate.annotations.LazyToOneOption.NO_PROXY;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Baseline test for uni-directional one-to-one, using an explicit @LazyToOne(NO_PROXY) and allowing enhanced proxies
|
* Baseline test for uni-directional one-to-one, using an explicit @LazyToOne(NO_PROXY) and allowing enhanced proxies
|
||||||
|
@ -62,8 +65,6 @@ public class OneToOneExplicitOptionTests extends BaseNonConfigCoreFunctionalTest
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOwnerIsProxy() {
|
public void testOwnerIsProxy() {
|
||||||
sqlStatementInterceptor.clear();
|
|
||||||
|
|
||||||
final EntityPersister supplementalInfoDescriptor = sessionFactory().getMetamodel().entityPersister( SupplementalInfo.class );
|
final EntityPersister supplementalInfoDescriptor = sessionFactory().getMetamodel().entityPersister( SupplementalInfo.class );
|
||||||
final BytecodeEnhancementMetadata supplementalInfoEnhancementMetadata = supplementalInfoDescriptor.getBytecodeEnhancementMetadata();
|
final BytecodeEnhancementMetadata supplementalInfoEnhancementMetadata = supplementalInfoDescriptor.getBytecodeEnhancementMetadata();
|
||||||
assertThat( supplementalInfoEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
assertThat( supplementalInfoEnhancementMetadata.isEnhancedForLazyLoading(), is( true ) );
|
||||||
|
@ -116,6 +117,27 @@ public class OneToOneExplicitOptionTests extends BaseNonConfigCoreFunctionalTest
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14659")
|
||||||
|
public void testQueryJoinFetch() {
|
||||||
|
SupplementalInfo info = fromTransaction( (session) -> {
|
||||||
|
final SupplementalInfo result = session.createQuery(
|
||||||
|
"select s from SupplementalInfo s join fetch s.customer",
|
||||||
|
SupplementalInfo.class )
|
||||||
|
.uniqueResult();
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
return result;
|
||||||
|
} );
|
||||||
|
|
||||||
|
// The "join fetch" should have already initialized the property,
|
||||||
|
// so that the getter can safely be called outside of a session.
|
||||||
|
assertTrue( Hibernate.isPropertyInitialized( info, "customer" ) );
|
||||||
|
// The "join fetch" should have already initialized the associated entity.
|
||||||
|
Customer customer = info.getCustomer();
|
||||||
|
assertTrue( Hibernate.isInitialized( customer ) );
|
||||||
|
assertThat( sqlStatementInterceptor.getSqlQueries().size(), is( 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void createTestData() {
|
public void createTestData() {
|
||||||
inTransaction(
|
inTransaction(
|
||||||
|
@ -126,6 +148,7 @@ public class OneToOneExplicitOptionTests extends BaseNonConfigCoreFunctionalTest
|
||||||
session.persist( supplementalInfo );
|
session.persist( supplementalInfo );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
sqlStatementInterceptor.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.boot.MetadataSources;
|
||||||
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||||
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
|
@ -72,6 +73,21 @@ public class JoinFetchedPolymorphicToOneTests extends BaseNonConfigCoreFunctiona
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14659")
|
||||||
|
public void testQueryJoinFetch() {
|
||||||
|
inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
final Order order = session.createQuery( "select o from Order o join fetch o.customer", Order.class )
|
||||||
|
.uniqueResult();
|
||||||
|
|
||||||
|
assertTrue( Hibernate.isPropertyInitialized( order, "customer" ) );
|
||||||
|
Customer customer = order.getCustomer();
|
||||||
|
assertTrue( Hibernate.isInitialized( customer ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void createTestData() {
|
public void createTestData() {
|
||||||
inTransaction(
|
inTransaction(
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||||
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
|
@ -36,6 +37,7 @@ import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -100,6 +102,21 @@ public class PolymorphicToOneExplicitOptionTests extends BaseNonConfigCoreFuncti
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14659")
|
||||||
|
public void testQueryJoinFetch() {
|
||||||
|
inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
final Order order = session.createQuery( "select o from Order o join fetch o.customer", Order.class )
|
||||||
|
.uniqueResult();
|
||||||
|
|
||||||
|
assertTrue( Hibernate.isPropertyInitialized( order, "customer" ) );
|
||||||
|
Customer customer = order.getCustomer();
|
||||||
|
assertTrue( Hibernate.isInitialized( customer ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void createTestData() {
|
public void createTestData() {
|
||||||
inTransaction(
|
inTransaction(
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
import org.hibernate.testing.bytecode.enhancement.BytecodeEnhancerRunner;
|
||||||
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
import org.hibernate.testing.bytecode.enhancement.EnhancementOptions;
|
||||||
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
import org.hibernate.testing.jdbc.SQLStatementInterceptor;
|
||||||
|
@ -34,6 +35,7 @@ import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
@ -72,6 +74,21 @@ public class PolymorphicToOneImplicitOptionTests extends BaseNonConfigCoreFuncti
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-14659")
|
||||||
|
public void testQueryJoinFetch() {
|
||||||
|
inTransaction(
|
||||||
|
(session) -> {
|
||||||
|
final Order order = session.createQuery( "select o from Order o join fetch o.customer", Order.class )
|
||||||
|
.uniqueResult();
|
||||||
|
|
||||||
|
assertTrue( Hibernate.isPropertyInitialized( order, "customer" ) );
|
||||||
|
Customer customer = order.getCustomer();
|
||||||
|
assertTrue( Hibernate.isInitialized( customer ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void createTestData() {
|
public void createTestData() {
|
||||||
inTransaction(
|
inTransaction(
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
/*
|
||||||
|
* 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.graalvm.internal;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Executable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import org.hibernate.internal.build.AllowSysOut;
|
||||||
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
|
|
||||||
|
import com.oracle.svm.core.annotate.AutomaticFeature;
|
||||||
|
import org.graalvm.nativeimage.hosted.Feature;
|
||||||
|
import org.graalvm.nativeimage.hosted.RuntimeReflection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This registers all ANTLR parser nodes for reflection, something that is necessary
|
||||||
|
* as the HQL parser's inner workings are based on reflection.
|
||||||
|
* This is different than the "static" registrations of {@link GraalVMStaticAutofeature}
|
||||||
|
* as we only register these if the HQL parser is actually reachable: some particularly
|
||||||
|
* simple applications might not need dynamic queries being expressed in string form,
|
||||||
|
* and for such cases the reflective registrations can be skipped.
|
||||||
|
*
|
||||||
|
* At time of writing, this is particularly unlikely to be effective as Hibernate ORM
|
||||||
|
* requires the parsers during bootstrap, but there is reasonable hope that this might
|
||||||
|
* be improved on, and can already be used by framework integrations which are able
|
||||||
|
* to bypass the traditional boot sequence.
|
||||||
|
*
|
||||||
|
* @author Sanne Grinovero
|
||||||
|
*/
|
||||||
|
@AutomaticFeature
|
||||||
|
public final class QueryParsingSupport implements Feature {
|
||||||
|
|
||||||
|
private final AtomicBoolean triggered = new AtomicBoolean( false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To set this, add `-J-Dorg.hibernate.graalvm.diagnostics=true` to the native-image parameters
|
||||||
|
*/
|
||||||
|
private static final boolean log = Boolean.getBoolean( "org.hibernate.graalvm.diagnostics" );
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeAnalysis(BeforeAnalysisAccess access) {
|
||||||
|
Class<?> lexerClazz = access.findClassByName("org.hibernate.grammars.hql.HqlLexer");
|
||||||
|
Class<?> parserClazz = access.findClassByName("org.hibernate.grammars.hql.HqlParser");
|
||||||
|
access.registerReachabilityHandler(this::enableHQLSupport, lexerClazz);
|
||||||
|
access.registerReachabilityHandler(this::enableHQLSupport, parserClazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllowSysOut
|
||||||
|
private void enableHQLSupport(DuringAnalysisAccess duringAnalysisAccess) {
|
||||||
|
final boolean needsEnablingYet = triggered.compareAndSet( false, true );
|
||||||
|
if ( needsEnablingYet ) {
|
||||||
|
if ( log ) {
|
||||||
|
System.out.println( "Hibernate ORM 's automatic feature for GraalVM native images: enabling support for HQL query parsing" );
|
||||||
|
}
|
||||||
|
enableAntlrParsersSupport();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enableAntlrParsersSupport() {
|
||||||
|
final Class<?>[] needsHavingSimpleConstructors = typesNeedingDefaultConstructorAccessible();
|
||||||
|
final Class[] neddingAllConstructorsAccessible = typesNeedingAllConstructorsAccessible();
|
||||||
|
//Size formula is just a reasonable guess:
|
||||||
|
ArrayList<Executable> executables = new ArrayList<>( needsHavingSimpleConstructors.length + neddingAllConstructorsAccessible.length * 3 );
|
||||||
|
for ( Class c : needsHavingSimpleConstructors ) {
|
||||||
|
executables.add( ReflectHelper.getDefaultConstructor( c ) );
|
||||||
|
}
|
||||||
|
for ( Class c : neddingAllConstructorsAccessible ) {
|
||||||
|
for ( Constructor declaredConstructor : c.getDeclaredConstructors() ) {
|
||||||
|
executables.add( declaredConstructor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RuntimeReflection.register( needsHavingSimpleConstructors );
|
||||||
|
RuntimeReflection.register( neddingAllConstructorsAccessible );
|
||||||
|
RuntimeReflection.register( executables.toArray(new Executable[0]) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class[] typesNeedingAllConstructorsAccessible() {
|
||||||
|
return new Class[] {
|
||||||
|
//ANTLR special ones:
|
||||||
|
// org.hibernate.hql.internal.ast.tree.EntityJoinFromElement.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.MapKeyEntityFromElement.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.ComponentJoin.class,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class[] typesNeedingDefaultConstructorAccessible() {
|
||||||
|
return new Class[] {
|
||||||
|
//Support for @OrderBy
|
||||||
|
// org.hibernate.sql.ordering.antlr.NodeSupport.class,
|
||||||
|
// org.hibernate.sql.ordering.antlr.OrderByFragment.class,
|
||||||
|
// org.hibernate.sql.ordering.antlr.SortSpecification.class,
|
||||||
|
// org.hibernate.sql.ordering.antlr.OrderingSpecification.class,
|
||||||
|
// org.hibernate.sql.ordering.antlr.CollationSpecification.class,
|
||||||
|
// org.hibernate.sql.ordering.antlr.SortKey.class,
|
||||||
|
|
||||||
|
//ANTLR tokens:
|
||||||
|
// antlr.CommonToken.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.SelectClause.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.HqlSqlWalkerNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.MethodNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.UnaryLogicOperatorNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.NullNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.IntoClause.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.UpdateStatement.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.SelectExpressionImpl.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.CastFunctionNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.DeleteStatement.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.SqlNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.SearchedCaseNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.FromElement.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.JavaConstantNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.SqlFragment.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.MapKeyNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.ImpliedFromElement.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.IsNotNullLogicOperatorNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.InsertStatement.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.UnaryArithmeticNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.CollectionFunction.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.BinaryLogicOperatorNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.CountNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.IsNullLogicOperatorNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.IdentNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.ParameterNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.MapEntryNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.MapValueNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.InLogicOperatorNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.IndexNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.DotNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.ResultVariableRefNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.BetweenOperatorNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.AggregateNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.QueryNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.BooleanLiteralNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.SimpleCaseNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.OrderByClause.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.FromClause.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.ConstructorNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.LiteralNode.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.BinaryArithmeticOperatorNode.class,
|
||||||
|
|
||||||
|
//Special tokens:
|
||||||
|
// org.hibernate.hql.internal.ast.HqlToken.class,
|
||||||
|
// org.hibernate.hql.internal.ast.tree.Node.class,
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -31,78 +31,18 @@ final class StaticClassLists {
|
||||||
org.hibernate.persister.entity.UnionSubclassEntityPersister.class,
|
org.hibernate.persister.entity.UnionSubclassEntityPersister.class,
|
||||||
org.hibernate.persister.entity.SingleTableEntityPersister.class,
|
org.hibernate.persister.entity.SingleTableEntityPersister.class,
|
||||||
org.hibernate.tuple.entity.PojoEntityTuplizer.class,
|
org.hibernate.tuple.entity.PojoEntityTuplizer.class,
|
||||||
//ANTLR special ones:
|
|
||||||
// org.hibernate.hql.internal.ast.tree.EntityJoinFromElement.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.MapKeyEntityFromElement.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.ComponentJoin.class,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Class[] typesNeedingDefaultConstructorAccessible() {
|
public static Class[] typesNeedingDefaultConstructorAccessible() {
|
||||||
return new Class[] {
|
return new Class[] {
|
||||||
//Support for @OrderBy
|
|
||||||
// org.hibernate.sql.ordering.antlr.NodeSupport.class,
|
|
||||||
// org.hibernate.sql.ordering.antlr.OrderByFragment.class,
|
|
||||||
// org.hibernate.sql.ordering.antlr.SortSpecification.class,
|
|
||||||
// org.hibernate.sql.ordering.antlr.OrderingSpecification.class,
|
|
||||||
// org.hibernate.sql.ordering.antlr.CollationSpecification.class,
|
|
||||||
// org.hibernate.sql.ordering.antlr.SortKey.class,
|
|
||||||
|
|
||||||
//ANTLR tokens:
|
|
||||||
// antlr.CommonToken.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.SelectClause.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.HqlSqlWalkerNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.MethodNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.UnaryLogicOperatorNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.NullNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.IntoClause.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.UpdateStatement.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.SelectExpressionImpl.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.CastFunctionNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.DeleteStatement.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.SqlNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.SearchedCaseNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.FromElement.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.JavaConstantNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.SqlFragment.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.MapKeyNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.ImpliedFromElement.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.IsNotNullLogicOperatorNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.InsertStatement.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.UnaryArithmeticNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.CollectionFunction.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.BinaryLogicOperatorNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.CountNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.IsNullLogicOperatorNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.IdentNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.ParameterNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.MapEntryNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.MapValueNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.InLogicOperatorNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.IndexNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.DotNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.ResultVariableRefNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.BetweenOperatorNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.AggregateNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.QueryNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.BooleanLiteralNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.SimpleCaseNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.OrderByClause.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.FromClause.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.ConstructorNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.LiteralNode.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.BinaryArithmeticOperatorNode.class,
|
|
||||||
|
|
||||||
//Various well known needs:
|
//Various well known needs:
|
||||||
|
|
||||||
org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorBuilderImpl.class,
|
org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorBuilderImpl.class,
|
||||||
org.hibernate.id.enhanced.SequenceStyleGenerator.class,
|
org.hibernate.id.enhanced.SequenceStyleGenerator.class,
|
||||||
org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl.class,
|
org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl.class,
|
||||||
org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorBuilderImpl.class,
|
org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorBuilderImpl.class,
|
||||||
EnumType.class,
|
EnumType.class,
|
||||||
MultipleLinesSqlCommandExtractor.class,
|
MultipleLinesSqlCommandExtractor.class,
|
||||||
// org.hibernate.hql.internal.ast.HqlToken.class,
|
|
||||||
// org.hibernate.hql.internal.ast.tree.Node.class,
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue