Query hints

+ dropped `AbstractProducedQuery` (no subclasses)
This commit is contained in:
Steve Ebersole 2021-08-23 13:40:03 -05:00
parent 397ca4e4a0
commit 0c674deda5
39 changed files with 387 additions and 1637 deletions

View File

@ -191,6 +191,7 @@ ext {
jakarta_weld: "org.jboss.weld.se:weld-se-shaded:${jakartaWeldVersion}",
assertj: "org.assertj:assertj-core:${assertjVersion}",
assertj_api: "org.assertj:assertj-core-api:${assertjVersion}",
// Shrinkwrap
shrinkwrap_api: "org.jboss.shrinkwrap:shrinkwrap-api:${shrinkwrapVersion}",

View File

@ -6,9 +6,18 @@
*/
package org.hibernate.engine.spi;
import org.hibernate.query.spi.QueryOptions;
/**
* Encapsulates details related to the creation and execution of
* a JDBC statement
*
* Differs from {@link QueryOptions} in that this contract describes options
*
* Represents a selection criteria for rows in a JDBC {@link java.sql.ResultSet}
*
*
*
* @author Gavin King
* @deprecated todo (6.0): remove in favor of Limit within QueryOptions?
*/

View File

@ -855,7 +855,7 @@ public class ProcedureCallImpl<R>
return this;
}
// todo (5.3) : all of the parameter stuff here can be done in AbstractProducedQuery
// todo (5.3) : all of the parameter stuff here can be done in AbstractQuery
// using #getParameterMetadata and #getQueryParameterBindings for abstraction.
// this "win" is to define these in one place

View File

@ -525,8 +525,9 @@ public class QuerySqmImpl<R>
@Override
protected List<R> doList() {
SqmUtil.verifyIsSelectStatement( getSqmStatement() );
getSession().prepareForQueryExecution( requiresTxn( getLockOptions().findGreatestLockMode() ) );
final SqmSelectStatement<?> selectStatement = (SqmSelectStatement<?>) getSqmStatement();
getSession().prepareForQueryExecution( requiresTxn( getLockOptions().findGreatestLockMode() ) );
final boolean containsCollectionFetches = selectStatement.containsCollectionFetches();
final boolean hasLimit = queryOptions.hasLimit();
final boolean needsDistincting = containsCollectionFetches && (
@ -535,7 +536,7 @@ public class QuerySqmImpl<R>
hasLimit
);
final ExecutionContext executionContextToUse;
if ( queryOptions.hasLimit() && containsCollectionFetches ) {
if ( hasLimit && containsCollectionFetches ) {
boolean fail = getSessionFactory().getSessionFactoryOptions().isFailOnPaginationOverCollectionFetchEnabled();
if (fail) {
throw new HibernateException(

View File

@ -0,0 +1,61 @@
/*
* 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.sql.exec.spi;
/**
* Options for the creation of a JDBC statement
*
* @author Steve Ebersole
*/
public class StatementOptions {
public static final StatementOptions NONE = new StatementOptions( -1, -1, -1, -1 );
private final Integer firstRow;
private final Integer maxRows;
private final Integer timeoutInMilliseconds;
private final Integer fetchSize;
public StatementOptions(
Integer firstRow,
Integer maxRows,
Integer timeoutInMilliseconds,
Integer fetchSize) {
this.firstRow = firstRow;
this.maxRows = maxRows;
this.timeoutInMilliseconds = timeoutInMilliseconds;
this.fetchSize = fetchSize;
}
public boolean hasLimit() {
return ( firstRow != null && firstRow > 0 )
|| ( maxRows != null && maxRows > 0 );
}
public Integer getFirstRow() {
return firstRow;
}
public Integer getMaxRows() {
return maxRows;
}
public boolean hasTimeout() {
return timeoutInMilliseconds != null && timeoutInMilliseconds > 0;
}
public Integer getTimeoutInMilliseconds() {
return timeoutInMilliseconds;
}
public boolean hasFetchSize() {
return fetchSize != null && fetchSize > 0;
}
public Integer getFetchSize() {
return fetchSize;
}
}

View File

@ -15,6 +15,7 @@ import org.hibernate.query.spi.QueryOptions;
import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.sql.exec.spi.Callback;
import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.exec.spi.StatementOptions;
import org.hibernate.sql.results.graph.Initializer;
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
import org.hibernate.sql.results.graph.entity.EntityFetch;

View File

@ -7,7 +7,7 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.junit.BaseSessionFactoryFunctionalTest;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;

View File

@ -21,7 +21,7 @@ import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
import org.hibernate.testing.boot.BasicTestingJdbcServiceImpl;
import org.hibernate.testing.orm.junit.BaseSessionFactoryFunctionalTest;
import org.hibernate.testing.orm.junit.RequiresDialect;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

View File

@ -20,7 +20,7 @@ import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

View File

@ -17,7 +17,7 @@ import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
import org.hibernate.testing.orm.junit.Jpa;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.Setting;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

View File

@ -16,7 +16,7 @@ import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
import org.hibernate.testing.orm.junit.Jpa;
import org.hibernate.testing.orm.junit.Setting;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

View File

@ -7,7 +7,7 @@
package org.hibernate.orm.test.jpa.ejb3configuration;
import org.hibernate.testing.orm.jpa.NonStringValueSettingProvider;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
/**
* @author Jan Schatteman

View File

@ -14,7 +14,7 @@ import javax.persistence.LockModeType;
import org.hibernate.Session;
import org.hibernate.dialect.CockroachDialect;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.SkipForDialect;

View File

@ -0,0 +1,90 @@
/*
* 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.orm.test.query;
import java.time.LocalDate;
import org.hibernate.query.IllegalQueryOperationException;
import org.hibernate.testing.orm.domain.StandardDomainModel;
import org.hibernate.testing.orm.domain.contacts.Contact;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Steve Ebersole
*/
@DomainModel( standardModels = StandardDomainModel.CONTACTS )
@SessionFactory
public class QueryApiTests {
@Test
public void testInvalidExecuteUpdateCall(SessionFactoryScope scope) {
try {
scope.inTransaction( (session) -> {
session.createQuery( "select c from Contact c" ).executeUpdate();
} );
fail( "Expecting failure" );
}
catch (IllegalStateException ise) {
assertThat( ise.getCause() ).isNotNull();
assertThat( ise.getCause() ).isInstanceOf( IllegalQueryOperationException.class );
}
}
@Test
public void testInvalidSelectQueryCall(SessionFactoryScope scope) {
try {
scope.inTransaction( (session) -> {
session.createQuery( "delete Contact" ).list();
} );
fail( "Expecting failure" );
}
catch (IllegalStateException ise) {
assertThat( ise.getCause() ).isNotNull();
assertThat( ise.getCause() ).isInstanceOf( IllegalQueryOperationException.class );
}
try {
scope.inTransaction( (session) -> {
session.createQuery( "delete Contact" ).uniqueResult();
} );
fail( "Expecting failure" );
}
catch (IllegalStateException ise) {
assertThat( ise.getCause() ).isNotNull();
assertThat( ise.getCause() ).isInstanceOf( IllegalQueryOperationException.class );
}
}
@BeforeEach
public void prepareTestData(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
final Contact contact = new Contact(
1,
new Contact.Name( "John", "Jingleheimer-Schmidt"),
Contact.Gender.MALE,
LocalDate.EPOCH
);
session.persist( contact );
} );
}
@AfterEach
public void dropTestData(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
session.createQuery( "delete Contact" ).executeUpdate();
} );
}
}

View File

@ -0,0 +1,91 @@
/*
* 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.orm.test.query;
import java.time.LocalDate;
import java.util.Collections;
import org.hibernate.graph.GraphParser;
import org.hibernate.jpa.QueryHints;
import org.hibernate.query.IllegalQueryOperationException;
import org.hibernate.testing.orm.assertj.HibernateInitializedCondition;
import org.hibernate.testing.orm.domain.StandardDomainModel;
import org.hibernate.testing.orm.domain.contacts.Contact;
import org.hibernate.testing.orm.domain.contacts.PhoneNumber;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Steve Ebersole
*/
@DomainModel( standardModels = StandardDomainModel.CONTACTS )
@SessionFactory
public class QueryHintTest {
@Test
public void testFetchGraphHint(SessionFactoryScope scope) {
final Contact queried = scope.fromTransaction( (session) -> {
return session.createQuery( "from Contact", Contact.class )
.setHint( QueryHints.HINT_FETCHGRAPH, GraphParser.parse( Contact.class, "phoneNumbers", session ) )
.uniqueResult();
} );
assertThat( queried ).is( HibernateInitializedCondition.IS_INITIALIZED );
assertThat( queried.getPhoneNumbers() ).is( HibernateInitializedCondition.IS_INITIALIZED );
}
@Test
public void testLoadGraphHint(SessionFactoryScope scope) {
final Contact queried = scope.fromTransaction( (session) -> {
return session.createQuery( "from Contact", Contact.class )
.setHint( QueryHints.HINT_LOADGRAPH, GraphParser.parse( Contact.class, "phoneNumbers", session ) )
.uniqueResult();
} );
assertThat( queried ).is( HibernateInitializedCondition.IS_INITIALIZED );
assertThat( queried.getPhoneNumbers() ).is( HibernateInitializedCondition.IS_INITIALIZED );
}
@Test
public void testQueryTimeoutHint(SessionFactoryScope scope) {
// see `org.hibernate.test.querytimeout.QueryTimeOutTest`
}
@BeforeEach
public void prepareTestData(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
final Contact contact = new Contact(
1,
new Contact.Name( "John", "Jingleheimer-Schmidt"),
Contact.Gender.MALE,
LocalDate.EPOCH
);
contact.setPhoneNumbers(
Collections.singletonList(
new PhoneNumber( 123, 456, 7890, PhoneNumber.Classification.OTHER )
)
);
session.persist( contact );
} );
}
@AfterEach
public void dropTestData(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
session.createQuery( "from Contact" ).list().forEach( session::delete );
} );
}
}

View File

@ -1,10 +1,10 @@
/*
* 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>.
* 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.test.querytimeout;
package org.hibernate.orm.test.query;
import java.sql.SQLException;
import java.util.Map;
@ -23,7 +23,7 @@ import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Before;
import org.junit.Test;

View File

@ -19,7 +19,7 @@ import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;

View File

@ -30,7 +30,7 @@ import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

View File

@ -37,7 +37,7 @@ import static org.junit.Assert.assertTrue;
* @author Brett Meyer
*/
@RequiresDialect( Oracle8iDialect.class )
public class QueryHintTest extends BaseNonConfigCoreFunctionalTestCase {
public class OracleQueryHintTest extends BaseNonConfigCoreFunctionalTestCase {
private SQLStatementInterceptor sqlStatementInterceptor;

View File

@ -28,7 +28,7 @@ import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

View File

@ -20,7 +20,7 @@ import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;

View File

@ -25,7 +25,7 @@ import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

View File

@ -25,7 +25,7 @@ import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

View File

@ -19,7 +19,7 @@ import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.orm.test.util.jdbc.PreparedStatementSpyConnectionProvider;
import org.hibernate.testing.orm.jdbc.PreparedStatementSpyConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;

View File

@ -14,7 +14,7 @@ import org.hibernate.dialect.PostgreSQL82Dialect;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.orm.test.util.jdbc.TimeZoneConnectionProvider;
import org.hibernate.testing.orm.jdbc.TimeZoneConnectionProvider;
/**
* @author Vlad Mihalcea

View File

@ -13,7 +13,7 @@ import org.hibernate.dialect.PostgreSQL82Dialect;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.orm.test.util.jdbc.TimeZoneConnectionProvider;
import org.hibernate.testing.orm.jdbc.TimeZoneConnectionProvider;
/**
* @author Vlad Mihalcea

View File

@ -23,7 +23,7 @@ import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.hibernate.orm.test.util.jdbc.TimeZoneConnectionProvider;
import org.hibernate.testing.orm.jdbc.TimeZoneConnectionProvider;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;

View File

@ -20,6 +20,9 @@ dependencies {
api libraries.junit5_api
api libraries.junit5_params
api 'org.hamcrest:hamcrest-all:1.3'
api libraries.assertj
api libraries.mockito
api libraries.mockito_inline
api libraries.byteman
api libraries.byteman_install
api libraries.byteman_bmunit

View File

@ -336,6 +336,14 @@ public class JdbcMocks {
return false;
}
public static class PreparedStatementHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
}
public static class EmptyResultSetHandler implements InvocationHandler {
public static ResultSet makeProxy() {
final EmptyResultSetHandler handler = new EmptyResultSetHandler();

View File

@ -0,0 +1,31 @@
/*
* 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.testing.orm.assertj;
import org.hibernate.Hibernate;
import org.assertj.core.api.Condition;
/**
* @author Steve Ebersole
*/
public class HibernateInitializedCondition extends Condition<Object> {
public static final HibernateInitializedCondition IS_INITIALIZED = new HibernateInitializedCondition( true );
public static final HibernateInitializedCondition IS_NOT_INITIALIZED = new HibernateInitializedCondition( false );
private final boolean positive;
public HibernateInitializedCondition(boolean positive) {
super( "Hibernate#isInitialized check" );
this.positive = positive;
}
@Override
public boolean matches(Object value) {
return positive == Hibernate.isInitialized( value );
}
}

View File

@ -33,9 +33,6 @@ public class Contact {
private LocalDate birthDay;
// NOTE : because of the @OrderColumn `addresses` is a List, while `phoneNumbers` is a BAG
// which is a List with no persisted order
@OrderColumn
private List<Address> addresses;
private List<PhoneNumber> phoneNumbers;
@ -86,6 +83,9 @@ public class Contact {
@ElementCollection
@CollectionTable( name = "contact_addresses" )
// NOTE : because of the @OrderColumn `addresses` is a List, while `phoneNumbers` is
// a BAG which is a List with no persisted order
@OrderColumn
public List<Address> getAddresses() {
return addresses;
}

View File

@ -19,6 +19,16 @@ public class PhoneNumber {
private Classification classification;
public PhoneNumber() {
}
public PhoneNumber(int areaCode, int prefix, int lineNumber, Classification classification) {
this.areaCode = areaCode;
this.prefix = prefix;
this.lineNumber = lineNumber;
this.classification = classification;
}
public int getAreaCode() {
return areaCode;
}

View File

@ -1,10 +1,10 @@
/*
* 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>.
* 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.orm.test.util.jdbc;
package org.hibernate.testing.orm.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;

View File

@ -0,0 +1,19 @@
/*
* 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.testing.orm.jdbc;
import org.hibernate.testing.orm.junit.SettingProvider;
/**
* @author Steve Ebersole
*/
public class PreparedStatementSpyConnectionProviderSettingProvider implements SettingProvider.Provider<PreparedStatementSpyConnectionProvider> {
@Override
public PreparedStatementSpyConnectionProvider getSetting() {
return new PreparedStatementSpyConnectionProvider( true, false );
}
}

View File

@ -1,10 +1,10 @@
/*
* 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>.
* 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.orm.test.util.jdbc;
package org.hibernate.testing.orm.jdbc;
import java.util.TimeZone;

View File

@ -75,6 +75,8 @@ public @interface ServiceRegistry {
Setting[] settings() default {};
SettingProvider[] settingProviders() default {};
@interface Service {
Class<? extends org.hibernate.service.Service> role();
Class<? extends org.hibernate.service.Service> impl();

View File

@ -182,6 +182,12 @@ public class ServiceRegistryExtension
ssrb.applySetting( setting.name(), setting.value() );
}
for ( SettingProvider providerAnn : serviceRegistryAnn.settingProviders() ) {
final Class<? extends SettingProvider.Provider<?>> providerImpl = providerAnn.provider();
final SettingProvider.Provider<?> provider = providerImpl.getConstructor().newInstance();
ssrb.applySetting( providerAnn.settingName(), provider.getSetting() );
}
for ( Class<? extends ServiceContributor> contributorClass : serviceRegistryAnn.serviceContributors() ) {
final ServiceContributor serviceContributor = contributorClass.newInstance();
serviceContributor.contribute( ssrb );

View File

@ -0,0 +1,19 @@
/*
* 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.testing.orm.junit;
/**
* @author Steve Ebersole
*/
public @interface SettingProvider {
interface Provider<S> {
S getSetting();
}
String settingName();
Class<? extends Provider<?>> provider();
}