diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/AbstractTransactSQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/AbstractTransactSQLDialect.java index 915c492f43..8e3c084207 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/AbstractTransactSQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/AbstractTransactSQLDialect.java @@ -178,7 +178,7 @@ abstract class AbstractTransactSQLDialect extends Dialect { } @Override - public String applyLocksToSql(String sql, LockOptions aliasedLockOptions, Map keyColumnNames) { + public String applyLocksToSql(String sql, LockOptions aliasedLockOptions, Map keyColumnNames) { // TODO: merge additional lockoptions support in Dialect.applyLocksToSql final Iterator itr = aliasedLockOptions.getAliasLockIterator(); final StringBuilder buffer = new StringBuilder( sql ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java index 5119f540ef..bd1e08cbbd 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java @@ -1452,7 +1452,7 @@ public abstract class Dialect implements ConversionContext { * @param keyColumnNames a map of key columns indexed by aliased table names. * @return the modified SQL string. */ - public String applyLocksToSql(String sql, LockOptions aliasedLockOptions, Map keyColumnNames) { + public String applyLocksToSql(String sql, LockOptions aliasedLockOptions, Map keyColumnNames) { return sql + new ForUpdateFragment( this, aliasedLockOptions, keyColumnNames ).toFragmentString(); } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE157Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE157Dialect.java index 9e164b9e05..6cf85a47ed 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE157Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE157Dialect.java @@ -96,7 +96,7 @@ public class SybaseASE157Dialect extends SybaseASE15Dialect { } @Override - public String applyLocksToSql(String sql, LockOptions aliasedLockOptions, Map keyColumnNames) { + public String applyLocksToSql(String sql, LockOptions aliasedLockOptions, Map keyColumnNames) { return sql + new ForUpdateFragment( this, aliasedLockOptions, keyColumnNames ).toFragmentString(); } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java index c1b006958c..e4f7434ba6 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/ColumnNameCache.java @@ -36,7 +36,7 @@ import java.util.concurrent.ConcurrentHashMap; public class ColumnNameCache { private static final float LOAD_FACTOR = .75f; - private final Map columnNameToIndexCache; + private final ConcurrentHashMap columnNameToIndexCache; /** * Constructs a ColumnNameCache diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/QueryTranslatorImpl.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/QueryTranslatorImpl.java index d7f7756641..da87cb4f12 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/QueryTranslatorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/QueryTranslatorImpl.java @@ -69,6 +69,7 @@ import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.IdentitySet; import org.hibernate.loader.hql.QueryLoader; +import org.hibernate.param.ParameterSpecification; import org.hibernate.persister.entity.Queryable; import org.hibernate.type.Type; @@ -101,7 +102,7 @@ public class QueryTranslatorImpl implements FilterTranslator { private String sql; private ParameterTranslations paramTranslations; - private List collectedParameterSpecifications; + private List collectedParameterSpecifications; /** @@ -569,12 +570,11 @@ public class QueryTranslatorImpl implements FilterTranslator { public ParameterTranslations getParameterTranslations() { if ( paramTranslations == null ) { paramTranslations = new ParameterTranslationsImpl( getWalker().getParameters() ); -// paramTranslations = new ParameterTranslationsImpl( collectedParameterSpecifications ); } return paramTranslations; } - public List getCollectedParameterSpecifications() { + public List getCollectedParameterSpecifications() { return collectedParameterSpecifications; } diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/SqlGenerator.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/SqlGenerator.java index 0c9b8846b5..e8339b99c2 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/SqlGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/SqlGenerator.java @@ -76,7 +76,7 @@ public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter { private SessionFactoryImplementor sessionFactory; private LinkedList outputStack = new LinkedList(); private final ASTPrinter printer = new ASTPrinter( SqlTokenTypes.class ); - private List collectedParameters = new ArrayList(); + private List collectedParameters = new ArrayList(); // handle trace logging ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -106,7 +106,7 @@ public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter { LOG.trace( prefix + ruleName ); } - public List getCollectedParameters() { + public List getCollectedParameters() { return collectedParameters; } diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElement.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElement.java index ceb1b87ab8..3138a76940 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElement.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/FromElement.java @@ -452,16 +452,12 @@ public class FromElement extends HqlSqlWalkerNode implements DisplayableNode, Pa this.alias = alias; } - /** - * {@inheritDoc} - */ + @Override public String getSqlFragment() { return persisterDiscriminatorMetadata.getSqlFragment( alias ); } - /** - * {@inheritDoc} - */ + @Override public Type getResolutionType() { return persisterDiscriminatorMetadata.getResolutionType(); } @@ -660,21 +656,24 @@ public class FromElement extends HqlSqlWalkerNode implements DisplayableNode, Pa // ParameterContainer impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - private List embeddedParameters; + private List embeddedParameters; + @Override public void addEmbeddedParameter(ParameterSpecification specification) { if ( embeddedParameters == null ) { - embeddedParameters = new ArrayList(); + embeddedParameters = new ArrayList(); } embeddedParameters.add( specification ); } + @Override public boolean hasEmbeddedParameters() { return embeddedParameters != null && ! embeddedParameters.isEmpty(); } + @Override public ParameterSpecification[] getEmbeddedParameters() { - return ( ParameterSpecification[] ) embeddedParameters.toArray( new ParameterSpecification[ embeddedParameters.size() ] ); + return embeddedParameters.toArray( new ParameterSpecification[ embeddedParameters.size() ] ); } public ParameterSpecification getIndexCollectionSelectorParamSpec() { diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/IndexNode.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/IndexNode.java index c579b9b6d5..0c12b17c5e 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/IndexNode.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/IndexNode.java @@ -147,14 +147,14 @@ public class IndexNode extends FromReferenceNode { } String selectorExpression = gen.getSQL(); joinSequence.addCondition( collectionTableAlias + '.' + indexCols[0] + " = " + selectorExpression ); - List paramSpecs = gen.getCollectedParameters(); + List paramSpecs = gen.getCollectedParameters(); if ( paramSpecs != null ) { switch ( paramSpecs.size() ) { case 0 : // nothing to do break; case 1 : - ParameterSpecification paramSpec = ( ParameterSpecification ) paramSpecs.get( 0 ); + ParameterSpecification paramSpec = paramSpecs.get( 0 ); paramSpec.setExpectedType( queryableCollection.getIndexType() ); fromElement.setIndexCollectionSelectorParamSpec( paramSpec ); break; @@ -176,39 +176,40 @@ public class IndexNode extends FromReferenceNode { * In the (rare?) case where the index selector contains multiple parameters... */ private static class AggregatedIndexCollectionSelectorParameterSpecifications implements ParameterSpecification { - private final List paramSpecs; + private final List paramSpecs; - public AggregatedIndexCollectionSelectorParameterSpecifications(List paramSpecs) { + public AggregatedIndexCollectionSelectorParameterSpecifications(List paramSpecs) { this.paramSpecs = paramSpecs; } + @Override public int bind(PreparedStatement statement, QueryParameters qp, SessionImplementor session, int position) throws SQLException { int bindCount = 0; - Iterator itr = paramSpecs.iterator(); - while ( itr.hasNext() ) { - final ParameterSpecification paramSpec = ( ParameterSpecification ) itr.next(); + for ( ParameterSpecification paramSpec : paramSpecs ) { bindCount += paramSpec.bind( statement, qp, session, position + bindCount ); } return bindCount; } + @Override public Type getExpectedType() { return null; } + @Override public void setExpectedType(Type expectedType) { } + @Override public String renderDisplayInfo() { return "index-selector [" + collectDisplayInfo() + "]" ; } private String collectDisplayInfo() { StringBuilder buffer = new StringBuilder(); - Iterator itr = paramSpecs.iterator(); - while ( itr.hasNext() ) { - buffer.append( ( ( ParameterSpecification ) itr.next() ).renderDisplayInfo() ); + for ( ParameterSpecification paramSpec : paramSpecs ) { + buffer.append( ( paramSpec ).renderDisplayInfo() ); } return buffer.toString(); } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java index 784559c18d..685c7a778d 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/Loader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/Loader.java @@ -79,6 +79,7 @@ import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.FetchingScrollableResultsImpl; import org.hibernate.internal.ScrollableResultsImpl; import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; @@ -110,7 +111,7 @@ import org.hibernate.type.VersionType; public abstract class Loader { protected static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, Loader.class.getName()); - + protected static final boolean DEBUG_ENABLED = LOG.isDebugEnabled(); private final SessionFactoryImplementor factory; private ColumnNameCache columnNameCache; @@ -931,9 +932,9 @@ public abstract class Loader { EntityKey[] keys = new EntityKey[entitySpan]; //we can reuse it for each row LOG.trace( "Processing result set" ); int count; - boolean isDebugEnabled = LOG.isDebugEnabled(); + for ( count = 0; count < maxRows && rs.next(); count++ ) { - if ( isDebugEnabled ) + if ( DEBUG_ENABLED ) LOG.debugf( "Result set row: %s", count ); Object result = getRowFromResultSet( rs, @@ -975,8 +976,10 @@ public abstract class Loader { protected boolean hasSubselectLoadableCollections() { final Loadable[] loadables = getEntityPersisters(); - for (int i=0; i namedParams, final int startIndex, final SessionImplementor session) throws SQLException, HibernateException { - if ( namedParams != null ) { - // assumes that types are all of span 1 - Iterator iter = namedParams.entrySet().iterator(); - final boolean debugEnabled = LOG.isDebugEnabled(); - int result = 0; - while ( iter.hasNext() ) { - Map.Entry e = ( Map.Entry ) iter.next(); - String name = ( String ) e.getKey(); - TypedValue typedval = ( TypedValue ) e.getValue(); - int[] locs = getNamedParameterLocs( name ); - for ( int i = 0; i < locs.length; i++ ) { - if ( debugEnabled ) LOG.debugf( "bindNamedParameters() %s -> %s [%s]", typedval.getValue(), name, locs[i] + startIndex ); - typedval.getType().nullSafeSet( statement, typedval.getValue(), locs[i] + startIndex, session ); - } - result += locs.length; - } + int result = 0; + if ( CollectionHelper.isEmpty( namedParams ) ) { return result; } - else { - return 0; + + for ( String name : namedParams.keySet() ) { + TypedValue typedValue = namedParams.get( name ); + int columnSpan = typedValue.getType().getColumnSpan( getFactory() ); + int[] locs = getNamedParameterLocs( name ); + for ( int loc : locs ) { + if ( DEBUG_ENABLED ) { + LOG.debugf( + "bindNamedParameters() %s -> %s [%s]", + typedValue.getValue(), + name, + loc + startIndex + ); + } + int start = loc * columnSpan + startIndex; + typedValue.getType().nullSafeSet( statement, typedValue.getValue(), start, session ); + } + result += locs.length; } + return result; } public int[] getNamedParameterLocs(String name) { @@ -2080,7 +2084,7 @@ public abstract class Loader { private ColumnNameCache retreiveColumnNameToIndexCache(ResultSet rs) throws SQLException { if ( columnNameCache == null ) { - LOG.trace( "Building columnName->columnIndex cache" ); + LOG.trace( "Building columnName -> columnIndex cache" ); columnNameCache = new ColumnNameCache( rs.getMetaData().getColumnCount() ); } @@ -2293,7 +2297,7 @@ public abstract class Loader { final Serializable[] ids, final Object[] parameterValues, final Type[] parameterTypes, - final Map namedParameters, + final Map namedParameters, final Type type) throws HibernateException { Type[] idTypes = new Type[ids.length]; @@ -2551,7 +2555,6 @@ public abstract class Loader { // whether scrolling of their result set should be allowed. // // By default it is allowed. - return; } /** diff --git a/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java index 81246e8aeb..009cd54731 100755 --- a/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java @@ -35,6 +35,7 @@ import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.engine.spi.TypedValue; import org.hibernate.persister.collection.QueryableCollection; import org.hibernate.type.Type; @@ -47,15 +48,15 @@ public class SubselectCollectionLoader extends BasicCollectionLoader { private final Serializable[] keys; private final Type[] types; private final Object[] values; - private final Map namedParameters; - private final Map namedParameterLocMap; + private final Map namedParameters; + private final Map namedParameterLocMap; public SubselectCollectionLoader( QueryableCollection persister, String subquery, Collection entityKeys, QueryParameters queryParameters, - Map namedParameterLocMap, + Map namedParameterLocMap, SessionFactoryImplementor factory, LoadQueryInfluencers loadQueryInfluencers) throws MappingException { super( persister, 1, subquery, factory, loadQueryInfluencers ); @@ -74,6 +75,7 @@ public class SubselectCollectionLoader extends BasicCollectionLoader { } + @Override public void initialize(Serializable id, SessionImplementor session) throws HibernateException { loadCollectionSubselect( @@ -86,8 +88,9 @@ public class SubselectCollectionLoader extends BasicCollectionLoader { ); } + @Override public int[] getNamedParameterLocs(String name) { - return (int[]) namedParameterLocMap.get( name ); + return namedParameterLocMap.get( name ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java index 4ef55cee5d..f830301645 100755 --- a/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java @@ -35,6 +35,7 @@ import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.QueryParameters; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.engine.spi.TypedValue; import org.hibernate.persister.collection.QueryableCollection; import org.hibernate.type.Type; @@ -47,15 +48,15 @@ public class SubselectOneToManyLoader extends OneToManyLoader { private final Serializable[] keys; private final Type[] types; private final Object[] values; - private final Map namedParameters; - private final Map namedParameterLocMap; + private final Map namedParameters; + private final Map namedParameterLocMap; public SubselectOneToManyLoader( QueryableCollection persister, String subquery, Collection entityKeys, QueryParameters queryParameters, - Map namedParameterLocMap, + Map namedParameterLocMap, SessionFactoryImplementor factory, LoadQueryInfluencers loadQueryInfluencers) throws MappingException { super( persister, 1, subquery, factory, loadQueryInfluencers ); @@ -73,6 +74,7 @@ public class SubselectOneToManyLoader extends OneToManyLoader { this.namedParameterLocMap = namedParameterLocMap; } + @Override public void initialize(Serializable id, SessionImplementor session) throws HibernateException { loadCollectionSubselect( session, @@ -83,9 +85,9 @@ public class SubselectOneToManyLoader extends OneToManyLoader { getKeyType() ); } - + @Override public int[] getNamedParameterLocs(String name) { - return (int[]) namedParameterLocMap.get( name ); + return namedParameterLocMap.get( name ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/loader/custom/CustomLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/custom/CustomLoader.java index b626e375ec..e8fd1013c6 100755 --- a/hibernate-core/src/main/java/org/hibernate/loader/custom/CustomLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/custom/CustomLoader.java @@ -459,7 +459,7 @@ public class CustomLoader extends Loader { ); } if ( loc instanceof Integer ) { - return new int[] { ( ( Integer ) loc ).intValue() }; + return new int[] { (Integer) loc }; } else { return ArrayHelper.toIntArray( ( List ) loc ); diff --git a/hibernate-core/src/main/java/org/hibernate/loader/hql/QueryLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/hql/QueryLoader.java index 3a45e39d53..e3a4c73136 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/hql/QueryLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/hql/QueryLoader.java @@ -88,7 +88,7 @@ public class QueryLoader extends BasicLoader { //private Type[] sqlResultTypes; private Type[] queryReturnTypes; - private final Map sqlAliasByEntityAlias = new HashMap(8); + private final Map sqlAliasByEntityAlias = new HashMap(8); private EntityType[] ownerAssociationTypes; private int[] owners; @@ -209,15 +209,15 @@ public class QueryLoader extends BasicLoader { public final void validateScrollability() throws HibernateException { queryTranslator.validateScrollability(); } - + @Override protected boolean needsFetchingScroll() { return queryTranslator.containsCollectionFetches(); } - + @Override public Loadable[] getEntityPersisters() { return entityPersisters; } - + @Override public String[] getAliases() { return sqlAliases; } @@ -225,15 +225,15 @@ public class QueryLoader extends BasicLoader { public String[] getSqlAliasSuffixes() { return sqlAliasSuffixes; } - + @Override public String[] getSuffixes() { return getSqlAliasSuffixes(); } - + @Override public String[] getCollectionSuffixes() { return collectionSuffixes; } - + @Override protected String getQueryIdentifier() { return queryTranslator.getQueryIdentifier(); } @@ -241,6 +241,7 @@ public class QueryLoader extends BasicLoader { /** * The SQL query string to be called. */ + @Override public String getSQLString() { return queryTranslator.getSQLString(); } @@ -249,14 +250,15 @@ public class QueryLoader extends BasicLoader { * An (optional) persister for a collection to be initialized; only collection loaders * return a non-null value */ + @Override protected CollectionPersister[] getCollectionPersisters() { return collectionPersisters; } - + @Override protected int[] getCollectionOwners() { return collectionOwners; } - + @Override protected boolean[] getEntityEagerPropertyFetches() { return entityEagerPropertyFetches; } @@ -265,16 +267,17 @@ public class QueryLoader extends BasicLoader { * An array of indexes of the entity that owns a one-to-one association * to the entity at the given index (-1 if there is no "owner") */ + @Override protected int[] getOwners() { return owners; } - + @Override protected EntityType[] getOwnerAssociationTypes() { return ownerAssociationTypes; } // -- Loader overrides -- - + @Override protected boolean isSubselectLoadingEnabled() { return hasSubselectLoadableCollections(); } @@ -282,6 +285,7 @@ public class QueryLoader extends BasicLoader { /** * @param lockOptions a collection of lock modes specified dynamically via the Query interface */ + @Override protected LockMode[] getLockModes(LockOptions lockOptions) { if ( lockOptions == null ) { return defaultLockModes; @@ -341,16 +345,14 @@ public class QueryLoader extends BasicLoader { // we need both the set of locks and the columns to reference in locks // as the ultimate output of this section... final LockOptions locks = new LockOptions( lockOptions.getLockMode() ); - final Map keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap() : null; + final Map keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap() : null; locks.setScope( lockOptions.getScope() ); locks.setTimeOut( lockOptions.getTimeOut() ); - final Iterator itr = sqlAliasByEntityAlias.entrySet().iterator(); - while ( itr.hasNext() ) { - final Map.Entry entry = (Map.Entry) itr.next(); - final String userAlias = (String) entry.getKey(); - final String drivingSqlAlias = (String) entry.getValue(); + for ( Map.Entry entry : sqlAliasByEntityAlias.entrySet() ) { + final String userAlias = entry.getKey(); + final String drivingSqlAlias = entry.getValue(); if ( drivingSqlAlias == null ) { throw new IllegalArgumentException( "could not locate alias to apply lock mode : " + userAlias ); } @@ -360,8 +362,8 @@ public class QueryLoader extends BasicLoader { // the exception case here is joined-subclass hierarchies where we instead // want to apply the lock against the root table (for all other strategies, // it just happens that driving and root are the same). - final QueryNode select = ( QueryNode ) queryTranslator.getSqlAST(); - final Lockable drivingPersister = ( Lockable ) select.getFromClause() + final QueryNode select = (QueryNode) queryTranslator.getSqlAST(); + final Lockable drivingPersister = (Lockable) select.getFromClause() .findFromElementByUserOrSqlAlias( userAlias, drivingSqlAlias ) .getQueryable(); final String sqlAlias = drivingPersister.getRootTableAlias( drivingSqlAlias ); @@ -377,7 +379,7 @@ public class QueryLoader extends BasicLoader { // apply the collected locks and columns return dialect.applyLocksToSql( sql, locks, keyColumnNames ); } - + @Override protected void applyPostLoadLocks(Object[] row, LockMode[] lockModesArray, SessionImplementor session) { // todo : scalars??? // if ( row.length != lockModesArray.length ) { @@ -393,7 +395,7 @@ public class QueryLoader extends BasicLoader { // } // } } - + @Override protected boolean upgradeLocks() { return true; } @@ -401,18 +403,18 @@ public class QueryLoader extends BasicLoader { private boolean hasSelectNew() { return aggregatedSelectExpression != null && aggregatedSelectExpression.getResultTransformer() != null; } - + @Override protected String[] getResultRowAliases() { return queryReturnAliases; } - + @Override protected ResultTransformer resolveResultTransformer(ResultTransformer resultTransformer) { final ResultTransformer implicitResultTransformer = aggregatedSelectExpression == null ? null : aggregatedSelectExpression.getResultTransformer(); return HolderInstantiator.resolveResultTransformer( implicitResultTransformer, resultTransformer ); } - + @Override protected boolean[] includeInResultRow() { boolean[] includeInResultTuple = includeInSelect; if ( hasScalars ) { @@ -421,7 +423,7 @@ public class QueryLoader extends BasicLoader { } return includeInResultTuple; } - + @Override protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session) throws SQLException, HibernateException { @@ -433,6 +435,7 @@ public class QueryLoader extends BasicLoader { ); } + @Override protected Object[] getResultRow(Object[] row, ResultSet rs, SessionImplementor session) throws SQLException, HibernateException { Object[] resultRow; @@ -450,6 +453,8 @@ public class QueryLoader extends BasicLoader { return resultRow; } + @SuppressWarnings("unchecked") + @Override protected List getResultList(List results, ResultTransformer resultTransformer) throws QueryException { // meant to handle dynamic instantiation queries... HolderInstantiator holderInstantiator = buildHolderInstantiator( resultTransformer ); @@ -579,6 +584,7 @@ public class QueryLoader extends BasicLoader { /** * Returns the locations of all occurrences of the named parameter. */ + @Override public int[] getNamedParameterLocs(String name) throws QueryException { return queryTranslator.getParameterTranslations().getNamedParameterSqlLocations( name ); } @@ -586,7 +592,7 @@ public class QueryLoader extends BasicLoader { /** * We specifically override this method here, because in general we know much more * about the parameters and their appropriate bind positions here then we do in - * our super because we track them explciitly here through the ParameterSpecification + * our super because we track them explicitly here through the ParameterSpecification * interface. * * @param queryParameters The encapsulation of the parameter values to be bound. @@ -595,45 +601,17 @@ public class QueryLoader extends BasicLoader { * @return The number of JDBC bind positions actually bound during this method execution. * @throws SQLException Indicates problems performing the binding. */ + @Override protected int bindParameterValues( final PreparedStatement statement, final QueryParameters queryParameters, final int startIndex, final SessionImplementor session) throws SQLException { -// int position = bindFilterParameterValues( statement, queryParameters, startIndex, session ); int position = startIndex; -// List parameterSpecs = queryTranslator.getSqlAST().getWalker().getParameters(); - List parameterSpecs = queryTranslator.getCollectedParameterSpecifications(); - Iterator itr = parameterSpecs.iterator(); - while ( itr.hasNext() ) { - ParameterSpecification spec = ( ParameterSpecification ) itr.next(); + List parameterSpecs = queryTranslator.getCollectedParameterSpecifications(); + for ( ParameterSpecification spec : parameterSpecs ) { position += spec.bind( statement, queryParameters, session, position ); } return position - startIndex; } - - private int bindFilterParameterValues( - PreparedStatement st, - QueryParameters queryParameters, - int position, - SessionImplementor session) throws SQLException { - // todo : better to handle dynamic filters through implicit DynamicFilterParameterSpecification - // see the discussion there in DynamicFilterParameterSpecification's javadocs as to why - // it is currently not done that way. - int filteredParamCount = queryParameters.getFilteredPositionalParameterTypes() == null - ? 0 - : queryParameters.getFilteredPositionalParameterTypes().length; - int nonfilteredParamCount = queryParameters.getPositionalParameterTypes() == null - ? 0 - : queryParameters.getPositionalParameterTypes().length; - int filterParamCount = filteredParamCount - nonfilteredParamCount; - for ( int i = 0; i < filterParamCount; i++ ) { - Type type = queryParameters.getFilteredPositionalParameterTypes()[i]; - Object value = queryParameters.getFilteredPositionalParameterValues()[i]; - type.nullSafeSet( st, value, position, session ); - position += type.getColumnSpan( getFactory() ); - } - - return position; - } } diff --git a/hibernate-core/src/main/java/org/hibernate/param/AbstractExplicitParameterSpecification.java b/hibernate-core/src/main/java/org/hibernate/param/AbstractExplicitParameterSpecification.java index de27388ea4..a5fffb6804 100644 --- a/hibernate-core/src/main/java/org/hibernate/param/AbstractExplicitParameterSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/param/AbstractExplicitParameterSpecification.java @@ -46,30 +46,22 @@ public abstract class AbstractExplicitParameterSpecification implements Explicit this.sourceColumn = sourceColumn; } - /** - * {@inheritDoc} - */ + @Override public int getSourceLine() { return sourceLine; } - /** - * {@inheritDoc} - */ + @Override public int getSourceColumn() { return sourceColumn; } - /** - * {@inheritDoc} - */ + @Override public Type getExpectedType() { return expectedType; } - /** - * {@inheritDoc} - */ + @Override public void setExpectedType(Type expectedType) { this.expectedType = expectedType; } diff --git a/hibernate-core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java b/hibernate-core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java index 67c774f2d1..eb8f6be70a 100644 --- a/hibernate-core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java @@ -55,9 +55,7 @@ public class CollectionFilterKeyParameterSpecification implements ParameterSpeci this.queryParameterPosition = queryParameterPosition; } - /** - * {@inheritDoc} - */ + @Override public int bind( PreparedStatement statement, QueryParameters qp, @@ -68,23 +66,17 @@ public class CollectionFilterKeyParameterSpecification implements ParameterSpeci return keyType.getColumnSpan( session.getFactory() ); } - /** - * {@inheritDoc} - */ + @Override public Type getExpectedType() { return keyType; } - /** - * {@inheritDoc} - */ + @Override public void setExpectedType(Type expectedType) { // todo : throw exception? } - /** - * {@inheritDoc} - */ + @Override public String renderDisplayInfo() { return "collection-filter-key=" + collectionRole; } diff --git a/hibernate-core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java b/hibernate-core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java index cc1fca6054..3258d76639 100644 --- a/hibernate-core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java @@ -60,9 +60,7 @@ public class DynamicFilterParameterSpecification implements ParameterSpecificati this.definedParameterType = definedParameterType; } - /** - * {@inheritDoc} - */ + @Override public int bind( PreparedStatement statement, QueryParameters qp, @@ -85,23 +83,17 @@ public class DynamicFilterParameterSpecification implements ParameterSpecificati } } - /** - * {@inheritDoc} - */ + @Override public Type getExpectedType() { return definedParameterType; } - /** - * {@inheritDoc} - */ + @Override public void setExpectedType(Type expectedType) { // todo : throw exception? maybe warn if not the same? } - /** - * {@inheritDoc} - */ + @Override public String renderDisplayInfo() { return "dynamic-filter={filterName=" + filterName + ",paramName=" + parameterName + "}"; } diff --git a/hibernate-core/src/main/java/org/hibernate/param/NamedParameterSpecification.java b/hibernate-core/src/main/java/org/hibernate/param/NamedParameterSpecification.java index 90d08fb14f..02efca32b2 100644 --- a/hibernate-core/src/main/java/org/hibernate/param/NamedParameterSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/param/NamedParameterSpecification.java @@ -35,7 +35,7 @@ import org.hibernate.engine.spi.TypedValue; * * @author Steve Ebersole */ -public class NamedParameterSpecification extends AbstractExplicitParameterSpecification implements ParameterSpecification { +public class NamedParameterSpecification extends AbstractExplicitParameterSpecification { private final String name; /** diff --git a/hibernate-core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java b/hibernate-core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java index f9f314a0e0..24c047b96d 100644 --- a/hibernate-core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java @@ -35,7 +35,7 @@ import org.hibernate.type.Type; * * @author Steve Ebersole */ -public class PositionalParameterSpecification extends AbstractExplicitParameterSpecification implements ParameterSpecification { +public class PositionalParameterSpecification extends AbstractExplicitParameterSpecification { private final int hqlPosition; /** diff --git a/hibernate-core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java b/hibernate-core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java index 84e2580d24..2407e23bb0 100644 --- a/hibernate-core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java @@ -37,7 +37,7 @@ import org.hibernate.type.VersionType; * @author Steve Ebersole */ public class VersionTypeSeedParameterSpecification implements ParameterSpecification { - private VersionType type; + private final VersionType type; /** * Constructs a version seed parameter bind specification. @@ -48,32 +48,24 @@ public class VersionTypeSeedParameterSpecification implements ParameterSpecifica this.type = type; } - /** - * {@inheritDoc} - */ + @Override public int bind(PreparedStatement statement, QueryParameters qp, SessionImplementor session, int position) throws SQLException { type.nullSafeSet( statement, type.seed( session ), position, session ); return 1; } - /** - * {@inheritDoc} - */ + @Override public Type getExpectedType() { return type; } - /** - * {@inheritDoc} - */ + @Override public void setExpectedType(Type expectedType) { // expected type is intrinsic here... } - /** - * {@inheritDoc} - */ + @Override public String renderDisplayInfo() { return "version-seed, type=" + type; } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ForUpdateFragment.java b/hibernate-core/src/main/java/org/hibernate/sql/ForUpdateFragment.java index 71895a88dd..4897bff2ea 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ForUpdateFragment.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ForUpdateFragment.java @@ -48,7 +48,7 @@ public class ForUpdateFragment { this.dialect = dialect; } - public ForUpdateFragment(Dialect dialect, LockOptions lockOptions, Map keyColumnNames) throws QueryException { + public ForUpdateFragment(Dialect dialect, LockOptions lockOptions, Map keyColumnNames) throws QueryException { this( dialect ); LockMode upgradeType = null; Iterator iter = lockOptions.getAliasLockIterator(); @@ -68,13 +68,13 @@ public class ForUpdateFragment { if ( LockMode.READ.lessThan( lockMode ) ) { final String tableAlias = ( String ) me.getKey(); if ( dialect.forUpdateOfColumns() ) { - String[] keyColumns = ( String[] ) keyColumnNames.get( tableAlias ); //use the id column alias + String[] keyColumns = keyColumnNames.get( tableAlias ); //use the id column alias if ( keyColumns == null ) { throw new IllegalArgumentException( "alias not found: " + tableAlias ); } keyColumns = StringHelper.qualify( tableAlias, keyColumns ); - for ( int i = 0; i < keyColumns.length; i++ ) { - addTableAlias( keyColumns[i] ); + for ( String keyColumn : keyColumns ) { + addTableAlias( keyColumn ); } } else { diff --git a/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java b/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java index 3febc377dd..7ae2972361 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/ComponentType.java @@ -120,8 +120,8 @@ public class ComponentType extends AbstractType implements CompositeType, Proced int n = 0; for ( int i = 0; i < propertySpan; i++ ) { int[] subtypes = propertyTypes[i].sqlTypes( mapping ); - for ( int j = 0; j < subtypes.length; j++ ) { - sqlTypes[n++] = subtypes[j]; + for ( int subtype : subtypes ) { + sqlTypes[n++] = subtype; } } return sqlTypes; @@ -327,7 +327,7 @@ public class ComponentType extends AbstractType implements CompositeType, Proced return old != null; } if ( old == null ) { - return current != null; + return true; } Object[] currentValues = getPropertyValues( current, session ); Object[] oldValues = ( Object[] ) old; @@ -344,12 +344,12 @@ public class ComponentType extends AbstractType implements CompositeType, Proced return false; } - + @Override public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException { return resolve( hydrate( rs, names, session, owner ), session, owner ); } - + @Override public void nullSafeSet(PreparedStatement st, Object value, int begin, SessionImplementor session) throws HibernateException, SQLException { @@ -360,7 +360,7 @@ public class ComponentType extends AbstractType implements CompositeType, Proced begin += propertyTypes[i].getColumnSpan( session.getFactory() ); } } - + @Override public void nullSafeSet( PreparedStatement st, Object value, @@ -401,13 +401,13 @@ public class ComponentType extends AbstractType implements CompositeType, Proced return getPropertyValues( value, entityMode ); } } - + @Override public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) throws HibernateException, SQLException { return nullSafeGet( rs, new String[] {name}, session, owner ); } - + @Override public Object getPropertyValue(Object component, int i, SessionImplementor session) throws HibernateException { return getPropertyValue( component, i, entityMode ); @@ -417,12 +417,12 @@ public class ComponentType extends AbstractType implements CompositeType, Proced throws HibernateException { return componentTuplizer.getPropertyValue( component, i ); } - + @Override public Object[] getPropertyValues(Object component, SessionImplementor session) throws HibernateException { return getPropertyValues( component, entityMode ); } - + @Override public Object[] getPropertyValues(Object component, EntityMode entityMode) throws HibernateException { if ( component instanceof Object[] ) { @@ -435,40 +435,41 @@ public class ComponentType extends AbstractType implements CompositeType, Proced return componentTuplizer.getPropertyValues( component ); } } - + @Override public void setPropertyValues(Object component, Object[] values, EntityMode entityMode) throws HibernateException { componentTuplizer.setPropertyValues( component, values ); } - + @Override public Type[] getSubtypes() { return propertyTypes; } - + @Override public String getName() { return "component" + ArrayHelper.toString( propertyNames ); } - + @Override public String toLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException { if ( value == null ) { return "null"; } - Map result = new HashMap(); + if ( entityMode == null ) { throw new ClassCastException( value.getClass().getName() ); } + Map result = new HashMap(); Object[] values = getPropertyValues( value, entityMode ); for ( int i = 0; i < propertyTypes.length; i++ ) { result.put( propertyNames[i], propertyTypes[i].toLoggableString( values[i], factory ) ); } return StringHelper.unqualify( getName() ) + result.toString(); } - + @Override public String[] getPropertyNames() { return propertyNames; } - + @Override public Object deepCopy(Object component, SessionFactoryImplementor factory) throws HibernateException { if ( component == null ) { @@ -491,7 +492,7 @@ public class ComponentType extends AbstractType implements CompositeType, Proced return result; } - + @Override public Object replace( Object original, Object target, @@ -577,11 +578,11 @@ public class ComponentType extends AbstractType implements CompositeType, Proced return result; } - + @Override public CascadeStyle getCascadeStyle(int i) { return cascade[i]; } - + @Override public boolean isMutable() { return true; } @@ -620,7 +621,7 @@ public class ComponentType extends AbstractType implements CompositeType, Proced return result; } } - + @Override public FetchMode getFetchMode(int i) { return joinedFetch[i]; } @@ -681,7 +682,7 @@ public class ComponentType extends AbstractType implements CompositeType, Proced //for components with many-to-one associations return resolve( value, session, owner ); } - + @Override public boolean[] getPropertyNullability() { return propertyNullability; } @@ -690,15 +691,15 @@ public class ComponentType extends AbstractType implements CompositeType, Proced public boolean isXMLElement() { return true; } - + @Override public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException { return xml; } - + @Override public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) throws HibernateException { replaceNode( node, ( Element ) value ); } - + @Override public boolean[] toColumnNullness(Object value, Mapping mapping) { boolean[] result = new boolean[ getColumnSpan( mapping ) ]; if ( value == null ) { @@ -713,7 +714,7 @@ public class ComponentType extends AbstractType implements CompositeType, Proced } return result; } - + @Override public boolean isEmbedded() { return false; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/subselect/CompositeIdTypeBindingTest.java b/hibernate-core/src/test/java/org/hibernate/test/subselect/CompositeIdTypeBindingTest.java new file mode 100644 index 0000000000..302c12cfcd --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/subselect/CompositeIdTypeBindingTest.java @@ -0,0 +1,89 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2013, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.subselect; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.Assert; +import org.junit.Test; + +import org.hibernate.Session; +import org.hibernate.dialect.H2Dialect; +import org.hibernate.testing.SkipForDialect; +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; + +/** + * @author Strong Liu + */ +@SkipForDialect(value = H2Dialect.class, comment = "H2 doesn't support this sql syntax") +@TestForIssue( jiraKey = "HHH-8312") +public class CompositeIdTypeBindingTest extends BaseCoreFunctionalTestCase { + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Employee.class, EmployeeGroup.class }; + } + + @Test + public void testCompositeTypeBinding() { + Session session = openSession(); + session.beginTransaction(); + + EmployeeGroup employeegroup = new EmployeeGroup( new EmployeeGroupId( "a", "b" ) ); + employeegroup.addEmployee( new Employee( "stliu" ) ); + employeegroup.addEmployee( new Employee( "david" ) ); + session.save( employeegroup ); + + + employeegroup = new EmployeeGroup( new EmployeeGroupId( "c", "d" ) ); + employeegroup.addEmployee( new Employee( "gail" ) ); + employeegroup.addEmployee( new Employee( "steve" ) ); + session.save( employeegroup ); + + + session.getTransaction().commit(); + + session.close(); + + session = openSession(); + + List parameters = new ArrayList(); + parameters.add( new EmployeeGroupId( "a", "b" ) ); + parameters.add( new EmployeeGroupId( "c", "d" ) ); + parameters.add( new EmployeeGroupId( "e", "f" ) ); + + List result = session.createQuery( "select eg from EmployeeGroup eg where eg.id in (:employeegroupIds)" ) + .setParameterList( "employeegroupIds", parameters ).list(); + + Assert.assertEquals( 2, result.size() ); + + employeegroup = (EmployeeGroup) result.get( 0 ); + + Assert.assertEquals( "a", employeegroup.getId().getGroupName() ); + Assert.assertNotNull( employeegroup.getEmployees() ); + Assert.assertEquals( 2, employeegroup.getEmployees().size() ); + session.close(); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/subselect/Employee.java b/hibernate-core/src/test/java/org/hibernate/test/subselect/Employee.java new file mode 100644 index 0000000000..17852a2f0c --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/subselect/Employee.java @@ -0,0 +1,53 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2013, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.subselect; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Entity +public class Employee { + @Id + @GeneratedValue + private Long id; + private String name; + + public String getName() { + return name; + } + + @SuppressWarnings("unused") + private Employee() { + } + + public Employee(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } +} \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/test/subselect/Employeegroup.java b/hibernate-core/src/test/java/org/hibernate/test/subselect/Employeegroup.java new file mode 100644 index 0000000000..f859eb4ab9 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/subselect/Employeegroup.java @@ -0,0 +1,70 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2013, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.subselect; + + +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; + +@Entity +public class EmployeeGroup { + @Id + private EmployeeGroupId id; + + @OneToMany(cascade = CascadeType.ALL) + @Fetch(FetchMode.SUBSELECT) + private List employees = new ArrayList(); + + public EmployeeGroup(EmployeeGroupId id) { + this.id = id; + } + + @SuppressWarnings("unused") + private EmployeeGroup() { + } + + public boolean addEmployee(Employee employee) { + return employees.add(employee); + } + + public List getEmployees() { + return employees; + } + + public EmployeeGroupId getId() { + return id; + } + + @Override + public String toString() { + return id.toString(); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/subselect/EmployeegroupId.java b/hibernate-core/src/test/java/org/hibernate/test/subselect/EmployeegroupId.java new file mode 100644 index 0000000000..2a97e6033f --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/subselect/EmployeegroupId.java @@ -0,0 +1,58 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2013, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.test.subselect; + + +import java.io.Serializable; +import javax.persistence.Embeddable; + +@Embeddable +public class EmployeeGroupId + implements Serializable { + private static final long serialVersionUID = 1L; + private String groupName; + private String departmentName; + + @SuppressWarnings("unused") + private EmployeeGroupId() { + } + + public EmployeeGroupId(String groupName, String departmentName) { + this.groupName = groupName; + this.departmentName = departmentName; + } + + public String getDepartmentName() { + return departmentName; + } + + public String getGroupName() { + return groupName; + } + + @Override + public String toString() { + return "groupName: " + groupName + ", departmentName: " + departmentName; + } +}