diff --git a/hibernate-core/src/main/java/org/hibernate/Query.java b/hibernate-core/src/main/java/org/hibernate/Query.java index a30518f5e8..53eec109d7 100644 --- a/hibernate-core/src/main/java/org/hibernate/Query.java +++ b/hibernate-core/src/main/java/org/hibernate/Query.java @@ -750,7 +750,7 @@ public interface Query extends org.hibernate.BasicQueryContract, TypedQuery extends org.hibernate.BasicQueryContract, TypedQuery extends org.hibernate.BasicQueryContract, TypedQuery extends org.hibernate.BasicQueryContract, TypedQuery extends org.hibernate.BasicQueryContract, TypedQuery { * * @return {@code this}, for method chaining * - * @deprecated (since 6.0) use {@link #connectionHandlingMode} instead + * @deprecated (since 5.2) use {@link #connectionHandlingMode} instead */ @Deprecated T connectionReleaseMode(ConnectionReleaseMode connectionReleaseMode); diff --git a/hibernate-core/src/main/java/org/hibernate/SharedSessionContract.java b/hibernate-core/src/main/java/org/hibernate/SharedSessionContract.java index fb0c1d7714..5668a709ac 100644 --- a/hibernate-core/src/main/java/org/hibernate/SharedSessionContract.java +++ b/hibernate-core/src/main/java/org/hibernate/SharedSessionContract.java @@ -115,7 +115,7 @@ public interface SharedSessionContract extends QueryProducer, Serializable { * * @return The criteria instance for manipulation and execution * - * @deprecated (since 6.0) for Session, use the JPA Criteria + * @deprecated (since 5.2) for Session, use the JPA Criteria */ @Deprecated Criteria createCriteria(Class persistentClass); @@ -129,7 +129,7 @@ public interface SharedSessionContract extends QueryProducer, Serializable { * * @return The criteria instance for manipulation and execution * - * @deprecated (since 6.0) for Session, use the JPA Criteria + * @deprecated (since 5.2) for Session, use the JPA Criteria */ @Deprecated Criteria createCriteria(Class persistentClass, String alias); @@ -141,7 +141,7 @@ public interface SharedSessionContract extends QueryProducer, Serializable { * @return The criteria instance for manipulation and execution * - * @deprecated (since 6.0) for Session, use the JPA Criteria + * @deprecated (since 5.2) for Session, use the JPA Criteria */ @Deprecated Criteria createCriteria(String entityName); @@ -154,7 +154,7 @@ public interface SharedSessionContract extends QueryProducer, Serializable { * * @return The criteria instance for manipulation and execution * - * @deprecated (since 6.0) for Session, use the JPA Criteria + * @deprecated (since 5.2) for Session, use the JPA Criteria */ @Deprecated Criteria createCriteria(String entityName, String alias); diff --git a/hibernate-core/src/main/java/org/hibernate/action/internal/BulkOperationCleanupAction.java b/hibernate-core/src/main/java/org/hibernate/action/internal/BulkOperationCleanupAction.java index 462aaf226a..103137a70e 100644 --- a/hibernate-core/src/main/java/org/hibernate/action/internal/BulkOperationCleanupAction.java +++ b/hibernate-core/src/main/java/org/hibernate/action/internal/BulkOperationCleanupAction.java @@ -57,7 +57,7 @@ public class BulkOperationCleanupAction implements Executable, Serializable { */ public BulkOperationCleanupAction(SharedSessionContractImplementor session, Queryable... affectedQueryables) { final SessionFactoryImplementor factory = session.getFactory(); - final LinkedHashSet spacesList = new LinkedHashSet(); + final LinkedHashSet spacesList = new LinkedHashSet<>(); for ( Queryable persister : affectedQueryables ) { spacesList.addAll( Arrays.asList( (String[]) persister.getQuerySpaces() ) ); @@ -68,10 +68,10 @@ public class BulkOperationCleanupAction implements Executable, Serializable { naturalIdCleanups.add( new NaturalIdCleanup( persister.getNaturalIdCacheAccessStrategy() ) ); } - final Set roles = factory.getCollectionRolesByEntityParticipant( persister.getEntityName() ); + final Set roles = factory.getMetamodel().getCollectionRolesByEntityParticipant( persister.getEntityName() ); if ( roles != null ) { for ( String role : roles ) { - final CollectionPersister collectionPersister = factory.getCollectionPersister( role ); + final CollectionPersister collectionPersister = factory.getMetamodel().collectionPersister( role ); if ( collectionPersister.hasCache() ) { collectionCleanups.add( new CollectionCleanup( collectionPersister.getCacheAccessStrategy() ) ); } @@ -96,12 +96,11 @@ public class BulkOperationCleanupAction implements Executable, Serializable { */ @SuppressWarnings({ "unchecked" }) public BulkOperationCleanupAction(SharedSessionContractImplementor session, Set tableSpaces) { - final LinkedHashSet spacesList = new LinkedHashSet(); + final LinkedHashSet spacesList = new LinkedHashSet<>(); spacesList.addAll( tableSpaces ); final SessionFactoryImplementor factory = session.getFactory(); - for ( String entityName : factory.getAllClassMetadata().keySet() ) { - final EntityPersister persister = factory.getEntityPersister( entityName ); + for ( EntityPersister persister : factory.getMetamodel().entityPersisters().values() ) { final String[] entitySpaces = (String[]) persister.getQuerySpaces(); if ( affectedEntity( tableSpaces, entitySpaces ) ) { spacesList.addAll( Arrays.asList( entitySpaces ) ); @@ -113,10 +112,10 @@ public class BulkOperationCleanupAction implements Executable, Serializable { naturalIdCleanups.add( new NaturalIdCleanup( persister.getNaturalIdCacheAccessStrategy() ) ); } - final Set roles = session.getFactory().getCollectionRolesByEntityParticipant( persister.getEntityName() ); + final Set roles = session.getFactory().getMetamodel().getCollectionRolesByEntityParticipant( persister.getEntityName() ); if ( roles != null ) { for ( String role : roles ) { - final CollectionPersister collectionPersister = factory.getCollectionPersister( role ); + final CollectionPersister collectionPersister = factory.getMetamodel().collectionPersister( role ); if ( collectionPersister.hasCache() ) { collectionCleanups.add( new CollectionCleanup( collectionPersister.getCacheAccessStrategy() ) diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java index 58462b0540..4864fd2744 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryBuilderImpl.java @@ -598,7 +598,10 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement ); final Object statelessInterceptorSetting = configurationSettings.get( SESSION_SCOPED_INTERCEPTOR ); - if ( statelessInterceptorSetting instanceof Class ) { + if ( statelessInterceptorSetting == null ) { + this.statelessInterceptorClass = null; + } + else if ( statelessInterceptorSetting instanceof Class ) { this.statelessInterceptorClass = (Class) statelessInterceptorSetting; } else { diff --git a/hibernate-core/src/main/java/org/hibernate/cache/spi/RegionFactory.java b/hibernate-core/src/main/java/org/hibernate/cache/spi/RegionFactory.java index 834ba1683f..f9a68f4015 100644 --- a/hibernate-core/src/main/java/org/hibernate/cache/spi/RegionFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/cache/spi/RegionFactory.java @@ -40,7 +40,7 @@ public interface RegionFactory extends Service { * considered as a sign to stop {@link org.hibernate.SessionFactory} * building. * - * @deprecated (since 6.0) use the form accepting map instead. + * @deprecated (since 5.2) use the form accepting map instead. */ @Deprecated void start(SessionFactoryOptions settings, Properties properties) throws CacheException; @@ -108,7 +108,7 @@ public interface RegionFactory extends Service { * * @throws CacheException Indicates problems building the region. * - * @deprecated (since 6.0) use the form taking Map instead + * @deprecated (since 5.2) use the form taking Map instead */ @Deprecated EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) @@ -143,7 +143,7 @@ public interface RegionFactory extends Service { * * @throws CacheException Indicates problems building the region. * - * @deprecated (since 6.0) use the form accepting a Map instead + * @deprecated (since 5.2) use the form accepting a Map instead */ @Deprecated NaturalIdRegion buildNaturalIdRegion(String regionName, Properties properties, CacheDataDescription metadata) @@ -209,7 +209,7 @@ public interface RegionFactory extends Service { * * @throws CacheException Indicates problems building the region. * - * @deprecated (since 6.0) use the form taking Map instead + * @deprecated (since 5.2) use the form taking Map instead */ @Deprecated QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException; @@ -240,7 +240,7 @@ public interface RegionFactory extends Service { * * @throws CacheException Indicates problems building the region. * - * @deprecated (since 6.0) use the form taking Map + * @deprecated (since 5.2) use the form taking Map */ @Deprecated TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/internal/SessionEventListenerManagerImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/internal/SessionEventListenerManagerImpl.java index b1ac69f1e5..a79dac9657 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/internal/SessionEventListenerManagerImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/internal/SessionEventListenerManagerImpl.java @@ -19,9 +19,10 @@ import org.hibernate.engine.spi.SessionEventListenerManager; public class SessionEventListenerManagerImpl implements SessionEventListenerManager, Serializable { private List listenerList; + @Override public void addListener(SessionEventListener... listeners) { if ( listenerList == null ) { - listenerList = new ArrayList(); + listenerList = new ArrayList<>(); } java.util.Collections.addAll( listenerList, listeners ); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java index 14911167c2..5168eb01af 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/query/spi/HQLQueryPlan.java @@ -104,13 +104,12 @@ public class HQLQueryPlan implements Serializable { final List sqlStringList = new ArrayList(); final Set combinedQuerySpaces = new HashSet(); - final boolean hasCollectionRole = (collectionRole == null); final Map querySubstitutions = factory.getSessionFactoryOptions().getQuerySubstitutions(); final QueryTranslatorFactory queryTranslatorFactory = factory.getServiceRegistry().getService( QueryTranslatorFactory.class ); for ( int i=0; i extends Ses * * @return {@code this}, for method chaining * - * @deprecated (since 6.0) since consolidating hibernate-entitymanager into hibernate-core + * @deprecated (since 5.2) since consolidating hibernate-entitymanager into hibernate-core * I believe this is no longer needed. */ @Deprecated diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionEventListenerManager.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionEventListenerManager.java index ee2c65c6e2..79e0f3d733 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionEventListenerManager.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionEventListenerManager.java @@ -12,4 +12,5 @@ import org.hibernate.SessionEventListener; * @author Steve Ebersole */ public interface SessionEventListenerManager extends SessionEventListener { + void addListener(SessionEventListener... listeners); } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java index 50608d3d0a..ba0feab88a 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java @@ -503,4 +503,9 @@ public class SessionFactoryDelegatingImpl implements SessionFactoryImplementor, public boolean isOpen() { return delegate.isOpen(); } + + @Override + public Type resolveParameterBindType(Object bindValue) { + return delegate.resolveParameterBindType( bindValue ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java index 8851d37e3c..e52bc7bc9f 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java @@ -44,6 +44,7 @@ import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.query.spi.NamedQueryRepository; +import org.hibernate.query.spi.QueryParameterBindingTypeResolver; import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.stat.spi.StatisticsImplementor; import org.hibernate.type.Type; @@ -59,7 +60,7 @@ import org.hibernate.type.TypeResolver; * @author Gavin King * @author Steve Ebersole */ -public interface SessionFactoryImplementor extends Mapping, SessionFactory { +public interface SessionFactoryImplementor extends Mapping, SessionFactory, QueryParameterBindingTypeResolver { /** * Get the UUID for this SessionFactory. The value is generated as a {@link java.util.UUID}, but kept * as a String. @@ -103,7 +104,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { * * @return The factory scope interceptor, or null if none. * - * @deprecated (since 6.0) if access to the SessionFactory-scoped Interceptor is needed, use + * @deprecated (since 5.2) if access to the SessionFactory-scoped Interceptor is needed, use * {@link SessionFactoryOptions#getInterceptor()} instead. However, generally speaking this access * is not needed. */ @@ -214,7 +215,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { // NamedQueryRepository /** - * @deprecated (since 6.0) Use {@link NamedQueryRepository#getNamedQueryDefinition(java.lang.String)} instead. + * @deprecated (since 5.2) Use {@link NamedQueryRepository#getNamedQueryDefinition(java.lang.String)} instead. */ @Deprecated default NamedQueryDefinition getNamedQuery(String queryName) { @@ -222,7 +223,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { } /** - * @deprecated (since 6.0) Use {@link NamedQueryRepository#registerNamedQueryDefinition} instead. + * @deprecated (since 5.2) Use {@link NamedQueryRepository#registerNamedQueryDefinition} instead. */ @Deprecated default void registerNamedQueryDefinition(String name, NamedQueryDefinition definition) { @@ -230,7 +231,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { } /** - * @deprecated (since 6.0) Use {@link NamedQueryRepository#getNamedSQLQueryDefinition} instead. + * @deprecated (since 5.2) Use {@link NamedQueryRepository#getNamedSQLQueryDefinition} instead. */ @Deprecated default NamedSQLQueryDefinition getNamedSQLQuery(String queryName) { @@ -238,7 +239,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { } /** - * @deprecated (since 6.0) Use {@link NamedQueryRepository#registerNamedSQLQueryDefinition} instead. + * @deprecated (since 5.2) Use {@link NamedQueryRepository#registerNamedSQLQueryDefinition} instead. */ @Deprecated default void registerNamedSQLQueryDefinition(String name, NamedSQLQueryDefinition definition) { @@ -246,7 +247,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { } /** - * @deprecated (since 6.0) Use {@link NamedQueryRepository#getResultSetMappingDefinition} instead. + * @deprecated (since 5.2) Use {@link NamedQueryRepository#getResultSetMappingDefinition} instead. */ @Deprecated default ResultSetMappingDefinition getResultSetMapping(String name) { @@ -267,7 +268,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { * * @return The dialect * - * @deprecated (since 6.0) instead, use this factory's {{@link #getServiceRegistry()}} -> + * @deprecated (since 5.2) instead, use this factory's {{@link #getServiceRegistry()}} -> * {@link JdbcServices#getDialect()} */ @Deprecated @@ -321,7 +322,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { MetamodelImplementor getMetamodel(); /** - * @deprecated (since 6.0) Use {@link MetamodelImplementor#entityPersister(Class)} instead. + * @deprecated (since 5.2) Use {@link MetamodelImplementor#entityPersister(Class)} instead. */ @Deprecated default EntityPersister getEntityPersister(String entityName) throws MappingException { @@ -329,7 +330,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { } /** - * @deprecated (since 6.0) Use {@link MetamodelImplementor#entityPersisters} instead. + * @deprecated (since 5.2) Use {@link MetamodelImplementor#entityPersisters} instead. */ @Deprecated default Map getEntityPersisters() { @@ -337,7 +338,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { } /** - * @deprecated (since 6.0) Use {@link MetamodelImplementor#collectionPersister(String)} instead. + * @deprecated (since 5.2) Use {@link MetamodelImplementor#collectionPersister(String)} instead. */ @Deprecated default CollectionPersister getCollectionPersister(String role) throws MappingException { @@ -345,7 +346,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { } /** - * @deprecated (since 6.0) Use {@link MetamodelImplementor#collectionPersisters} instead. + * @deprecated (since 5.2) Use {@link MetamodelImplementor#collectionPersisters} instead. */ @Deprecated default Map getCollectionPersisters() { @@ -353,7 +354,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { } /** - * @deprecated (since 6.0) Use {@link MetamodelImplementor#collectionPersisters} instead. + * @deprecated (since 5.2) Use {@link MetamodelImplementor#collectionPersisters} instead. * Retrieves a set of all the collection roles in which the given entity * is a participant, as either an index or an element. * @@ -365,7 +366,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { } /** - * @deprecated (since 6.0) Use {@link MetamodelImplementor#locateEntityPersister(Class)} instead. + * @deprecated (since 5.2) Use {@link MetamodelImplementor#locateEntityPersister(Class)} instead. */ @Deprecated default EntityPersister locateEntityPersister(Class byClass) { @@ -373,7 +374,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { } /** - * @deprecated (since 6.0) Use {@link MetamodelImplementor#locateEntityPersister(String)} instead. + * @deprecated (since 5.2) Use {@link MetamodelImplementor#locateEntityPersister(String)} instead. */ @Deprecated default EntityPersister locateEntityPersister(String byName) { @@ -413,7 +414,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { * * @return The name of the region * - * @deprecated (since 6.0) Use this factory's {@link #getCache()} reference + * @deprecated (since 5.2) Use this factory's {@link #getCache()} reference * to access Region via {@link CacheImplementor#determineEntityRegionAccessStrategy} or * {@link CacheImplementor#determineCollectionRegionAccessStrategy} instead. */ @@ -440,7 +441,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { * @return That region's "access strategy" * * - * @deprecated (since 6.0) Use this factory's {@link #getCache()} reference + * @deprecated (since 5.2) Use this factory's {@link #getCache()} reference * to access {@link CacheImplementor#determineEntityRegionAccessStrategy} or * {@link CacheImplementor#determineCollectionRegionAccessStrategy} instead. */ @@ -466,7 +467,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { * * @return The region * - * @deprecated (since 6.0) Use this factory's {@link #getCache()} -> + * @deprecated (since 5.2) Use this factory's {@link #getCache()} -> * {@link CacheImplementor#getNaturalIdCacheRegionAccessStrategy(String)} -> * {@link NaturalIdRegionAccessStrategy#getRegion()} instead. */ @@ -482,7 +483,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { * * @return That region's "access strategy" * - * @deprecated (since 6.0) Use this factory's {@link #getCache()} -> + * @deprecated (since 5.2) Use this factory's {@link #getCache()} -> * {@link CacheImplementor#getNaturalIdCacheRegionAccessStrategy(String)} instead. */ @Deprecated @@ -497,7 +498,7 @@ public interface SessionFactoryImplementor extends Mapping, SessionFactory { * * @return The map of regions * - * @deprecated (since 6.0) with no direct replacement; use this factory's {@link #getCache()} reference + * @deprecated (since 5.2) with no direct replacement; use this factory's {@link #getCache()} reference * to access cache objects as needed. */ @Deprecated diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionOwner.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionOwner.java index 83624eac3a..903a3ee6a8 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionOwner.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionOwner.java @@ -17,7 +17,7 @@ import org.hibernate.resource.transaction.backend.jta.internal.synchronization.M * * @see SessionBuilderImplementor#owner * - * @deprecated (since 6.0) since consolidating hibernate-entitymanager into hibernate-core + * @deprecated (since 5.2) since consolidating hibernate-entitymanager into hibernate-core * I believe this is no longer needed. */ @Deprecated diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionContractImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionContractImplementor.java index ce90a8a10d..c7a4fda6c9 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionContractImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionContractImplementor.java @@ -404,7 +404,7 @@ public interface SharedSessionContractImplementor * * @param flushMode the new flush mode * - * @deprecated (since 6.0) use {@link #setHibernateFlushMode(FlushMode)} instead + * @deprecated (since 5.2) use {@link #setHibernateFlushMode(FlushMode)} instead */ @Deprecated void setFlushMode(FlushMode flushMode); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionImpl.java index 42b1d9541a..2b63c3a5c4 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionImpl.java @@ -53,7 +53,8 @@ public class TransactionImpl implements TransactionImplementor { @Override public void commit() { - if ( getStatus() != TransactionStatus.ACTIVE ) { + if ( !isActive() ) { + // allow MARKED_ROLLBACK to propagate through to transactionDriverControl throw new IllegalStateException( "Transaction not successfully started" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java index fe5ee18936..c9d4e268d6 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java @@ -513,7 +513,7 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i ); if ( event.isAssociationFetch() && event.getSession().getFactory().getStatistics().isStatisticsEnabled() ) { - event.getSession().getFactory().getStatisticsImplementor().fetchEntity( event.getEntityClassName() ); + event.getSession().getFactory().getStatistics().fetchEntity( event.getEntityClassName() ); } return entity; diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/QuerySplitter.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/QuerySplitter.java index f5716a623e..e95c188e68 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/QuerySplitter.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/QuerySplitter.java @@ -186,6 +186,6 @@ public final class QuerySplitter { } public static String getImportedClass(String name, SessionFactoryImplementor factory) { - return factory.getImportedClassName( name ); + return factory.getMetamodel().getImportedClassName( name ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/ParameterTranslationsImpl.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/ParameterTranslationsImpl.java index f5f837c261..8348562dbb 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/ParameterTranslationsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/ParameterTranslationsImpl.java @@ -41,8 +41,7 @@ public class ParameterTranslationsImpl implements ParameterTranslations { } public ParameterInfo getOrdinalParameterInfo(int ordinalPosition) { - // remember that ordinal parameters numbers are 1-based!!! - return ordinalParameters[ordinalPosition - 1]; + return ordinalParameters[ordinalPosition]; } @Override @@ -85,14 +84,14 @@ public class ParameterTranslationsImpl implements ParameterTranslations { */ public ParameterTranslationsImpl(List parameterSpecifications) { class NamedParamTempHolder { - String name; - Type type; - List positions = new ArrayList(); + private String name; + private Type type; + private List positions = new ArrayList<>(); } final int size = parameterSpecifications.size(); - final List ordinalParameterList = new ArrayList(); - final Map namedParameterMap = new HashMap(); + final List ordinalParameterList = new ArrayList<>(); + final Map namedParameterMap = new HashMap<>(); for ( int i = 0; i < size; i++ ) { final ParameterSpecification spec = parameterSpecifications.get( i ); if ( PositionalParameterSpecification.class.isInstance( spec ) ) { @@ -124,7 +123,7 @@ public class ParameterTranslationsImpl implements ParameterTranslations { namedParameters = java.util.Collections.emptyMap(); } else { - final Map namedParametersBacking = new HashMap( namedParameterMap.size() ); + final Map namedParametersBacking = new HashMap<>( namedParameterMap.size() ); for ( NamedParamTempHolder holder : namedParameterMap.values() ) { namedParametersBacking.put( holder.name, diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/SessionFactoryHelper.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/SessionFactoryHelper.java index df7b072b8f..6d800109b6 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/SessionFactoryHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/SessionFactoryHelper.java @@ -51,7 +51,7 @@ public class SessionFactoryHelper { */ public SessionFactoryHelper(SessionFactoryImplementor sfi) { this.sfi = sfi; - this.collectionPropertyMappingByRole = new HashMap(); + this.collectionPropertyMappingByRole = new HashMap<>(); } /** @@ -91,7 +91,7 @@ public class SessionFactoryHelper { * @return The qualified class name. */ public String getImportedClassName(String className) { - return sfi.getImportedClassName( className ); + return sfi.getMetamodel().getImportedClassName( className ); } /** @@ -115,12 +115,12 @@ public class SessionFactoryHelper { * @return The defined persister for this class, or null if none found. */ public static Queryable findQueryableUsingImports(SessionFactoryImplementor sfi, String className) { - final String importedClassName = sfi.getImportedClassName( className ); + final String importedClassName = sfi.getMetamodel().getImportedClassName( className ); if ( importedClassName == null ) { return null; } try { - return (Queryable) sfi.getEntityPersister( importedClassName ); + return (Queryable) sfi.getMetamodel().entityPersister( importedClassName ); } catch ( MappingException me ) { return null; @@ -139,18 +139,18 @@ public class SessionFactoryHelper { public EntityPersister findEntityPersisterByName(String name) throws MappingException { // First, try to get the persister using the given name directly. try { - return sfi.getEntityPersister( name ); + return sfi.getMetamodel().entityPersister( name ); } catch ( MappingException ignore ) { // unable to locate it using this name } // If that didn't work, try using the 'import' name. - String importedClassName = sfi.getImportedClassName( name ); + String importedClassName = sfi.getMetamodel().getImportedClassName( name ); if ( importedClassName == null ) { return null; } - return sfi.getEntityPersister( importedClassName ); + return sfi.getMetamodel().entityPersister( importedClassName ); } /** @@ -186,7 +186,7 @@ public class SessionFactoryHelper { */ public QueryableCollection getCollectionPersister(String role) { try { - return (QueryableCollection) sfi.getCollectionPersister( role ); + return (QueryableCollection) sfi.getMetamodel().collectionPersister( role ); } catch ( ClassCastException cce ) { throw new QueryException( "collection is not queryable: " + role ); @@ -208,7 +208,7 @@ public class SessionFactoryHelper { */ public QueryableCollection requireQueryableCollection(String role) throws QueryException { try { - QueryableCollection queryableCollection = (QueryableCollection) sfi.getCollectionPersister( role ); + QueryableCollection queryableCollection = (QueryableCollection) sfi.getMetamodel().collectionPersister( role ); if ( queryableCollection != null ) { collectionPropertyMappingByRole.put( role, new CollectionPropertyMapping( queryableCollection ) ); } @@ -419,6 +419,6 @@ public class SessionFactoryHelper { } public boolean isStrictJPAQLComplianceEnabled() { - return sfi.getSettings().isStrictJPAQLCompliance(); + return sfi.getSessionFactoryOptions().isStrictJpaQueryLanguageCompliance(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java index 408f58b9e5..6b9d4af143 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java @@ -20,11 +20,13 @@ import javax.persistence.LockTimeoutException; import javax.persistence.NoResultException; import javax.persistence.NonUniqueResultException; import javax.persistence.OptimisticLockException; +import javax.persistence.PersistenceContextType; import javax.persistence.PersistenceException; import javax.persistence.PessimisticLockException; import javax.persistence.QueryTimeoutException; import javax.persistence.SynchronizationType; import javax.persistence.Tuple; +import javax.persistence.spi.PersistenceUnitTransactionType; import org.hibernate.AssertionFailure; import org.hibernate.CacheMode; @@ -94,6 +96,7 @@ import org.hibernate.query.internal.QueryImpl; import org.hibernate.query.spi.NativeQueryImplementor; import org.hibernate.query.spi.QueryImplementor; import org.hibernate.resource.jdbc.spi.JdbcSessionContext; +import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode; import org.hibernate.resource.jdbc.spi.StatementInspector; import org.hibernate.resource.transaction.TransactionCoordinator; import org.hibernate.resource.transaction.TransactionCoordinatorBuilder; @@ -127,8 +130,19 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont private final String tenantIdentifier; private final UUID sessionIdentifier; + // todo : (5.2) review synchronizationType, persistenceContextType, transactionType usage + + private transient PhysicalConnectionHandlingMode connectionHandlingMode; + // SynchronizationType -> should we auto enlist in transactions + private transient SynchronizationType synchronizationType; + // PersistenceUnitTransactionType -> what type of TransactionCoordinator(Builder) to use; + // according to JPA should technically also disallow access to Transaction object for + // JTA environments + private transient PersistenceUnitTransactionType transactionType; + // PersistenceContextType -> influences FlushMode and 'autoClose' + private transient PersistenceContextType persistenceContextType; + private final boolean isTransactionCoordinatorShared; - private final boolean autoJoinTransactions; private final TransactionCoordinator transactionCoordinator; private final JdbcCoordinator jdbcCoordinator; private final Interceptor interceptor; @@ -139,7 +153,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont private CacheMode cacheMode; private boolean closed; - private transient SessionEventListenerManagerImpl sessionEventsManager; + private transient SessionEventListenerManagerImpl sessionEventsManager = new SessionEventListenerManagerImpl(); private transient JdbcConnectionAccess jdbcConnectionAccess; private transient TransactionImplementor currentHibernateTransaction; private transient Boolean useStreamForLobBinding; @@ -150,6 +164,10 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont this.sessionIdentifier = StandardRandomStrategy.INSTANCE.generateUUID( null ); this.timestamp = factory.getCache().getRegionFactory().nextTimestamp(); + this.transactionType = options.getPersistenceUnitTransactionType(); + this.synchronizationType = options.getSynchronizationType(); + this.persistenceContextType = PersistenceContextType.TRANSACTION; + this.tenantIdentifier = options.getTenantIdentifier(); if ( MultiTenancyStrategy.NONE == factory.getSettings().getMultiTenancyStrategy() ) { if ( tenantIdentifier != null ) { @@ -175,7 +193,6 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont } this.isTransactionCoordinatorShared = true; - this.autoJoinTransactions = false; final SharedSessionCreationOptions sharedOptions = (SharedSessionCreationOptions) options; this.transactionCoordinator = sharedOptions.getTransactionCoordinator(); @@ -196,10 +213,11 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont "with sharing JDBC connection between sessions; ignoring" ); } + + addSharedSessionTransactionObserver( transactionCoordinator ); } else { this.isTransactionCoordinatorShared = false; - this.autoJoinTransactions = options.getSynchronizationType() == SynchronizationType.SYNCHRONIZED; this.jdbcCoordinator = new JdbcCoordinatorImpl( options.getConnection(), this ); this.transactionCoordinator = factory.getServiceRegistry() @@ -211,6 +229,9 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont } } + protected void addSharedSessionTransactionObserver(TransactionCoordinator transactionCoordinator) { + } + private Interceptor interpret(Interceptor interceptor) { return interceptor == null ? EmptyInterceptor.INSTANCE : interceptor; } @@ -235,15 +256,6 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont return interceptor; } - @Override - public SessionEventListenerManager getEventListenerManager() { - if ( sessionEventsManager == null ) { - // See class-level JavaDocs for a discussion of the concurrent-access safety of this method - sessionEventsManager = new SessionEventListenerManagerImpl(); - } - return sessionEventsManager; - } - @Override public JdbcCoordinator getJdbcCoordinator() { return jdbcCoordinator; @@ -263,6 +275,11 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont return entityNameResolver; } + @Override + public SessionEventListenerManager getEventListenerManager() { + return sessionEventsManager; + } + @Override public UUID getSessionIdentifier() { return sessionIdentifier; @@ -273,6 +290,24 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont return tenantIdentifier; } + public SynchronizationType getSynchronizationType() { + return synchronizationType; + } + + public PersistenceUnitTransactionType getTransactionType() { + return transactionType; + } + + public PersistenceContextType getPersistenceContextType() { + return persistenceContextType; + } + + @Override + public void disableTransactionAutoJoin() { + checkOpen(); + synchronizationType = SynchronizationType.UNSYNCHRONIZED; + } + @Override public long getTimestamp() { return timestamp; @@ -294,7 +329,9 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont return; } - sessionEventsManager.end(); + if ( sessionEventsManager != null ) { + sessionEventsManager.end(); + } if ( currentHibernateTransaction != null ) { currentHibernateTransaction.invalidate(); @@ -404,7 +441,8 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont @Override public boolean isConnected() { - return jdbcCoordinator.getLogicalConnection().isPhysicallyConnected(); + checkTransactionSynchStatus(); + return jdbcCoordinator.getLogicalConnection().isOpen(); } @Override @@ -882,12 +920,12 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont @Override public NativeQueryImplementor createSQLQuery(String queryString) { - return null; + return createNativeQuery( queryString ); } @Override public NativeQueryImplementor getNamedSQLQuery(String name) { - return null; + return getNamedNativeQuery( name ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java index e9ac2e56f8..ed32eb9095 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/CacheImpl.java @@ -23,6 +23,7 @@ import org.hibernate.cache.spi.EntityRegion; import org.hibernate.cache.spi.NaturalIdRegion; import org.hibernate.cache.spi.QueryCache; import org.hibernate.cache.spi.QueryResultsRegion; +import org.hibernate.cache.spi.Region; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TimestampsRegion; import org.hibernate.cache.spi.UpdateTimestampsCache; @@ -53,6 +54,8 @@ public class CacheImpl implements CacheImplementor { private final transient RegionFactory regionFactory; private final String cacheRegionPrefix; + private final transient ConcurrentHashMap allRegionsMap = new ConcurrentHashMap<>(); + private final transient ConcurrentHashMap entityRegionAccessStrategyMap = new ConcurrentHashMap<>(); private final transient ConcurrentHashMap collectionRegionAccessStrategyMap = new ConcurrentHashMap<>(); private final transient ConcurrentHashMap naturalIdRegionAccessStrategyMap = new ConcurrentHashMap<>(); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index 68b323443b..955da44933 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -100,6 +100,7 @@ import org.hibernate.metamodel.spi.MetamodelImplementor; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Loadable; import org.hibernate.proxy.EntityNotFoundDelegate; +import org.hibernate.proxy.HibernateProxyHelper; import org.hibernate.query.criteria.internal.CriteriaBuilderImpl; import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode; import org.hibernate.resource.jdbc.spi.StatementInspector; @@ -116,6 +117,7 @@ import org.hibernate.stat.spi.StatisticsImplementor; import org.hibernate.tool.schema.spi.DelayedDropAction; import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator; import org.hibernate.tuple.entity.EntityTuplizer; +import org.hibernate.type.SerializableType; import org.hibernate.type.Type; import org.hibernate.type.TypeResolver; @@ -221,7 +223,6 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor { this.sqlFunctionRegistry = new SQLFunctionRegistry( jdbcServices.getJdbcEnvironment().getDialect(), options.getCustomSqlFunctionMap() ); this.cacheAccess = this.serviceRegistry.getService( CacheImplementor.class ); - this.metamodel = MetamodelImpl.buildMetamodel( metadata, this, determineJpaMetaModelPopulationSetting( properties ) ); this.criteriaBuilder = new CriteriaBuilderImpl( this ); this.persistenceUnitUtil = new PersistenceUnitUtilImpl( this ); @@ -283,6 +284,9 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor { LOG.debug( "Instantiated session factory" ); + this.metamodel = new MetamodelImpl( this ); + this.metamodel.initialize( metadata, determineJpaMetaModelPopulationSetting( properties ) ); + settings.getMultiTableBulkIdStrategy().prepare( jdbcServices, buildLocalConnectionAccess(), @@ -645,25 +649,20 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor { } public CollectionMetadata getCollectionMetadata(String roleName) throws HibernateException { -// return collectionMetadata.get( roleName ); - return null; + return (CollectionMetadata) getMetamodel().collectionPersister( roleName ); } public ClassMetadata getClassMetadata(String entityName) throws HibernateException { -// return classMetadata.get( entityName ); - return null; + return (ClassMetadata) getMetamodel().entityPersister( entityName ); } - - + @Override public Map getAllClassMetadata() throws HibernateException { -// return classMetadata; - return null; + throw new UnsupportedOperationException( "org.hibernate.SessionFactory.getAllClassMetadata is no longer supported" ); } public Map getAllCollectionMetadata() throws HibernateException { -// return collectionMetadata; - return null; + throw new UnsupportedOperationException( "org.hibernate.SessionFactory.getAllCollectionMetadata is no longer supported" ); } public Type getReferencedPropertyType(String className, String propertyName) @@ -748,8 +747,13 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor { return isClosed; } + private transient StatisticsImplementor statistics; + public StatisticsImplementor getStatistics() { - return serviceRegistry.getService( StatisticsImplementor.class ); + if ( statistics == null ) { + statistics = serviceRegistry.getService( StatisticsImplementor.class ); + } + return statistics; } public FilterDefinition getFilterDefinition(String filterName) throws HibernateException { @@ -841,6 +845,36 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor { return typeHelper; } + @Override + public Type resolveParameterBindType(Object bindValue) { + if ( bindValue == null ) { + // we can't guess + return null; + } + + final Class clazz = HibernateProxyHelper.getClassWithoutInitializingProxy( bindValue ); + String typename = clazz.getName(); + Type type = getTypeResolver().heuristicType( typename ); + boolean serializable = type != null && type instanceof SerializableType; + if ( type == null || serializable ) { + try { + getMetamodel().entityPersister( clazz.getName() ); + } + catch (MappingException me) { + if ( serializable ) { + return type; + } + else { + throw new HibernateException( "Could not determine a type for class: " + typename ); + } + } + return getTypeHelper().entity( clazz ); + } + else { + return type; + } + } + static class SessionBuilderImpl implements SessionBuilderImplementor, SessionCreationOptions { private static final Logger log = CoreLogging.logger( SessionBuilderImpl.class ); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java index 777215c13a..7ae01af4de 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java @@ -20,6 +20,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; @@ -38,6 +39,7 @@ import javax.persistence.LockTimeoutException; import javax.persistence.NoResultException; import javax.persistence.NonUniqueResultException; import javax.persistence.OptimisticLockException; +import javax.persistence.PersistenceContextType; import javax.persistence.PersistenceException; import javax.persistence.PessimisticLockException; import javax.persistence.PessimisticLockScope; @@ -81,7 +83,6 @@ import org.hibernate.SharedSessionBuilder; import org.hibernate.SimpleNaturalIdLoadAccess; import org.hibernate.StaleObjectStateException; import org.hibernate.StaleStateException; -import org.hibernate.TransactionException; import org.hibernate.TransientObjectException; import org.hibernate.TypeHelper; import org.hibernate.TypeMismatchException; @@ -92,7 +93,6 @@ import org.hibernate.criterion.NaturalIdentifier; import org.hibernate.dialect.lock.LockingStrategyException; import org.hibernate.dialect.lock.OptimisticEntityLockException; import org.hibernate.dialect.lock.PessimisticEntityLockException; -import org.hibernate.engine.internal.SessionEventListenerManagerImpl; import org.hibernate.engine.internal.StatefulPersistenceContext; import org.hibernate.engine.jdbc.LobCreator; import org.hibernate.engine.jdbc.NonContextualLobCreator; @@ -166,6 +166,7 @@ import org.hibernate.jpa.internal.util.FlushModeTypeHelper; import org.hibernate.jpa.internal.util.LockModeTypeHelper; import org.hibernate.jpa.spi.CriteriaQueryTupleTransformer; import org.hibernate.jpa.spi.HibernateEntityManagerImplementor; +import org.hibernate.loader.MultipleBagFetchException; import org.hibernate.loader.criteria.CriteriaLoader; import org.hibernate.loader.custom.CustomLoader; import org.hibernate.loader.custom.CustomQuery; @@ -239,9 +240,7 @@ public final class SessionImpl private transient SessionOwner sessionOwner; - private SessionEventListenerManagerImpl sessionEventsManager = new SessionEventListenerManagerImpl(); - - private Map properties; + private Map properties = new HashMap<>(); private transient ActionQueue actionQueue; private transient StatefulPersistenceContext persistenceContext; @@ -252,18 +251,11 @@ public final class SessionImpl private transient ManagedFlushChecker managedFlushChecker; private transient AfterCompletionAction afterCompletionAction; + // todo : (5.2) HEM always initialized this. Is that really needed? + private LockOptions lockOptions = new LockOptions(); - // todo : (5.2) review synchronizationType, persistenceContextType, transactionType usage - - private transient PhysicalConnectionHandlingMode connectionHandlingMode; - private transient SynchronizationType synchronizationType; - private transient PersistenceUnitTransactionType transactionType; - - private LockOptions lockOptions; - - + // todo : (5.2) are these still really needed? private transient boolean autoClear; //for EJB3 - private transient boolean autoJoinTransactions = true; private transient boolean flushBeforeCompletionEnabled; private transient boolean autoCloseSessionEnabled; @@ -277,15 +269,15 @@ public final class SessionImpl public SessionImpl(SessionFactoryImpl factory, SessionCreationOptions options) { super( factory, options ); - this.transactionType = options.getPersistenceUnitTransactionType(); - this.synchronizationType = options.getSynchronizationType(); - this.actionQueue = new ActionQueue( this ); this.persistenceContext = new StatefulPersistenceContext( this ); this.sessionOwner = options.getSessionOwner(); initializeFromSessionOwner( sessionOwner ); + this.autoClear = options.isClearStateOnCloseEnabled(); + this.flushBeforeCompletionEnabled = options.isFlushBeforeCompletionEnabled(); + if ( options instanceof SharedSessionCreationOptions && ( (SharedSessionCreationOptions) options ).isTransactionCoordinatorShared() ) { final SharedSessionCreationOptions sharedOptions = (SharedSessionCreationOptions) options; if ( sharedOptions.getTransactionCompletionProcesses() != null ) { @@ -318,12 +310,14 @@ public final class SessionImpl public void afterCompletion(boolean successful, boolean delayed) { log.tracef( "TransactionObserver#afterCompletion(%s, %s) on Session [%s]", successful, delayed, getSessionIdentifier() ); afterTransactionCompletion( successful, delayed ); - if ( !isClosed() && autoCloseSessionEnabled ) { - managedClose(); - } } } ); + + } + else { + this.autoCloseSessionEnabled = getPersistenceContextType() == PersistenceContextType.TRANSACTION + && factory.getSessionFactoryOptions().isAutoCloseSessionEnabled(); } loadQueryInfluencers = new LoadQueryInfluencers( factory ); @@ -388,7 +382,7 @@ public final class SessionImpl private void applyProperties() { - setHibernateFlushMode( ConfigurationHelper.getFlushMode( properties.get( AvailableSettings.FLUSH_MODE ) ) ); + setHibernateFlushMode( ConfigurationHelper.getFlushMode( properties.get( AvailableSettings.FLUSH_MODE ), FlushMode.AUTO ) ); setLockOptions( this.properties, this.lockOptions ); getSession().setCacheMode( CacheModeHelper.interpretCacheMode( @@ -623,10 +617,16 @@ public final class SessionImpl @Override public void close() throws HibernateException { log.tracef( "Closing session [%s]", getSessionIdentifier() ); - checkOpen(); + +// todo : we want this check if usage is JPA, but not native Hibernate usage +// checkOpen(); super.close(); + if ( getFactory().getStatistics().isStatisticsEnabled() ) { + getFactory().getStatistics().closeSession(); + } + // Original hibernate-entitymanager EM#close behavior // does any of this need to be integrated? // checkSessionFactoryOpen(); @@ -663,7 +663,7 @@ public final class SessionImpl @Override public boolean shouldAutoJoinTransaction() { - return synchronizationType == SynchronizationType.SYNCHRONIZED; + return getSynchronizationType() == SynchronizationType.SYNCHRONIZED; } @Override @@ -744,12 +744,6 @@ public final class SessionImpl autoClear = enabled; } - @Override - public void disableTransactionAutoJoin() { - checkOpen(); - autoJoinTransactions = false; - } - /** * Check if there is a Hibernate or JTA transaction in progress and, * if there is not, flush if necessary, make sure the connection has @@ -764,11 +758,6 @@ public final class SessionImpl } } - @Override - public SessionEventListenerManagerImpl getEventListenerManager() { - return sessionEventsManager; - } - @Override public void addEventListeners(SessionEventListener... listeners) { getEventListenerManager().addListener( listeners ); @@ -2120,10 +2109,14 @@ public final class SessionImpl checkOpen(); // checkTransactionSynchStatus(); - if ( object != null - && !( object instanceof HibernateProxy ) - && getSessionFactory().getMetamodel().entityPersister( object.getClass() ) == null ) { - throw convert( new IllegalArgumentException( "Not an entity:" + object.getClass() ) ); + if ( object != null && !HibernateProxy.class.isInstance( object ) ) { + // check if it is an entity -> if not throw an exception (per JPA) + try { + getSessionFactory().getMetamodel().entityPersister( object.getClass() ); + } + catch (HibernateException e) { + throw convert( new IllegalArgumentException( "Not an entity:" + object.getClass() ) ); + } } try { @@ -2518,12 +2511,12 @@ public final class SessionImpl @Override public PersistenceUnitTransactionType getTransactionType() { - return transactionType; + return super.getTransactionType(); } @Override public SynchronizationType getSynchronizationType() { - return synchronizationType; + return super.getSynchronizationType(); } private static class LobHelperImpl implements LobHelper { @@ -2617,7 +2610,7 @@ public final class SessionImpl @Override public T autoJoinTransactions() { - return autoJoinTransactions( session.autoJoinTransactions ); + return autoJoinTransactions( session.isAutoCloseSessionEnabled() ); } @Override @@ -2714,6 +2707,39 @@ public final class SessionImpl } } + @Override + protected void addSharedSessionTransactionObserver(TransactionCoordinator transactionCoordinator) { + transactionCoordinator.addObserver( + new TransactionObserver() { + @Override + public void afterBegin() { + } + + @Override + public void beforeCompletion() { + if ( isOpen() && flushBeforeCompletionEnabled ) { + managedFlush(); + } + actionQueue.beforeTransactionCompletion(); + try { + getInterceptor().beforeTransactionCompletion( getCurrentTransaction() ); + } + catch (Throwable t) { + log.exceptionInBeforeTransactionCompletionInterceptor( t ); + } + } + + @Override + public void afterCompletion(boolean successful, boolean delayed) { + afterTransactionCompletion( successful, delayed ); + if ( !isClosed() && autoCloseSessionEnabled ) { + managedClose(); + } + } + } + ); + } + private class IdentifierLoadAccessImpl implements IdentifierLoadAccess { private final EntityPersister entityPersister; private LockOptions lockOptions; @@ -3286,9 +3312,9 @@ public final class SessionImpl @Override public RuntimeException convert(HibernateException e, LockOptions lockOptions) { Throwable cause = e; - if(e instanceof TransactionException){ - cause = e.getCause(); - } +// if (e instanceof TransactionException){ +// cause = e.getCause(); +// } if ( cause instanceof StaleStateException ) { final PersistenceException converted = wrapStaleStateException( (StaleStateException) cause ); handlePersistenceException( converted ); @@ -3337,6 +3363,9 @@ public final class SessionImpl else if ( cause instanceof QueryException ) { return new IllegalArgumentException( cause ); } + else if ( cause instanceof MultipleBagFetchException ) { + return new IllegalArgumentException( cause ); + } else if ( cause instanceof TransientObjectException ) { try { markForRollbackOnly(); @@ -3660,9 +3689,7 @@ public final class SessionImpl private void checkTransactionNeeded() { if ( !isTransactionInProgress() ) { - throw new TransactionRequiredException( - "no transaction is in progress" - ); + throw new TransactionRequiredException( "no transaction is in progress" ); } } @@ -3974,7 +4001,7 @@ public final class SessionImpl } private void joinTransaction(boolean explicitRequest) { - if ( transactionType != PersistenceUnitTransactionType.JTA ) { + if ( getTransactionType() != PersistenceUnitTransactionType.JTA ) { if ( explicitRequest ) { log.callingJoinTransactionOnNonJtaEntityManager(); } diff --git a/hibernate-core/src/main/java/org/hibernate/jpa/AvailableSettings.java b/hibernate-core/src/main/java/org/hibernate/jpa/AvailableSettings.java index 4d32e6893f..fc0181d231 100644 --- a/hibernate-core/src/main/java/org/hibernate/jpa/AvailableSettings.java +++ b/hibernate-core/src/main/java/org/hibernate/jpa/AvailableSettings.java @@ -20,115 +20,115 @@ public interface AvailableSettings { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_PERSISTENCE_PROVIDER} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_PERSISTENCE_PROVIDER} instead */ @Deprecated String PROVIDER = org.hibernate.cfg.AvailableSettings.JPA_PERSISTENCE_PROVIDER; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_TRANSACTION_TYPE} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_TRANSACTION_TYPE} instead */ @Deprecated String TRANSACTION_TYPE = org.hibernate.cfg.AvailableSettings.JPA_TRANSACTION_TYPE; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_JTA_DATASOURCE} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_JTA_DATASOURCE} instead */ @Deprecated String JTA_DATASOURCE = org.hibernate.cfg.AvailableSettings.JPA_JTA_DATASOURCE; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_NON_JTA_DATASOURCE} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_NON_JTA_DATASOURCE} instead */ @Deprecated String NON_JTA_DATASOURCE = org.hibernate.cfg.AvailableSettings.JPA_NON_JTA_DATASOURCE; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_JDBC_DRIVER} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_JDBC_DRIVER} instead */ @Deprecated String JDBC_DRIVER = org.hibernate.cfg.AvailableSettings.JPA_JDBC_DRIVER; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_JDBC_URL} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_JDBC_URL} instead */ @Deprecated String JDBC_URL = org.hibernate.cfg.AvailableSettings.JPA_JDBC_URL; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_JDBC_USER} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_JDBC_USER} instead */ @Deprecated String JDBC_USER = org.hibernate.cfg.AvailableSettings.JPA_JDBC_USER; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_JDBC_USER} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_JDBC_USER} instead */ @Deprecated String JDBC_PASSWORD = org.hibernate.cfg.AvailableSettings.JPA_JDBC_USER; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_SHARED_CACHE_MODE} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_SHARED_CACHE_MODE} instead */ @Deprecated String SHARED_CACHE_MODE = org.hibernate.cfg.AvailableSettings.JPA_SHARED_CACHE_MODE; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_SHARED_CACHE_RETRIEVE_MODE} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_SHARED_CACHE_RETRIEVE_MODE} instead */ @Deprecated String SHARED_CACHE_RETRIEVE_MODE = org.hibernate.cfg.AvailableSettings.JPA_SHARED_CACHE_RETRIEVE_MODE; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_SHARED_CACHE_STORE_MODE} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_SHARED_CACHE_STORE_MODE} instead */ @Deprecated String SHARED_CACHE_STORE_MODE = org.hibernate.cfg.AvailableSettings.JPA_SHARED_CACHE_STORE_MODE; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_VALIDATION_MODE} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_VALIDATION_MODE} instead */ @Deprecated String VALIDATION_MODE = org.hibernate.cfg.AvailableSettings.JPA_VALIDATION_MODE; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_VALIDATION_FACTORY} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_VALIDATION_FACTORY} instead */ @Deprecated String VALIDATION_FACTORY = org.hibernate.cfg.AvailableSettings.JPA_VALIDATION_FACTORY; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_PERSIST_VALIDATION_GROUP} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_PERSIST_VALIDATION_GROUP} instead */ @Deprecated String PERSIST_VALIDATION_GROUP = org.hibernate.cfg.AvailableSettings.JPA_PERSIST_VALIDATION_GROUP; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_UPDATE_VALIDATION_GROUP} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_UPDATE_VALIDATION_GROUP} instead */ @Deprecated String UPDATE_VALIDATION_GROUP = org.hibernate.cfg.AvailableSettings.JPA_UPDATE_VALIDATION_GROUP; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_REMOVE_VALIDATION_GROUP} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_REMOVE_VALIDATION_GROUP} instead */ @Deprecated String REMOVE_VALIDATION_GROUP = org.hibernate.cfg.AvailableSettings.JPA_REMOVE_VALIDATION_GROUP; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_LOCK_SCOPE} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_LOCK_SCOPE} instead */ @Deprecated String LOCK_SCOPE = org.hibernate.cfg.AvailableSettings.JPA_LOCK_SCOPE; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#JPA_LOCK_TIMEOUT} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#JPA_LOCK_TIMEOUT} instead */ @Deprecated String LOCK_TIMEOUT = org.hibernate.cfg.AvailableSettings.JPA_LOCK_TIMEOUT; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#CDI_BEAN_MANAGER} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#CDI_BEAN_MANAGER} instead */ @Deprecated String CDI_BEAN_MANAGER = org.hibernate.cfg.AvailableSettings.CDI_BEAN_MANAGER; @@ -139,86 +139,86 @@ public interface AvailableSettings { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_CREATE_SOURCE} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_CREATE_SOURCE} instead */ @Deprecated String SCHEMA_GEN_CREATE_SOURCE = org.hibernate.cfg.AvailableSettings.HBM2DDL_CREATE_SOURCE; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DROP_SOURCE} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DROP_SOURCE} instead */ @Deprecated String SCHEMA_GEN_DROP_SOURCE = org.hibernate.cfg.AvailableSettings.HBM2DDL_DROP_SOURCE; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_CREATE_SCRIPT_SOURCE} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_CREATE_SCRIPT_SOURCE} instead */ @Deprecated String SCHEMA_GEN_CREATE_SCRIPT_SOURCE = org.hibernate.cfg.AvailableSettings.HBM2DDL_CREATE_SCRIPT_SOURCE; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DROP_SCRIPT_SOURCE} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DROP_SCRIPT_SOURCE} instead */ @Deprecated String SCHEMA_GEN_DROP_SCRIPT_SOURCE = org.hibernate.cfg.AvailableSettings.HBM2DDL_DROP_SCRIPT_SOURCE; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DATABASE_ACTION} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DATABASE_ACTION} instead */ @Deprecated String SCHEMA_GEN_DATABASE_ACTION = org.hibernate.cfg.AvailableSettings.HBM2DDL_DATABASE_ACTION; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_SCRIPTS_ACTION} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_SCRIPTS_ACTION} instead */ @Deprecated String SCHEMA_GEN_SCRIPTS_ACTION = org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_ACTION; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_SCRIPTS_CREATE_TARGET} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_SCRIPTS_CREATE_TARGET} instead */ @Deprecated String SCHEMA_GEN_SCRIPTS_CREATE_TARGET = org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_CREATE_TARGET; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_SCRIPTS_DROP_TARGET} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_SCRIPTS_DROP_TARGET} instead */ @Deprecated String SCHEMA_GEN_SCRIPTS_DROP_TARGET = org.hibernate.cfg.AvailableSettings.HBM2DDL_SCRIPTS_DROP_TARGET; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#HBM2DLL_CREATE_NAMESPACES} + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DLL_CREATE_NAMESPACES} * or {@link org.hibernate.cfg.AvailableSettings#HBM2DLL_CREATE_SCHEMAS} instead */ @Deprecated String SCHEMA_GEN_CREATE_SCHEMAS = org.hibernate.cfg.AvailableSettings.HBM2DLL_CREATE_NAMESPACES; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_CONNECTION} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_CONNECTION} instead */ @Deprecated String SCHEMA_GEN_CONNECTION = org.hibernate.cfg.AvailableSettings.HBM2DDL_CONNECTION; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DB_NAME} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DB_NAME} instead */ @Deprecated String SCHEMA_GEN_DB_NAME = org.hibernate.cfg.AvailableSettings.HBM2DDL_DB_NAME; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DB_MAJOR_VERSION} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DB_MAJOR_VERSION} instead */ @Deprecated String SCHEMA_GEN_DB_MAJOR_VERSION = org.hibernate.cfg.AvailableSettings.HBM2DDL_DB_MAJOR_VERSION; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DB_MINOR_VERSION} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_DB_MINOR_VERSION} instead */ @Deprecated String SCHEMA_GEN_DB_MINOR_VERSION = org.hibernate.cfg.AvailableSettings.HBM2DDL_DB_MINOR_VERSION; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_LOAD_SCRIPT_SOURCE} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#HBM2DDL_LOAD_SCRIPT_SOURCE} instead */ @Deprecated String SCHEMA_GEN_LOAD_SCRIPT_SOURCE = org.hibernate.cfg.AvailableSettings.HBM2DDL_LOAD_SCRIPT_SOURCE; @@ -229,13 +229,13 @@ public interface AvailableSettings { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#INTERCEPTOR} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#INTERCEPTOR} instead */ @Deprecated String INTERCEPTOR = "hibernate.ejb.interceptor"; /** - * @deprecated (since 6.0) use {@link org.hibernate.cfg.AvailableSettings#SESSION_SCOPED_INTERCEPTOR} instead + * @deprecated (since 5.2) use {@link org.hibernate.cfg.AvailableSettings#SESSION_SCOPED_INTERCEPTOR} instead */ @Deprecated String SESSION_INTERCEPTOR = "hibernate.ejb.interceptor.session_scoped"; diff --git a/hibernate-core/src/main/java/org/hibernate/jpa/HibernateEntityManagerFactory.java b/hibernate-core/src/main/java/org/hibernate/jpa/HibernateEntityManagerFactory.java index a3a7dd2016..4024fc2d36 100755 --- a/hibernate-core/src/main/java/org/hibernate/jpa/HibernateEntityManagerFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/jpa/HibernateEntityManagerFactory.java @@ -20,7 +20,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; * * @author Gavin King * - * @deprecated (since 6.0) Use SessionFactory (or SessionFactoryImplementor) as it now extends EntityManagerFactory directly + * @deprecated (since 5.2) Use SessionFactory (or SessionFactoryImplementor) as it now extends EntityManagerFactory directly */ @Deprecated public interface HibernateEntityManagerFactory extends EntityManagerFactory, Serializable { diff --git a/hibernate-core/src/main/java/org/hibernate/jpa/internal/util/ConfigurationHelper.java b/hibernate-core/src/main/java/org/hibernate/jpa/internal/util/ConfigurationHelper.java index 76eade7fa7..8a66a509c7 100644 --- a/hibernate-core/src/main/java/org/hibernate/jpa/internal/util/ConfigurationHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/jpa/internal/util/ConfigurationHelper.java @@ -28,8 +28,8 @@ public abstract class ConfigurationHelper { } } - public static FlushMode getFlushMode(Object value) { - FlushMode flushMode = null; + public static FlushMode getFlushMode(Object value, FlushMode defaultFlushMode) { + final FlushMode flushMode; if (value instanceof FlushMode) { flushMode = (FlushMode) value; } @@ -39,12 +39,21 @@ public abstract class ConfigurationHelper { else if (value instanceof String) { flushMode = ConfigurationHelper.getFlushMode( (String) value); } + else { + flushMode = defaultFlushMode; + } + if (flushMode == null) { throw new PersistenceException("Unable to parse org.hibernate.flushMode: " + value); } + return flushMode; } + public static FlushMode getFlushMode(Object value) { + return getFlushMode( value, null ); + } + private static FlushMode getFlushMode(String flushMode) { if (flushMode == null) { return null; diff --git a/hibernate-core/src/main/java/org/hibernate/jpa/spi/HibernateEntityManagerFactoryAware.java b/hibernate-core/src/main/java/org/hibernate/jpa/spi/HibernateEntityManagerFactoryAware.java index 352bf88265..a50aad84fd 100644 --- a/hibernate-core/src/main/java/org/hibernate/jpa/spi/HibernateEntityManagerFactoryAware.java +++ b/hibernate-core/src/main/java/org/hibernate/jpa/spi/HibernateEntityManagerFactoryAware.java @@ -13,7 +13,7 @@ import org.hibernate.jpa.HibernateEntityManagerFactory; * * @author Strong Liu * - * @deprecated (since 6.0) Why do we need an over-arching access to HibernateEntityManagerFactory across + * @deprecated (since 5.2) Why do we need an over-arching access to HibernateEntityManagerFactory across * multiple contract hierarchies? */ @Deprecated diff --git a/hibernate-core/src/main/java/org/hibernate/jpa/spi/HibernateEntityManagerImplementor.java b/hibernate-core/src/main/java/org/hibernate/jpa/spi/HibernateEntityManagerImplementor.java index 1c5859faba..8e289017f4 100644 --- a/hibernate-core/src/main/java/org/hibernate/jpa/spi/HibernateEntityManagerImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/jpa/spi/HibernateEntityManagerImplementor.java @@ -118,7 +118,7 @@ public interface HibernateEntityManagerImplementor extends HibernateEntityManage * * @return the LockOptions * - * @deprecated (since 6.0) use {@link #buildLockOptions(LockModeType, Map)} instead + * @deprecated (since 5.2) use {@link #buildLockOptions(LockModeType, Map)} instead */ @Deprecated LockOptions getLockRequest(LockModeType lockModeType, Map properties); diff --git a/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/AbstractLoadPlanBasedEntityLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/AbstractLoadPlanBasedEntityLoader.java index 0fee5ffcf4..05d469d367 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/AbstractLoadPlanBasedEntityLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/entity/plan/AbstractLoadPlanBasedEntityLoader.java @@ -174,7 +174,7 @@ public abstract class AbstractLoadPlanBasedEntityLoader extends AbstractLoadPlan result = extractEntityResult( results ); } catch ( SQLException sqle ) { - throw getFactory().getSQLExceptionHelper().convert( + throw session.getJdbcServices().getSqlExceptionHelper().convert( sqle, "could not load an entity: " + MessageHelper.infoString( entityPersister, diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AttributeFactory.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AttributeFactory.java index 64650a17dd..1b8c060a41 100755 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AttributeFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/AttributeFactory.java @@ -239,14 +239,16 @@ public class AttributeFactory { final Type.PersistenceType persistenceType = ownerType.getPersistenceType(); if ( persistenceType == Type.PersistenceType.ENTITY ) { return context.getSessionFactory() - .getEntityPersister( ownerType.getTypeName() ) + .getMetamodel() + .entityPersister( ownerType.getTypeName() ) .getEntityMetamodel(); } else if ( persistenceType == Type.PersistenceType.MAPPED_SUPERCLASS ) { PersistentClass persistentClass = context.getPersistentClassHostingProperties( (MappedSuperclassTypeImpl) ownerType ); return context.getSessionFactory() - .getEntityPersister( persistentClass.getClassName() ) + .getMetamodel() + .entityPersister( persistentClass.getClassName() ) .getEntityMetamodel(); } else { @@ -921,6 +923,9 @@ public class AttributeFactory { else if ( java.util.Collection.class.isAssignableFrom( javaType ) ) { return PluralAttribute.CollectionType.COLLECTION; } + else if ( javaType.isArray() ) { + return PluralAttribute.CollectionType.LIST; + } else { throw new IllegalArgumentException( "Expecting collection type [" + javaType.getName() + "]" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataContext.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataContext.java index 6ae3091c61..b0fbb2132a 100755 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataContext.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataContext.java @@ -53,25 +53,18 @@ class MetadataContext { private final boolean ignoreUnsupported; private final AttributeFactory attributeFactory = new AttributeFactory( this ); - private Map, EntityTypeImpl> entityTypes - = new HashMap, EntityTypeImpl>(); - private Map> entityTypesByEntityName - = new HashMap>(); - private Map> entityTypesByPersistentClass - = new HashMap>(); - private Map, EmbeddableTypeImpl> embeddables - = new HashMap, EmbeddableTypeImpl>(); - private Map> mappedSuperclassByMappedSuperclassMapping - = new HashMap>(); + private Map, EntityTypeImpl> entityTypes = new HashMap<>(); + private Map> entityTypesByEntityName = new HashMap<>(); + private Map> entityTypesByPersistentClass = new HashMap<>(); + private Map, EmbeddableTypeImpl> embeddables = new HashMap<>(); + private Map> mappedSuperclassByMappedSuperclassMapping = new HashMap<>(); //this list contains MappedSuperclass and EntityTypes ordered by superclass first - private List orderedMappings = new ArrayList(); + private List orderedMappings = new ArrayList<>(); /** * Stack of PersistentClass being process. Last in the list is the highest in the stack. */ - private List stackOfPersistentClassesBeingProcessed - = new ArrayList(); - private Map, PersistentClass> mappedSuperClassTypeToPersistentClass - = new HashMap, PersistentClass>(); + private List stackOfPersistentClassesBeingProcessed = new ArrayList<>(); + private Map, PersistentClass> mappedSuperClassTypeToPersistentClass = new HashMap<>(); public MetadataContext( SessionFactoryImplementor sessionFactory, @@ -120,7 +113,9 @@ class MetadataContext { } /*package*/ void registerEntityType(PersistentClass persistentClass, EntityTypeImpl entityType) { - entityTypes.put( entityType.getBindableJavaType(), entityType ); + if ( entityType.getBindableJavaType() != null ) { + entityTypes.put( entityType.getBindableJavaType(), entityType ); + } entityTypesByEntityName.put( persistentClass.getEntityName(), entityType ); entityTypesByPersistentClass.put( persistentClass, entityType ); orderedMappings.add( persistentClass ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetamodelImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetamodelImpl.java index b126a8964c..3543b7efbf 100755 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetamodelImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetamodelImpl.java @@ -8,7 +8,6 @@ package org.hibernate.metamodel.internal; import java.io.Serializable; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.Locale; import java.util.Map; @@ -61,33 +60,33 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable { private final SessionFactoryImplementor sessionFactory; - private final Map imports; - private final Map entityPersisterMap; - private final Map entityProxyInterfaceMap; - private final Map collectionPersisterMap; - private final Map> collectionRolesByEntityParticipant; - private final ConcurrentMap entityNameResolvers; + private final Map imports = new ConcurrentHashMap<>(); + private final Map entityPersisterMap = new ConcurrentHashMap<>(); + private final Map entityProxyInterfaceMap = new ConcurrentHashMap<>(); + private final Map collectionPersisterMap = new ConcurrentHashMap<>(); + private final Map> collectionRolesByEntityParticipant = new ConcurrentHashMap<>(); + private final ConcurrentMap entityNameResolvers = new ConcurrentHashMap<>(); - private final Map, EntityTypeImpl> entities; - private final Map, EmbeddableTypeImpl> embeddables; - private final Map, MappedSuperclassType> mappedSuperclassTypeMap; - private final Map> entityTypesByEntityName; + private final Map, EntityTypeImpl> jpaEntityTypeMap = new ConcurrentHashMap<>(); + private final Map, EmbeddableTypeImpl> jpaEmbeddableTypeMap = new ConcurrentHashMap<>(); + private final Map, MappedSuperclassType> jpaMappedSuperclassTypeMap = new ConcurrentHashMap<>(); + private final Map> jpaEntityTypesByEntityName = new ConcurrentHashMap<>(); + + public MetamodelImpl(SessionFactoryImplementor sessionFactory) { + this.sessionFactory = sessionFactory; + } /** - * Build the metamodel using the information from the collection of Hibernate - * {@link PersistentClass} models as well as the Hibernate {@link org.hibernate.SessionFactory}. + * Prepare the metamodel using the information from the collection of Hibernate + * {@link PersistentClass} models * - * @param mappingMetadata Access to the mapping metadata - * @param sessionFactory The Hibernate session factory. - * @param jpaMetaModelPopulationSetting ignore unsupported/unknown annotations (like @Any) - * - * @return The built metamodel + * @param mappingMetadata The mapping information + * @param jpaMetaModelPopulationSetting Should the JPA Metamodel be built as well? */ - public static MetamodelImpl buildMetamodel( - MetadataImplementor mappingMetadata, - SessionFactoryImplementor sessionFactory, - JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting) { + public void initialize(MetadataImplementor mappingMetadata, JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting) { + this.imports.putAll( mappingMetadata.getImports() ); + final PersisterCreationContext persisterCreationContext = new PersisterCreationContext() { @Override public SessionFactoryImplementor getSessionFactory() { @@ -102,8 +101,6 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable { final PersisterFactory persisterFactory = sessionFactory.getServiceRegistry().getService( PersisterFactory.class ); - final Map entityPersisterMap = CollectionHelper.concurrentMap( mappingMetadata.getEntityBindings().size() ); - final Map entityProxyInterfaceMap = CollectionHelper.concurrentMap( mappingMetadata.getEntityBindings().size() ); for ( final PersistentClass model : mappingMetadata.getEntityBindings() ) { final EntityRegionAccessStrategy accessStrategy = sessionFactory.getCache().determineEntityRegionAccessStrategy( model @@ -151,9 +148,6 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable { } } - final Map collectionPersisterMap = new HashMap<>(); - final Map> entityToCollectionRoleMap = new HashMap<>(); - for ( final Collection model : mappingMetadata.getCollectionBindings() ) { final CollectionRegionAccessStrategy accessStrategy = sessionFactory.getCache().determineCollectionRegionAccessStrategy( model @@ -168,28 +162,26 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable { Type indexType = persister.getIndexType(); if ( indexType != null && indexType.isAssociationType() && !indexType.isAnyType() ) { String entityName = ( (AssociationType) indexType ).getAssociatedEntityName( sessionFactory ); - Set roles = entityToCollectionRoleMap.get( entityName ); + Set roles = collectionRolesByEntityParticipant.get( entityName ); if ( roles == null ) { roles = new HashSet<>(); - entityToCollectionRoleMap.put( entityName, roles ); + collectionRolesByEntityParticipant.put( entityName, roles ); } roles.add( persister.getRole() ); } Type elementType = persister.getElementType(); if ( elementType.isAssociationType() && !elementType.isAnyType() ) { String entityName = ( ( AssociationType ) elementType ).getAssociatedEntityName( sessionFactory ); - Set roles = entityToCollectionRoleMap.get( entityName ); + Set roles = collectionRolesByEntityParticipant.get( entityName ); if ( roles == null ) { roles = new HashSet<>(); - entityToCollectionRoleMap.put( entityName, roles ); + collectionRolesByEntityParticipant.put( entityName, roles ); } roles.add( persister.getRole() ); } } - ConcurrentHashMap entityNameResolvers = new ConcurrentHashMap<>(); - - // afterQuery *all* persisters and named queries are registered + // after *all* persisters and named queries are registered entityPersisterMap.values().forEach( EntityPersister::generateEntityDefinition ); for ( EntityPersister persister : entityPersisterMap.values() ) { @@ -211,23 +203,12 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable { } context.wrapUp(); - return new MetamodelImpl( - sessionFactory, - mappingMetadata.getImports(), - entityPersisterMap, - entityProxyInterfaceMap, - entityNameResolvers, - collectionPersisterMap, - entityToCollectionRoleMap, - context.getEntityTypeMap(), - context.getEmbeddableTypeMap(), - context.getMappedSuperclassTypeMap(), - context.getEntityTypesByEntityName() - ); + this.jpaEntityTypeMap.putAll( context.getEntityTypeMap() ); + this.jpaEmbeddableTypeMap.putAll( context.getEmbeddableTypeMap() ); + this.jpaMappedSuperclassTypeMap.putAll( context.getMappedSuperclassTypeMap() ); + this.jpaEntityTypesByEntityName.putAll( context.getEntityTypesByEntityName() ); } - - public java.util.Collection getEntityNameResolvers() { return entityNameResolvers.keySet(); } @@ -330,38 +311,38 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable { return mappedSuperclassType; } - /** - * Instantiate the metamodel. - * - * @param entityNameResolvers - * @param entities The entity mappings. - * @param embeddables The embeddable (component) mappings. - * @param mappedSuperclassTypeMap The {@link javax.persistence.MappedSuperclass} mappings - */ - private MetamodelImpl( - SessionFactoryImplementor sessionFactory, - Map imports, - Map entityPersisterMap, - Map entityProxyInterfaceMap, - ConcurrentHashMap entityNameResolvers, - Map collectionPersisterMap, - Map> collectionRolesByEntityParticipant, - Map, EntityTypeImpl> entities, - Map, EmbeddableTypeImpl> embeddables, - Map, MappedSuperclassType> mappedSuperclassTypeMap, - Map> entityTypesByEntityName) { - this.sessionFactory = sessionFactory; - this.imports = imports; - this.entityPersisterMap = entityPersisterMap; - this.entityProxyInterfaceMap = entityProxyInterfaceMap; - this.entityNameResolvers = entityNameResolvers; - this.collectionPersisterMap = collectionPersisterMap; - this.collectionRolesByEntityParticipant = collectionRolesByEntityParticipant; - this.entities = entities; - this.embeddables = embeddables; - this.mappedSuperclassTypeMap = mappedSuperclassTypeMap; - this.entityTypesByEntityName = entityTypesByEntityName; - } +// /** +// * Instantiate the metamodel. +// * +// * @param entityNameResolvers +// * @param entities The entity mappings. +// * @param embeddables The embeddable (component) mappings. +// * @param mappedSuperclassTypeMap The {@link javax.persistence.MappedSuperclass} mappings +// */ +// private MetamodelImpl( +// SessionFactoryImplementor sessionFactory, +// Map imports, +// Map entityPersisterMap, +// Map entityProxyInterfaceMap, +// ConcurrentHashMap entityNameResolvers, +// Map collectionPersisterMap, +// Map> collectionRolesByEntityParticipant, +// Map, EntityTypeImpl> entities, +// Map, EmbeddableTypeImpl> embeddables, +// Map, MappedSuperclassType> mappedSuperclassTypeMap, +// Map> entityTypesByEntityName) { +// this.sessionFactory = sessionFactory; +// this.imports = imports; +// this.entityPersisterMap = entityPersisterMap; +// this.entityProxyInterfaceMap = entityProxyInterfaceMap; +// this.entityNameResolvers = entityNameResolvers; +// this.collectionPersisterMap = collectionPersisterMap; +// this.collectionRolesByEntityParticipant = collectionRolesByEntityParticipant; +// this.entities = entities; +// this.embeddables = embeddables; +// this.mappedSuperclassTypeMap = mappedSuperclassTypeMap; +// this.entityTypesByEntityName = entityTypesByEntityName; +// } @Override public SessionFactoryImplementor getSessionFactory() { @@ -371,7 +352,7 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable { @Override @SuppressWarnings({"unchecked"}) public EntityType entity(Class cls) { - final EntityType entityType = entities.get( cls ); + final EntityType entityType = jpaEntityTypeMap.get( cls ); if ( entityType == null ) { throw new IllegalArgumentException( "Not an entity: " + cls ); } @@ -381,12 +362,12 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable { @Override @SuppressWarnings({"unchecked"}) public ManagedType managedType(Class cls) { - ManagedType type = entities.get( cls ); + ManagedType type = jpaEntityTypeMap.get( cls ); if ( type == null ) { - type = mappedSuperclassTypeMap.get( cls ); + type = jpaMappedSuperclassTypeMap.get( cls ); } if ( type == null ) { - type = embeddables.get( cls ); + type = jpaEmbeddableTypeMap.get( cls ); } if ( type == null ) { throw new IllegalArgumentException( "Not a managed type: " + cls ); @@ -397,7 +378,7 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable { @Override @SuppressWarnings({"unchecked"}) public EmbeddableType embeddable(Class cls) { - final EmbeddableType embeddableType = embeddables.get( cls ); + final EmbeddableType embeddableType = jpaEmbeddableTypeMap.get( cls ); if ( embeddableType == null ) { throw new IllegalArgumentException( "Not an embeddable: " + cls ); } @@ -407,29 +388,29 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable { @Override public Set> getManagedTypes() { final int setSize = CollectionHelper.determineProperSizing( - entities.size() + mappedSuperclassTypeMap.size() + embeddables.size() + jpaEntityTypeMap.size() + jpaMappedSuperclassTypeMap.size() + jpaEmbeddableTypeMap.size() ); final Set> managedTypes = new HashSet>( setSize ); - managedTypes.addAll( entities.values() ); - managedTypes.addAll( mappedSuperclassTypeMap.values() ); - managedTypes.addAll( embeddables.values() ); + managedTypes.addAll( jpaEntityTypeMap.values() ); + managedTypes.addAll( jpaMappedSuperclassTypeMap.values() ); + managedTypes.addAll( jpaEmbeddableTypeMap.values() ); return managedTypes; } @Override public Set> getEntities() { - return new HashSet<>( entityTypesByEntityName.values() ); + return new HashSet<>( jpaEntityTypesByEntityName.values() ); } @Override public Set> getEmbeddables() { - return new HashSet<>( embeddables.values() ); + return new HashSet<>( jpaEmbeddableTypeMap.values() ); } @Override @SuppressWarnings("unchecked") public EntityType entity(String entityName) { - return (EntityType) entityTypesByEntityName.get( entityName ); + return (EntityType) jpaEntityTypesByEntityName.get( entityName ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/PluralAttributeImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/PluralAttributeImpl.java index 385867d375..cb30c8fecc 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/PluralAttributeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/PluralAttributeImpl.java @@ -103,6 +103,13 @@ public abstract class PluralAttributeImpl } //apply loose rules + if ( collectionClass.isArray() ) { + final Builder, E,?> builder = (Builder, E,?>) this; + return ( PluralAttributeImpl ) new ListAttributeImpl( + builder + ); + } + if ( Map.class.isAssignableFrom( collectionClass ) ) { final Builder,E,K> builder = (Builder,E,K>) this; return ( PluralAttributeImpl ) new MapAttributeImpl( diff --git a/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java b/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java index bfbe0e3950..0e02a348e6 100644 --- a/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/procedure/internal/ProcedureCallImpl.java @@ -17,9 +17,7 @@ import java.util.Map; import java.util.Set; import javax.persistence.ParameterMode; -import org.hibernate.HibernateException; import org.hibernate.QueryException; -import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.engine.ResultSetMappingDefinition; import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; @@ -435,8 +433,13 @@ public class ProcedureCallImpl extends AbstractProducedQuery implements Procedur } @Override - public Type[] getReturnTypes() throws HibernateException { - throw new NotYetImplementedException(); + public String[] getReturnAliases() { + throw new UnsupportedOperationException( "Procedure/function calls do not support returning aliases" ); + } + + @Override + public Type[] getReturnTypes() { + throw new UnsupportedOperationException( "Procedure/function calls do not support returning 'return types'" ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/AbstractProducedQuery.java b/hibernate-core/src/main/java/org/hibernate/query/internal/AbstractProducedQuery.java index a565af8f43..476b07cc44 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/AbstractProducedQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/AbstractProducedQuery.java @@ -39,6 +39,7 @@ import org.hibernate.engine.query.spi.HQLQueryPlan; import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.RowSelection; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.engine.spi.TypedValue; import org.hibernate.hql.internal.QueryExecutionRequestException; import org.hibernate.internal.EntityManagerMessageLogger; import org.hibernate.internal.HEMLogging; @@ -56,6 +57,7 @@ import org.hibernate.property.access.spi.PropertyAccess; import org.hibernate.query.ParameterMetadata; import org.hibernate.query.QueryParameter; import org.hibernate.query.spi.QueryImplementor; +import org.hibernate.query.spi.QueryParameterBinding; import org.hibernate.transform.ResultTransformer; import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.Type; @@ -90,7 +92,7 @@ public abstract class AbstractProducedQuery implements QueryImplementor { private String cacheRegion; private boolean readOnly; - private LockOptions lockOptions; + private LockOptions lockOptions = new LockOptions(); private Integer fetchSize; @@ -99,7 +101,7 @@ public abstract class AbstractProducedQuery implements QueryImplementor { private Map hints; private ResultTransformer resultTransformer; - private RowSelection selection; + private RowSelection selection = new RowSelection(); private HQLQueryPlan entityGraphHintedQueryPlan; private Object optionalObject; @@ -111,7 +113,7 @@ public abstract class AbstractProducedQuery implements QueryImplementor { ParameterMetadata parameterMetadata) { this.producer = producer; this.parameterMetadata = parameterMetadata; - this.queryParameterBindings = QueryParameterBindingsImpl.from( parameterMetadata ); + this.queryParameterBindings = QueryParameterBindingsImpl.from( parameterMetadata, producer.getFactory() ); } @Override @@ -930,7 +932,9 @@ public abstract class AbstractProducedQuery implements QueryImplementor { public QueryParameters getQueryParameters() { QueryParameters queryParameters = new QueryParameters( - queryParameterBindings, + getPositionalParameterTypes(), + getPositionalParameterValues(), + getNamedParameterMap(), getLockOptions(), selection, true, @@ -949,10 +953,27 @@ public abstract class AbstractProducedQuery implements QueryImplementor { return queryParameters; } + @SuppressWarnings("deprecation") + protected Type[] getPositionalParameterTypes() { + return queryParameterBindings.collectPositionalBindTypes(); + } + + @SuppressWarnings("deprecation") + protected Object[] getPositionalParameterValues() { + return queryParameterBindings.collectPositionalBindValues(); + } + + @SuppressWarnings("deprecation") + protected Map getNamedParameterMap() { + return queryParameterBindings.collectNamedParameterBindings(); + } + private FlushMode sessionFlushMode; private CacheMode sessionCacheMode; protected void beforeQuery() { + queryParameterBindings.verifyParametersBound( isCallable() ); + assert sessionFlushMode == null; assert sessionCacheMode == null; @@ -980,7 +1001,6 @@ public abstract class AbstractProducedQuery implements QueryImplementor { @Override @SuppressWarnings("unchecked") public Iterator iterate() { - queryParameterBindings.verifyParametersBound( false ); beforeQuery(); try { return getProducer().iterate( @@ -995,22 +1015,11 @@ public abstract class AbstractProducedQuery implements QueryImplementor { @Override public ScrollableResults scroll() { - queryParameterBindings.verifyParametersBound( false ); - beforeQuery(); - try { - return getProducer().scroll( - queryParameterBindings.expandListValuedParameters( getQueryString(), getProducer() ), - getQueryParameters() - ); - } - finally { - afterQuery(); - } + return scroll( getProducer().getJdbcServices().getJdbcEnvironment().getDialect().defaultScrollMode() ); } @Override public ScrollableResults scroll(ScrollMode scrollMode) { - queryParameterBindings.verifyParametersBound( false ); beforeQuery(); try { QueryParameters queryParameters = getQueryParameters(); @@ -1026,15 +1035,10 @@ public abstract class AbstractProducedQuery implements QueryImplementor { } @Override - @SuppressWarnings("unchecked") public List list() { - queryParameterBindings.verifyParametersBound( false ); beforeQuery(); try { - return getProducer().list( - queryParameterBindings.expandListValuedParameters( getQueryString(), getProducer() ), - getQueryParameters() - ); + return doList(); } catch (QueryExecutionRequestException he) { throw new IllegalStateException( he ); @@ -1050,6 +1054,22 @@ public abstract class AbstractProducedQuery implements QueryImplementor { } } + protected boolean isCallable() { + return false; + } + + @SuppressWarnings("unchecked") + protected List doList() { + return getProducer().list( + queryParameterBindings.expandListValuedParameters( getQueryString(), getProducer() ), + getQueryParameters() + ); + } + + public QueryParameterBindingsImpl getQueryParameterBindings() { + return queryParameterBindings; + } + @Override public R uniqueResult() { return uniqueElement( list() ); @@ -1071,19 +1091,22 @@ public abstract class AbstractProducedQuery implements QueryImplementor { @Override public int executeUpdate() throws HibernateException { - queryParameterBindings.verifyParametersBound( false ); beforeQuery(); try { - return getProducer().executeUpdate( - queryParameterBindings.expandListValuedParameters( getQueryString(), getProducer() ), - getQueryParameters() - ); + return doExecuteUpdate(); } finally { afterQuery(); } } + protected int doExecuteUpdate() { + return getProducer().executeUpdate( + queryParameterBindings.expandListValuedParameters( getQueryString(), getProducer() ), + getQueryParameters() + ); + } + protected String resolveEntityName(Object val) { if ( val == null ) { throw new IllegalArgumentException( "entity for parameter binding cannot be null" ); @@ -1105,4 +1128,21 @@ public abstract class AbstractProducedQuery implements QueryImplementor { public void setOptionalObject(Object optionalObject) { this.optionalObject = optionalObject; } + + @Override + @SuppressWarnings("unchecked") + public Type determineProperBooleanType(String name, Object value, Type defaultType) { + final QueryParameterBinding binding = getQueryParameterBindings().getBinding( name ); + return binding.getBindType() != null + ? binding.getBindType() + : defaultType; + } + + @Override + public Type determineProperBooleanType(int position, Object value, Type defaultType) { + final QueryParameterBinding binding = getQueryParameterBindings().getBinding( position ); + return binding.getBindType() != null + ? binding.getBindType() + : defaultType; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/CollectionFilterImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/CollectionFilterImpl.java index 76cb37fb76..8bc5086df2 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/CollectionFilterImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/CollectionFilterImpl.java @@ -6,7 +6,11 @@ */ package org.hibernate.query.internal; +import java.util.Iterator; +import java.util.List; + import org.hibernate.HibernateException; +import org.hibernate.ScrollMode; import org.hibernate.ScrollableResults; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.query.Query; @@ -41,16 +45,66 @@ public class CollectionFilterImpl extends org.hibernate.query.internal.AbstractP return queryString; } + @Override + public Iterator iterate() throws HibernateException { + getQueryParameterBindings().verifyParametersBound( false ); + return getProducer().iterateFilter( + collection, + getQueryParameterBindings().expandListValuedParameters( getQueryString(), getProducer() ), + getQueryParameters() + ); + } + + @Override + public List list() throws HibernateException { + getQueryParameterBindings().verifyParametersBound( false ); + return getProducer().listFilter( + collection, + getQueryParameterBindings().expandListValuedParameters( getQueryString(), getProducer() ), + getQueryParameters() + ); + } + + @Override + public ScrollableResults scroll() throws HibernateException { + throw new UnsupportedOperationException( "Can't scroll filters" ); + } + + @Override + public ScrollableResults scroll(ScrollMode scrollMode) { + throw new UnsupportedOperationException( "Can't scroll filters" ); + } + + @Override + protected Type[] getPositionalParameterTypes() { + final Type[] explicitParameterTypes = super.getPositionalParameterTypes(); + final Type[] expandedParameterTypes = new Type[ explicitParameterTypes.length + 1 ]; + + // previously this logic would only add an additional slot in the array, not fill it. carry that logic here, for now + System.arraycopy( explicitParameterTypes, 0, expandedParameterTypes, 1, explicitParameterTypes.length ); + + return expandedParameterTypes; + } + + @SuppressWarnings("deprecation") + protected Object[] getPositionalParameterValues() { + final Object[] explicitParameterValues = super.getPositionalParameterValues(); + final Object[] expandedParameterValues = new Object[ explicitParameterValues.length + 1 ]; + + // previously this logic would only add an additional slot in the array, not fill it. carry that logic here, for now + System.arraycopy( explicitParameterValues, 0, expandedParameterValues, 1, explicitParameterValues.length ); + + return expandedParameterValues; + } + @Override public Type[] getReturnTypes() { return getProducer().getFactory().getReturnTypes( getQueryString() ); } - /** - * @see org.hibernate.Query#scroll() - */ - public ScrollableResults scroll() throws HibernateException { - throw new UnsupportedOperationException( "Can't scroll filters" ); + @Override + public String[] getReturnAliases() { + return getProducer().getFactory().getReturnAliases( getQueryString() ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/NativeQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/NativeQueryImpl.java index 12028c0c97..dda3f17821 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/NativeQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/NativeQueryImpl.java @@ -26,8 +26,10 @@ import org.hibernate.LockOptions; import org.hibernate.MappingException; import org.hibernate.QueryException; import org.hibernate.engine.ResultSetMappingDefinition; +import org.hibernate.engine.query.spi.sql.NativeSQLQueryConstructorReturn; import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn; import org.hibernate.engine.query.spi.sql.NativeSQLQueryScalarReturn; +import org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification; import org.hibernate.engine.spi.NamedSQLQueryDefinition; import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SharedSessionContractImplementor; @@ -98,6 +100,7 @@ public class NativeQueryImpl extends AbstractProducedQuery implements Na ParameterMetadata sqlParameterMetadata) { super( session, sqlParameterMetadata ); + this.queryReturns = new ArrayList<>(); this.sqlString = sqlString; this.callable = callable; this.querySpaces = new ArrayList<>(); @@ -130,10 +133,31 @@ public class NativeQueryImpl extends AbstractProducedQuery implements Na return queryReturns; } + @Override + @SuppressWarnings("unchecked") + protected List doList() { + return getProducer().list( + generateQuerySpecification(), + getQueryParameters() + ); + } + + private NativeSQLQuerySpecification generateQuerySpecification() { + return new NativeSQLQuerySpecification( + getQueryParameterBindings().expandListValuedParameters( getQueryString(), getProducer() ), + queryReturns.toArray( new NativeSQLQueryReturn[queryReturns.size()] ), + querySpaces + ); + } + @Override public QueryParameters getQueryParameters() { final QueryParameters queryParameters = super.getQueryParameters(); - queryParameters.setCollectionKeys( new Serializable[] {collectionKey} ); + queryParameters.setCallable( callable ); + queryParameters.setAutoDiscoverScalarTypes( autoDiscoverTypes ); + if ( collectionKey != null ) { + queryParameters.setCollectionKeys( new Serializable[] {collectionKey} ); + } return queryParameters; } @@ -156,6 +180,27 @@ public class NativeQueryImpl extends AbstractProducedQuery implements Na @Override protected void beforeQuery() { + prepareQueryReturnsIfNecessary(); + boolean noReturns = queryReturns == null || queryReturns.isEmpty(); + if ( noReturns ) { + this.autoDiscoverTypes = true; + } + else { + for ( NativeSQLQueryReturn queryReturn : queryReturns ) { + if ( queryReturn instanceof NativeSQLQueryScalarReturn ) { + NativeSQLQueryScalarReturn scalar = (NativeSQLQueryScalarReturn) queryReturn; + if ( scalar.getType() == null ) { + autoDiscoverTypes = true; + break; + } + } + else if ( NativeSQLQueryConstructorReturn.class.isInstance( queryReturn ) ) { + autoDiscoverTypes = true; + break; + } + } + } + super.beforeQuery(); if ( getSynchronizedQuerySpaces() != null && !getSynchronizedQuerySpaces().isEmpty() ) { @@ -167,9 +212,19 @@ public class NativeQueryImpl extends AbstractProducedQuery implements Na // otherwise we need to flush. the query itself is not required to execute in a transaction; if there is // no transaction, the flush would throw a TransactionRequiredException which would potentially break existing // apps, so we only do the flush if a transaction is in progress. + // + // NOTE : this was added for JPA initially. Perhaps we want to only do this from JPA usage? if ( getProducer().isTransactionInProgress() ) { getProducer().flush(); } + + } + + protected int doExecuteUpdate() { + return getProducer().executeNativeUpdate( + generateQuerySpecification(), + getQueryParameters() + ); } @Override @@ -315,6 +370,15 @@ public class NativeQueryImpl extends AbstractProducedQuery implements Na return this; } + protected void addQuerySpaces(String... spaces) { + if ( spaces != null ) { + if ( querySpaces == null ) { + querySpaces = new ArrayList<>(); + } + querySpaces.addAll( Arrays.asList( (String[]) spaces ) ); + } + } + protected void addQuerySpaces(Serializable... spaces) { if ( spaces != null ) { if ( querySpaces == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryImpl.java index e0822cfc28..f084b241a5 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryImpl.java @@ -30,11 +30,21 @@ public class QueryImpl extends AbstractProducedQuery implements Query { return queryString; } + @Override + protected boolean isNativeQuery() { + return false; + } + @Override public Type[] getReturnTypes() { return getProducer().getFactory().getReturnTypes( queryString ); } + @Override + public String[] getReturnAliases() { + return getProducer().getFactory().getReturnAliases( queryString ); + } + @Override public Query setEntity(int position, Object val) { return setParameter( position, val, getProducer().getFactory().getTypeHelper().entity( resolveEntityName( val ) ) ); @@ -44,9 +54,4 @@ public class QueryImpl extends AbstractProducedQuery implements Query { public Query setEntity(String name, Object val) { return setParameter( name, val, getProducer().getFactory().getTypeHelper().entity( resolveEntityName( val ) ) ); } - - @Override - protected boolean isNativeQuery() { - return false; - } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingImpl.java index 6b3cf11e9b..6169597ee8 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingImpl.java @@ -9,17 +9,21 @@ package org.hibernate.query.internal; import javax.persistence.TemporalType; import org.hibernate.query.spi.QueryParameterBinding; +import org.hibernate.query.spi.QueryParameterBindingTypeResolver; import org.hibernate.type.Type; /** * @author Steve Ebersole */ public class QueryParameterBindingImpl implements QueryParameterBinding { + private final QueryParameterBindingTypeResolver typeResolver; + private Type bindType; private T bindValue; - public QueryParameterBindingImpl(Type type) { + public QueryParameterBindingImpl(Type type, QueryParameterBindingTypeResolver typeResolver) { this.bindType = type; + this.typeResolver = typeResolver; } @Override @@ -34,10 +38,11 @@ public class QueryParameterBindingImpl implements QueryParameterBinding { @Override public void setBindValue(T value) { - if ( value == null ) { - throw new IllegalArgumentException( "Cannot bind null to query parameter" ); - } this.bindValue = value; + + if ( bindType == null ) { + this.bindType = typeResolver.resolveParameterBindType( value ); + } } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingsImpl.java b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingsImpl.java index 4ae675a876..dc46da4a2e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/internal/QueryParameterBindingsImpl.java @@ -6,14 +6,13 @@ */ package org.hibernate.query.internal; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; -import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeMap; import java.util.stream.Collectors; import org.hibernate.HibernateException; @@ -21,6 +20,8 @@ import org.hibernate.Incubating; import org.hibernate.QueryException; import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.engine.query.spi.NamedParameterDescriptor; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.TypedValue; import org.hibernate.hql.internal.classic.ParserHelper; @@ -32,6 +33,7 @@ import org.hibernate.query.QueryParameter; import org.hibernate.query.spi.QueryParameterBinding; import org.hibernate.query.spi.QueryParameterBindings; import org.hibernate.query.spi.QueryParameterListBinding; +import org.hibernate.type.SerializableType; import org.hibernate.type.Type; /** @@ -43,18 +45,27 @@ import org.hibernate.type.Type; public class QueryParameterBindingsImpl implements QueryParameterBindings { private static final CoreMessageLogger log = CoreLogging.messageLogger( QueryParameterBindingsImpl.class ); + private final SessionFactoryImplementor sessionFactory; + private Map parameterBindingMap; private Map parameterListBindingMap; - public static QueryParameterBindingsImpl from(ParameterMetadata parameterMetadata) { - return new QueryParameterBindingsImpl( parameterMetadata.collectAllParameters() ); + public static QueryParameterBindingsImpl from(ParameterMetadata parameterMetadata, SessionFactoryImplementor sessionFactory) { + if ( parameterMetadata == null ) { + return new QueryParameterBindingsImpl( sessionFactory ); + } + else { + return new QueryParameterBindingsImpl( sessionFactory, parameterMetadata.collectAllParameters() ); + } } - public QueryParameterBindingsImpl() { - this( Collections.emptySet() ); + public QueryParameterBindingsImpl(SessionFactoryImplementor sessionFactory) { + this( sessionFactory, Collections.emptySet() ); } - public QueryParameterBindingsImpl(Set> queryParameters) { + public QueryParameterBindingsImpl(SessionFactoryImplementor sessionFactory, Set> queryParameters) { + this.sessionFactory = sessionFactory; + if ( queryParameters == null || queryParameters.isEmpty() ) { parameterBindingMap = Collections.emptyMap(); } @@ -69,8 +80,12 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings { parameterListBindingMap = new HashMap<>(); } - protected QueryParameterBindingImpl makeBinding(QueryParameter queryParameter) { - return new QueryParameterBindingImpl( queryParameter.getType() ); + protected QueryParameterBinding makeBinding(QueryParameter queryParameter) { + return makeBinding( queryParameter.getType() ); + } + + protected QueryParameterBinding makeBinding(Type bindType) { + return new QueryParameterBindingImpl( bindType, sessionFactory ); } public boolean isBound(QueryParameter parameter) { @@ -220,19 +235,42 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings { */ @Deprecated public Type[] collectPositionalBindTypes() { - List types = new ArrayList<>(); + TreeMap positionalParameterBindingMap = collectPositionalParameterBindings(); + Type[] types = new Type[ positionalParameterBindingMap.size() ]; + + // NOTE : bindings should be ordered by position by nature of a TreeMap... + // NOTE : we also assume the contiguity of the positions + + for ( Map.Entry entry : positionalParameterBindingMap.entrySet() ) { + final int position = entry.getKey(); + + Type type = entry.getValue().getBindType(); + if ( type == null ) { + log.debugf( "Binding for positional-parameter [%s] did not define type, using SerializableType", position ); + type = SerializableType.INSTANCE; + } + + types[ position ] = type; + } + + return types; + } + + private TreeMap collectPositionalParameterBindings() { + final TreeMap bindings = new TreeMap<>(); + for ( Map.Entry entry : parameterBindingMap.entrySet() ) { if ( entry.getKey().getPosition() == null ) { continue; } - Type type = entry.getValue().getBindType(); + final int position = entry.getKey().getPosition(); // these should be contiguous - types.add( entry.getKey().getPosition(), type ); + bindings.put( position, entry.getValue() ); } - return types.toArray( new Type[ types.size() ] ); + return bindings; } /** @@ -240,17 +278,18 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings { */ @Deprecated public Object[] collectPositionalBindValues() { - List values = new ArrayList<>(); - for ( Map.Entry entry : parameterBindingMap.entrySet() ) { - if ( entry.getKey().getPosition() == null ) { - continue; - } + TreeMap positionalParameterBindingMap = collectPositionalParameterBindings(); + Object[] values = new Object[ positionalParameterBindingMap.size() ]; - // these should be contiguous - values.add( entry.getKey().getPosition(), entry.getValue().getBindValue() ); + // NOTE : bindings should be ordered by position by nature of a TreeMap... + // NOTE : we also assume the contiguity of the positions + + for ( Map.Entry entry : positionalParameterBindingMap.entrySet() ) { + final int position = entry.getKey(); + values[ position ] = entry.getValue().getBindValue(); } - return values.toArray( new Object[ values.size() ] ); + return values; } /** @@ -264,12 +303,15 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings { continue; } + Type bindType = entry.getValue().getBindType(); + if ( bindType == null ) { + log.debugf( "Binding for named-parameter [%s] did not define type", entry.getKey().getName() ); + bindType = SerializableType.INSTANCE; + } + collectedBindings.put( entry.getKey().getName(), - new TypedValue( - entry.getValue().getBindType(), - entry.getValue().getBindValue() - ) + new TypedValue( bindType, entry.getValue().getBindValue() ) ); } @@ -416,7 +458,7 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings { final int inExprLimit = dialect.getInExpressionCountLimit(); for ( Map.Entry entry : parameterListBindingMap.entrySet() ) { - final QueryParameterNamedImpl sourceParam = (QueryParameterNamedImpl) entry.getKey(); + final NamedParameterDescriptor sourceParam = (NamedParameterDescriptor) entry.getKey(); final Collection bindValues = entry.getValue().getBindValues(); if ( inExprLimit > 0 && bindValues.size() > inExprLimit ) { @@ -444,7 +486,7 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings { if ( bindValues.size() == 1 && isEnclosedInParens ) { // short-circuit for performance when only 1 value and the // placeholder is already enclosed in parentheses... - final QueryParameterBinding syntheticBinding = new QueryParameterBindingImpl( entry.getValue().getBindType() ); + final QueryParameterBinding syntheticBinding = makeBinding( entry.getValue().getBindType() ); syntheticBinding.setBindValue( bindValues.iterator().next() ); parameterBindingMap.put( sourceParam, syntheticBinding ); continue; @@ -469,7 +511,7 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings { sourceParam.isJpaPositionalParameter(), sourceParam.getType() ); - final QueryParameterBinding syntheticBinding = new QueryParameterBindingImpl( entry.getValue().getBindType() ); + final QueryParameterBinding syntheticBinding = makeBinding( entry.getValue().getBindType() ); syntheticBinding.setBindValue( bindValue ); if ( parameterBindingMap.put( syntheticParam, syntheticBinding ) != null ) { throw new HibernateException( "Repeated usage of synthetic parameter name [" + syntheticName + "] while expanding list parameter." ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/procedure/internal/StoredProcedureQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/procedure/internal/StoredProcedureQueryImpl.java index 6f3f419d67..c0ecc1ba76 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/procedure/internal/StoredProcedureQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/procedure/internal/StoredProcedureQueryImpl.java @@ -144,6 +144,11 @@ public class StoredProcedureQueryImpl extends AbstractProducedQuery impl return procedureCall.getReturnTypes(); } + @Override + public String[] getReturnAliases() { + throw new UnsupportedOperationException( "Procedure/function calls do not support returning aliases" ); + } + @Override protected boolean applyTimeoutHint(int timeout) { procedureCall.setTimeout( timeout ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/spi/QueryParameterBindingTypeResolver.java b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryParameterBindingTypeResolver.java new file mode 100644 index 0000000000..b08eb7a39c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/spi/QueryParameterBindingTypeResolver.java @@ -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 . + */ +package org.hibernate.query.spi; + +import org.hibernate.type.Type; + +/** + * A resolver for Type based on a parameter value being bound, when no + * explicit type information is supplied. + * + * @author Steve Ebersole + */ +public interface QueryParameterBindingTypeResolver { + Type resolveParameterBindType(Object bindValue); +} diff --git a/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentStatisticsImpl.java b/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentStatisticsImpl.java index 8ea86f89f9..d220c36058 100644 --- a/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentStatisticsImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/stat/internal/ConcurrentStatisticsImpl.java @@ -301,15 +301,27 @@ public class ConcurrentStatisticsImpl implements StatisticsImplementor, Service final EntityRegionAccessStrategy entityRegionAccess = sessionFactory.getCache().getEntityRegionAccess( regionName ); final CollectionRegionAccessStrategy collectionRegionAccess = sessionFactory.getCache().getCollectionRegionAccess( regionName ); + if ( entityRegionAccess == null && collectionRegionAccess == null ) { - return null; + final Region region = sessionFactory.getCache().getQueryCache( regionName ).getRegion(); + if ( region == null ) { + throw new IllegalArgumentException( "Could not resolve region name [" + regionName + "]" ); + } + stat = new ConcurrentSecondLevelCacheStatisticsImpl( region, null, null ); + } + else { + + final Region region = entityRegionAccess != null + ? entityRegionAccess.getRegion() + : collectionRegionAccess.getRegion(); + + stat = new ConcurrentSecondLevelCacheStatisticsImpl( + region, + entityRegionAccess, + collectionRegionAccess + ); } - final Region region = entityRegionAccess != null - ? entityRegionAccess.getRegion() - : collectionRegionAccess.getRegion(); - - stat = new ConcurrentSecondLevelCacheStatisticsImpl( region, entityRegionAccess, collectionRegionAccess ); ConcurrentSecondLevelCacheStatisticsImpl previous; if ( ( previous = secondLevelCacheStatistics.putIfAbsent( regionName, stat ) ) != null ) { stat = previous; diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java index 0b688d6b76..878f575ccf 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java @@ -31,7 +31,7 @@ import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.mapping.Component; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; -import org.hibernate.persister.entity.AbstractEntityPersister; +import org.hibernate.persister.entity.EntityPersister; import org.hibernate.tuple.GenerationTiming; import org.hibernate.tuple.IdentifierProperty; import org.hibernate.tuple.InDatabaseValueGenerationStrategy; @@ -58,11 +58,10 @@ public class EntityMetamodel implements Serializable { private static final int NO_VERSION_INDX = -66; private final SessionFactoryImplementor sessionFactory; - private final AbstractEntityPersister persister; private final String name; private final String rootName; - private final EntityType entityType; + private EntityType entityType; private final IdentifierProperty identifierAttribute; private final boolean versioned; @@ -126,14 +125,12 @@ public class EntityMetamodel implements Serializable { public EntityMetamodel( PersistentClass persistentClass, - AbstractEntityPersister persister, + EntityPersister persister, SessionFactoryImplementor sessionFactory) { this.sessionFactory = sessionFactory; - this.persister = persister; name = persistentClass.getEntityName(); rootName = persistentClass.getRootClass().getEntityName(); - entityType = sessionFactory.getTypeResolver().getTypeFactory().manyToOne( name ); identifierAttribute = PropertyFactory.buildIdentifierAttribute( persistentClass, @@ -889,6 +886,9 @@ public class EntityMetamodel implements Serializable { } public EntityType getEntityType() { + if ( entityType == null ) { + entityType = sessionFactory.getTypeResolver().getTypeFactory().manyToOne( name ); + } return entityType; } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptionsContext.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptionsContext.java index 802f1b03ca..0d354b499e 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptionsContext.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/WrapperOptionsContext.java @@ -11,7 +11,7 @@ package org.hibernate.type.descriptor; * * @author Steve Ebersole * - * @deprecated (since 6.0) Just directly implement WrapperOptions + * @deprecated (since 5.2) Just directly implement WrapperOptions */ @Deprecated public interface WrapperOptionsContext extends WrapperOptions { @@ -20,7 +20,7 @@ public interface WrapperOptionsContext extends WrapperOptions { * * @return The WrapperOptions * - * @deprecated (since 6.0) Just directly implement WrapperOptions + * @deprecated (since 5.2) Just directly implement WrapperOptions */ @Deprecated default WrapperOptions getWrapperOptions() { diff --git a/hibernate-core/src/test/java/org/hibernate/test/converter/literal/QueryLiteralTest.java b/hibernate-core/src/test/java/org/hibernate/test/converter/literal/QueryLiteralTest.java index ff3f413d83..74ca2aad85 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/converter/literal/QueryLiteralTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/converter/literal/QueryLiteralTest.java @@ -24,6 +24,7 @@ import org.hibernate.Session; import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; import org.junit.Test; +import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -64,7 +65,8 @@ public class QueryLiteralTest extends BaseNonConfigCoreFunctionalTestCase { find( entity.getId(), "e.integerWrapper='10'" ); fail("Should throw QueryException!"); } - catch (QueryException e) { + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); assertTrue( e.getMessage().contains( "AttributeConverter domain-model attribute type [org.hibernate.test.converter.literal.QueryLiteralTest$IntegerWrapper] and JDBC type [java.lang.Integer] did not match query literal type [java.lang.String]" ) ); } } @@ -93,8 +95,7 @@ public class QueryLiteralTest extends BaseNonConfigCoreFunctionalTestCase { assertEquals( "HUNDRED", entity.getSameTypeConverter() ); Session session = openSession(); - String value = (String) session.createSQLQuery( - "select e.same_type_converter from entity_converter e where e.id=:id" ) + String value = (String) session.createSQLQuery( "select e.same_type_converter from entity_converter e where e.id=:id" ) .setParameter( "id", entity.getId() ) .uniqueResult(); assertEquals( "VALUE_HUNDRED", value ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/cuk/CompositePropertyRefTest.java b/hibernate-core/src/test/java/org/hibernate/test/cuk/CompositePropertyRefTest.java index 63b0872233..f3f79dcdfa 100755 --- a/hibernate-core/src/test/java/org/hibernate/test/cuk/CompositePropertyRefTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/cuk/CompositePropertyRefTest.java @@ -5,17 +5,18 @@ * See the lgpl.txt file in the root directory or . */ package org.hibernate.test.cuk; + import java.util.List; import java.util.Set; -import org.junit.Test; - import org.hibernate.Hibernate; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; + import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -62,8 +63,8 @@ public class CompositePropertyRefTest extends BaseCoreFunctionalTestCase { s.flush(); s.clear(); - p = (Person) s.get( Person.class, p.getId() ); //get address reference by outer join - p2 = (Person) s.get( Person.class, p2.getId() ); //get null address reference by outer join + p = s.get( Person.class, p.getId() ); //get address reference by outer join + p2 = s.get( Person.class, p2.getId() ); //get null address reference by outer join assertNull( p2.getAddress() ); assertNotNull( p.getAddress() ); List l = s.createQuery("from Person").list(); //pull address references for cache diff --git a/hibernate-core/src/test/java/org/hibernate/test/flush/TestClearBatchFetchQueueAfterFlush.java b/hibernate-core/src/test/java/org/hibernate/test/flush/TestClearBatchFetchQueueAfterFlush.java index a63b23523b..9f28d23724 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/flush/TestClearBatchFetchQueueAfterFlush.java +++ b/hibernate-core/src/test/java/org/hibernate/test/flush/TestClearBatchFetchQueueAfterFlush.java @@ -11,6 +11,7 @@ import java.util.Iterator; import org.hibernate.Session; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; + import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.junit.Test; @@ -57,16 +58,14 @@ public class TestClearBatchFetchQueueAfterFlush extends BaseCoreFunctionalTestCa s.getTransaction().commit(); s.clear(); - bookStore1 = (BookStore) s.load( BookStore.class, bookStore1.getId() ); - bookStore2 = (BookStore) s.load( BookStore.class, bookStore2.getId() ); - bookStore3 = (BookStore) s.load( BookStore.class, bookStore3.getId() ); + bookStore1 = s.load( BookStore.class, bookStore1.getId() ); + bookStore2 = s.load( BookStore.class, bookStore2.getId() ); + bookStore3 = s.load( BookStore.class, bookStore3.getId() ); s.beginTransaction(); s.delete( bookStore2 ); s.getTransaction().commit(); - s.flush(); - bookStore1.getBooks().size(); bookStore3.getBooks().size(); } diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/ASTParserLoadingTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/ASTParserLoadingTest.java index 9027147fda..5ceb00ab5d 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/ASTParserLoadingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/ASTParserLoadingTest.java @@ -48,6 +48,7 @@ import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.TeradataDialect; import org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory; import org.hibernate.internal.util.StringHelper; +import org.hibernate.loader.MultipleBagFetchException; import org.hibernate.persister.entity.DiscriminatorType; import org.hibernate.stat.QueryStatistics; import org.hibernate.transform.DistinctRootEntityResultTransformer; @@ -77,6 +78,7 @@ import org.junit.Test; import org.jboss.logging.Logger; import static org.hibernate.testing.junit4.ExtraAssertions.assertClassAssignability; +import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -103,7 +105,8 @@ import static org.junit.Assert.fail; public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase { private static final Logger log = Logger.getLogger( ASTParserLoadingTest.class ); - private List createdAnimalIds = new ArrayList(); + private List createdAnimalIds = new ArrayList<>(); + @Override protected boolean isCleanupTestDataRequired() { return true; @@ -858,6 +861,9 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase { s.createQuery( "from Animal a where a.offspring.description = 'xyz'" ).list(); fail( "illegal collection dereference semantic did not cause failure" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( QueryException qe ) { log.trace("expected failure...", qe); } @@ -866,6 +872,9 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase { s.createQuery( "from Animal a where a.offspring.father.description = 'xyz'" ).list(); fail( "illegal collection dereference semantic did not cause failure" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( QueryException qe ) { log.trace("expected failure...", qe); } @@ -874,6 +883,9 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase { s.createQuery( "from Animal a order by a.offspring.description" ).list(); fail( "illegal collection dereference semantic did not cause failure" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( QueryException qe ) { log.trace("expected failure...", qe); } @@ -882,6 +894,9 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase { s.createQuery( "from Animal a order by a.offspring.father.description" ).list(); fail( "illegal collection dereference semantic did not cause failure" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( QueryException qe ) { log.trace("expected failure...", qe); } @@ -1562,6 +1577,9 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase { query.list(); fail( "query execution should have failed" ); } + catch (IllegalArgumentException e) { + assertTyping( TypeMismatchException.class, e.getCause() ); + } catch( TypeMismatchException tme ) { // expected behavior } @@ -1578,6 +1596,9 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase { s.createQuery( "from Human h join fetch h.friends f join fetch f.friends fof" ).list(); fail( "failure expected" ); } + catch (IllegalArgumentException e) { + assertTyping( MultipleBagFetchException.class, e.getCause() ); + } catch( HibernateException e ) { assertTrue( "unexpected failure reason : " + e, e.getMessage().indexOf( "multiple bags" ) > 0 ); } @@ -1688,6 +1709,9 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase { s.createQuery( "from Animal a where a.mother in (select m from Animal a1 inner join a1.mother as m join fetch m.mother)" ).list(); fail( "fetch join allowed in subquery" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( QueryException expected ) { // expected behavior } @@ -1860,6 +1884,9 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase { s.createQuery( "select mother from Human a left join fetch a.mother mother" ).list(); fail( "invalid fetch semantic allowed!" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( QueryException e ) { } @@ -1867,6 +1894,9 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase { s.createQuery( "select mother from Human a left join fetch a.mother mother" ).list(); fail( "invalid fetch semantic allowed!" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( QueryException e ) { } @@ -2885,7 +2915,7 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase { Transaction txn = session.beginTransaction(); for ( Long createdAnimalId : createdAnimalIds ) { - Animal animal = (Animal) session.load( Animal.class, createdAnimalId ); + Animal animal = session.load( Animal.class, createdAnimalId ); session.delete( animal ); } @@ -3487,21 +3517,33 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase { try { getSelectNewQuery( session ).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list(); fail("'select new' together with a resulttransformer should result in error!"); - } catch(QueryException he) { + } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } + catch(QueryException he) { assertTrue(he.getMessage().indexOf("ResultTransformer")==0); } try { getSelectNewQuery( session ).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).iterate(); fail("'select new' together with a resulttransformer should result in error!"); - } catch(HibernateException he) { + } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } + catch(HibernateException he) { assertTrue(he.getMessage().indexOf("ResultTransformer")==0); } try { getSelectNewQuery( session ).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).scroll(); fail("'select new' together with a resulttransformer should result in error!"); - } catch(HibernateException he) { + } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } + catch(HibernateException he) { assertTrue(he.getMessage().indexOf("ResultTransformer")==0); } t.commit(); @@ -3624,7 +3666,6 @@ public class ASTParserLoadingTest extends BaseCoreFunctionalTestCase { assertTrue( "Incorrect result size", sr.next() ); assertTrue( "Incorrect return type", sr.get(0) instanceof Map ); - assertFalse( session.contains( sr.get( 0 ) ) ); sr.close(); t.commit(); diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/BulkManipulationTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/BulkManipulationTest.java index ae8a61326f..bb471057b7 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/BulkManipulationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/BulkManipulationTest.java @@ -38,6 +38,7 @@ import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.junit.Test; import junit.framework.AssertionFailedError; +import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -90,6 +91,9 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase { s.createQuery( "delete NonExistentEntity" ).executeUpdate(); fail( "no exception thrown" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( QueryException ignore ) { } @@ -106,6 +110,9 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase { s.createQuery( "update NonExistentEntity e set e.someProp = ?" ).executeUpdate(); fail( "no exception thrown" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( QueryException e ) { } @@ -210,9 +217,14 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase { try { s.createQuery("select :someParameter, id from Car"); fail("Should throw an unsupported exception"); - } catch(QueryException q) { + } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } + catch(QueryException q) { // allright - } finally { + } + finally { s.close(); } } @@ -287,7 +299,11 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase { try { org.hibernate.Query q1 = s.createQuery( "insert into Pickup (id, owner, vin) select :id, (select :description from Animal a where a.description = :description), :vin from Car" ); fail("Unsupported exception should have been thrown"); - } catch(QueryException e) { + } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } + catch(QueryException e) { assertTrue(e.getMessage().indexOf("Use of parameters in subqueries of INSERT INTO DML statements is not supported.") > -1); } @@ -309,9 +325,10 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase { try { org.hibernate.Query q = s.createQuery( "insert into Pickup (id, owner, vin) select id, :owner, id from Car" ); fail("Parameter type mismatch but no exception thrown"); - } catch (Throwable throwable) { - assertTrue(throwable instanceof QueryException); - String m = throwable.getMessage(); + } + catch (Throwable throwable) { + QueryException queryException = assertTyping( QueryException.class, throwable.getCause() ); + String m = queryException.getMessage(); // insertion type [org.hibernate.type.StringType@21e3cc77] and selection type [org.hibernate.type.LongType@7284aa02] at position 2 are not compatible [insert into Pickup (id, owner, vin) select id, :owner, id from org.hibernate.test.hql.Car] int st = m.indexOf("org.hibernate.type.StringType"); int lt = m.indexOf("org.hibernate.type.LongType"); @@ -319,7 +336,8 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase { assertTrue("type causing error not reported", lt > -1); assertTrue(lt > st); assertTrue("wrong position of type error reported", m.indexOf("position 2") > -1); - } finally { + } + finally { s.close(); } } @@ -343,7 +361,8 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase { t.commit(); t = s.beginTransaction(); - s.createSQLQuery( "delete from Truck" ).executeUpdate(); + int deleteCount = s.createSQLQuery( "delete from Truck" ).executeUpdate(); + assertEquals( 1, deleteCount ); l = s.createQuery("from Vehicle").list(); assertEquals(l.size(),4); @@ -407,6 +426,9 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase { s.createQuery( "insert into Pickup (owner, vin, id) select id, vin, owner from Car" ).executeUpdate(); fail( "mismatched types did not error" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( QueryException e ) { // expected result } @@ -434,6 +456,9 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase { s.createQuery( "insert into Human (id, bodyWeight) select id, bodyWeight from Lizard" ).executeUpdate(); fail( "superclass prop insertion did not error" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( QueryException e ) { // expected result } @@ -463,6 +488,9 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase { s.createQuery( "insert into Joiner (name, joinedName) select vin, owner from Car" ).executeUpdate(); fail( "mapped-join insertion did not error" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( QueryException e ) { // expected result } @@ -669,6 +697,9 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase { s.createQuery( "update Human set Human.description = 'xyz' where Human.id = 1 and Human.description is null" ); fail( "expected failure" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( QueryException expected ) { // ignore : expected behavior } @@ -894,6 +925,9 @@ public class BulkManipulationTest extends BaseCoreFunctionalTestCase { s.createQuery( "update Human set mother.name.initial = :initial" ).setString( "initial", "F" ).executeUpdate(); fail( "update allowed across implicit join" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( QueryException e ) { } diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/CaseStatementTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/CaseStatementTest.java index d36eb2ff02..4a861dda26 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/CaseStatementTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/CaseStatementTest.java @@ -16,6 +16,7 @@ import org.hibernate.Transaction; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.junit.Test; +import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; import static org.junit.Assert.fail; /** @@ -72,6 +73,9 @@ public class CaseStatementTest extends BaseCoreFunctionalTestCase { .list(); fail( "was expecting an exception" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch (QueryException expected) { // expected } @@ -122,6 +126,9 @@ public class CaseStatementTest extends BaseCoreFunctionalTestCase { .list(); fail( "was expecting an exception" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch (QueryException expected) { // expected } diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java index bc7b99bdc7..1053b12150 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java @@ -9,10 +9,7 @@ package org.hibernate.test.hql; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collections; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import javax.persistence.PersistenceException; import org.hibernate.Session; import org.hibernate.Transaction; @@ -23,12 +20,17 @@ import org.hibernate.hql.internal.ast.tree.SelectClause; import org.hibernate.hql.internal.classic.ClassicQueryTranslatorFactory; import org.hibernate.hql.spi.QueryTranslator; import org.hibernate.hql.spi.QueryTranslatorFactory; -import org.hibernate.testing.TestForIssue; import org.hibernate.type.BigDecimalType; import org.hibernate.type.BigIntegerType; import org.hibernate.type.DoubleType; import org.hibernate.type.LongType; +import org.hibernate.testing.TestForIssue; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; @@ -323,6 +325,15 @@ public class CriteriaHQLAlignmentTest extends QueryTranslatorTestCase { } assertEquals( 1, count.longValue() ); } + catch (PersistenceException e) { + SQLGrammarException cause = assertTyping( SQLGrammarException.class, e.getCause() ); + if ( ! getDialect().supportsTupleCounts() ) { + // expected + } + else { + throw e; + } + } catch ( SQLGrammarException ex ) { if ( ! getDialect().supportsTupleCounts() ) { // expected diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/HQLTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/HQLTest.java index 40270628e4..ec4ae26d4b 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/HQLTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/HQLTest.java @@ -250,12 +250,12 @@ public class HQLTest extends QueryTranslatorTestCase { assertEquals( "incorrect return type", CalendarDateType.INSTANCE, translator.getReturnTypes()[0] ); translator = createNewQueryTranslator( "from Order o where o.orderDate > ?" ); - assertEquals( "incorrect expected param type", CalendarDateType.INSTANCE, translator.getParameterTranslations().getOrdinalParameterExpectedType( 1 ) ); + assertEquals( "incorrect expected param type", CalendarDateType.INSTANCE, translator.getParameterTranslations().getOrdinalParameterExpectedType( 0 ) ); translator = createNewQueryTranslator( "select o.orderDate + ? from Order o" ); assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); assertEquals( "incorrect return type", CalendarDateType.INSTANCE, translator.getReturnTypes()[0] ); - assertEquals( "incorrect expected param type", DoubleType.INSTANCE, translator.getParameterTranslations().getOrdinalParameterExpectedType( 1 ) ); + assertEquals( "incorrect expected param type", DoubleType.INSTANCE, translator.getParameterTranslations().getOrdinalParameterExpectedType( 0 ) ); } diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/ScrollableCollectionFetchingTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/ScrollableCollectionFetchingTest.java index a42b791788..02455e0ddf 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/ScrollableCollectionFetchingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/ScrollableCollectionFetchingTest.java @@ -6,21 +6,16 @@ */ package org.hibernate.test.hql; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - import org.hibernate.HibernateException; +import org.hibernate.QueryException; import org.hibernate.ScrollMode; import org.hibernate.ScrollableResults; import org.hibernate.Session; import org.hibernate.Transaction; -import org.hibernate.dialect.CUBRIDDialect; import org.hibernate.dialect.AbstractHANADialect; +import org.hibernate.dialect.CUBRIDDialect; import org.hibernate.dialect.SybaseASE15Dialect; -import org.hibernate.engine.spi.SessionFactoryImplementor; + import org.hibernate.testing.DialectChecks; import org.hibernate.testing.RequiresDialectFeature; import org.hibernate.testing.SkipForDialect; @@ -28,6 +23,13 @@ import org.hibernate.testing.SkipForDialects; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.junit.Test; +import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + /** * Tests the new functionality of allowing scrolling of results which * contain collection fetches. @@ -48,6 +50,9 @@ public class ScrollableCollectionFetchingTest extends BaseCoreFunctionalTestCase s.createQuery( "select a, a.weight from Animal a inner join fetch a.offspring" ).scroll(); fail( "scroll allowed with collection fetch and reurning tuples" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( HibernateException e ) { // expected result... } diff --git a/hibernate-core/src/test/java/org/hibernate/test/hql/WithClauseTest.java b/hibernate-core/src/test/java/org/hibernate/test/hql/WithClauseTest.java index 08564ccdf5..2c873e7424 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/hql/WithClauseTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/hql/WithClauseTest.java @@ -6,23 +6,26 @@ */ package org.hibernate.test.hql; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - import java.util.ArrayList; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.Query; +import org.hibernate.QueryException; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.hql.internal.ast.InvalidWithClauseException; + import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.junit.Test; +import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + /** * Implementation of WithClauseTest. * @@ -47,6 +50,9 @@ public class WithClauseTest extends BaseCoreFunctionalTestCase { .list(); fail( "ad-hoc on clause allowed with fetched association" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch ( HibernateException e ) { // the expected response... } @@ -72,6 +78,9 @@ public class WithClauseTest extends BaseCoreFunctionalTestCase { .list(); fail( "failure expected" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( InvalidWithClauseException expected ) { } @@ -81,6 +90,9 @@ public class WithClauseTest extends BaseCoreFunctionalTestCase { .list(); fail( "failure expected" ); } + catch (IllegalArgumentException e) { + assertTyping( QueryException.class, e.getCause() ); + } catch( InvalidWithClauseException expected ) { } diff --git a/hibernate-core/src/test/java/org/hibernate/test/legacy/Custom.hbm.xml b/hibernate-core/src/test/java/org/hibernate/test/legacy/Custom.hbm.xml index ba547dca69..d70fb013d9 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/legacy/Custom.hbm.xml +++ b/hibernate-core/src/test/java/org/hibernate/test/legacy/Custom.hbm.xml @@ -11,7 +11,7 @@ - + diff --git a/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java b/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java index ec996d9db0..9206731e50 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java +++ b/hibernate-core/src/test/java/org/hibernate/test/legacy/CustomPersister.java @@ -61,6 +61,7 @@ public class CustomPersister implements EntityPersister { private static final IdentifierGenerator GENERATOR = new UUIDHexGenerator(); private SessionFactoryImplementor factory; + private EntityMetamodel entityMetamodel; @SuppressWarnings("UnusedParameters") public CustomPersister( @@ -69,6 +70,7 @@ public class CustomPersister implements EntityPersister { NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy, PersisterCreationContext creationContext) { this.factory = creationContext.getSessionFactory(); + this.entityMetamodel = new EntityMetamodel( model, this, factory ); } public boolean hasLazyProperties() { @@ -674,7 +676,7 @@ public class CustomPersister implements EntityPersister { @Override public EntityMetamodel getEntityMetamodel() { - return null; + return entityMetamodel; } @Override diff --git a/hibernate-core/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java b/hibernate-core/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java index e9cf823e92..2936b48020 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/sql/hand/query/NativeSQLQueriesTest.java @@ -185,7 +185,7 @@ public class NativeSQLQueriesTest extends BaseCoreFunctionalTestCase { s.persist( jboss ); // now query on Employment, this should not cause an auto-flush - s.createSQLQuery( getEmploymentSQL() ).list(); + s.createSQLQuery( getEmploymentSQL() ).addSynchronizedQuerySpace( "ABC" ).list(); assertEquals( 0, sessionFactory().getStatistics().getEntityInsertCount() ); // now try to query on Employment but this time add Organization as a synchronized query space... @@ -630,7 +630,7 @@ public class NativeSQLQueriesTest extends BaseCoreFunctionalTestCase { s = openSession(); t = s.beginTransaction(); - Dimension dim = new Dimension( 3, Integer.MAX_VALUE ); + Dimension dim = new Dimension( 3, 30 ); s.save( dim ); list = s.createSQLQuery( "select d_len * d_width as surface, d_len * d_width * 10 as volume from Dimension" ).list(); s.delete( dim ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/tm/TransactionTimeoutTest.java b/hibernate-core/src/test/java/org/hibernate/test/tm/TransactionTimeoutTest.java index 939b301657..4d134c7901 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/tm/TransactionTimeoutTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/tm/TransactionTimeoutTest.java @@ -6,6 +6,8 @@ */ package org.hibernate.test.tm; +import javax.persistence.PersistenceException; + import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.TransactionException; @@ -21,6 +23,7 @@ import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.test.jdbc.Person; import org.junit.Test; +import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; @@ -53,17 +56,29 @@ public class TransactionTimeoutTest extends BaseCoreFunctionalTestCase { session.close(); } - @Test(expected = TransactionException.class) + @Test public void testTransactionTimeoutFailure() throws InterruptedException { Session session = openSession(); - Transaction transaction = session.getTransaction(); - transaction.setTimeout( 1 ); - assertEquals( -1, ((SessionImplementor)session).getJdbcCoordinator().determineRemainingTransactionTimeOutPeriod() ); - transaction.begin(); - Thread.sleep( 1000 ); - session.persist( new Person( "Lukasz", "Antoniak" ) ); - transaction.commit(); - session.close(); + try { + Transaction transaction = session.getTransaction(); + transaction.setTimeout( 1 ); + assertEquals( -1, + ( (SessionImplementor) session ).getJdbcCoordinator().determineRemainingTransactionTimeOutPeriod() + ); + transaction.begin(); + Thread.sleep( 1000 ); + session.persist( new Person( "Lukasz", "Antoniak" ) ); + transaction.commit(); + } + catch (PersistenceException e) { + assertTyping( TransactionException.class, e.getCause() ); + } + catch (TransactionException e) { + // expected + } + finally { + session.close(); + } } @Test