You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(22) |
Nov
(308) |
Dec
(131) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(369) |
Feb
(171) |
Mar
(236) |
Apr
(187) |
May
(218) |
Jun
(217) |
Jul
(127) |
Aug
(448) |
Sep
(270) |
Oct
(231) |
Nov
(422) |
Dec
(255) |
2004 |
Jan
(111) |
Feb
(73) |
Mar
(338) |
Apr
(351) |
May
(349) |
Jun
(495) |
Jul
(394) |
Aug
(1048) |
Sep
(499) |
Oct
(142) |
Nov
(269) |
Dec
(638) |
2005 |
Jan
(825) |
Feb
(1272) |
Mar
(593) |
Apr
(690) |
May
(950) |
Jun
(958) |
Jul
(767) |
Aug
(839) |
Sep
(525) |
Oct
(449) |
Nov
(585) |
Dec
(455) |
2006 |
Jan
(603) |
Feb
(656) |
Mar
(195) |
Apr
(114) |
May
(136) |
Jun
(100) |
Jul
(128) |
Aug
(68) |
Sep
(7) |
Oct
(1) |
Nov
(1) |
Dec
(8) |
2007 |
Jan
(4) |
Feb
(3) |
Mar
(8) |
Apr
(16) |
May
(5) |
Jun
(4) |
Jul
(6) |
Aug
(23) |
Sep
(15) |
Oct
(5) |
Nov
(7) |
Dec
(5) |
2008 |
Jan
(5) |
Feb
(1) |
Mar
(1) |
Apr
(5) |
May
(1) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2012 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
(1) |
Jul
(1) |
Aug
(1) |
Sep
|
Oct
(2) |
Nov
(3) |
Dec
(2) |
2013 |
Jan
(1) |
Feb
|
Mar
(2) |
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(2) |
Jun
(1) |
Jul
|
Aug
(1) |
Sep
(1) |
Oct
|
Nov
(1) |
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2017 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <hib...@li...> - 2006-05-08 21:14:23
|
Author: max...@jb... Date: 2006-05-08 17:14:20 -0400 (Mon, 08 May 2006) New Revision: 9909 Modified: trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java Log: more complete "sum" type resolvement. Modified: trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java 2006-05-08 20:59:20 UTC (rev 9908) +++ trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java 2006-05-08 21:14:20 UTC (rev 9909) @@ -79,13 +79,6 @@ throw new QueryException( me ); } if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in avg()" ); - int sqlType = sqlTypes[0]; - /*pre H3.2 behavior if ( sqlType == Types.INTEGER || sqlType == Types.BIGINT || sqlType == Types.TINYINT ) { - return Hibernate.FLOAT; - } - else { - return columnType; - }*/ return Hibernate.DOUBLE; } } ); @@ -104,15 +97,26 @@ } if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in sum()" ); int sqlType = sqlTypes[0]; + + // First allow the actual type to control the return value. (the actual underlying sqltype could actually be different) if ( columnType == Hibernate.BIG_INTEGER ) { return Hibernate.BIG_INTEGER; } - if ( columnType == Hibernate.BIG_DECIMAL ) { + else if ( columnType == Hibernate.BIG_DECIMAL ) { return Hibernate.BIG_DECIMAL; } - if ( sqlType == Types.FLOAT || sqlType == Types.DOUBLE || sqlType == Types.NUMERIC ) { + else if ( columnType == Hibernate.FLOAT || columnType == Hibernate.DOUBLE) { return Hibernate.DOUBLE; - } else if ( sqlType == Types.INTEGER || sqlType == Types.SMALLINT || sqlType == Types.TINYINT ) { + } + + // finally use the sqltype if == on Hibernate types did not find a match. + if ( sqlType == Types.BIGINT) { + return Hibernate.BIG_INTEGER; + } + else if ( sqlType == Types.FLOAT || sqlType == Types.DOUBLE || sqlType == Types.NUMERIC || sqlType == Types.DECIMAL || sqlType == Types.REAL) { + return Hibernate.DOUBLE; + } + else if ( sqlType == Types.INTEGER || sqlType == Types.SMALLINT || sqlType == Types.TINYINT ) { return Hibernate.LONG; } else { |
Author: max...@jb... Date: 2006-05-08 16:59:20 -0400 (Mon, 08 May 2006) New Revision: 9908 Added: trunk/Hibernate3/src/org/hibernate/dialect/function/ClassicAvgFunction.java trunk/Hibernate3/src/org/hibernate/dialect/function/ClassicCountFunction.java trunk/Hibernate3/src/org/hibernate/dialect/function/ClassicSumFunction.java trunk/Hibernate3/src/org/hibernate/dialect/function/SQLFunctionRegistry.java Modified: trunk/Hibernate3/src/org/hibernate/cfg/Configuration.java trunk/Hibernate3/src/org/hibernate/criterion/AggregateProjection.java trunk/Hibernate3/src/org/hibernate/criterion/AvgProjection.java trunk/Hibernate3/src/org/hibernate/criterion/CountProjection.java trunk/Hibernate3/src/org/hibernate/criterion/RowCountProjection.java trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java trunk/Hibernate3/src/org/hibernate/engine/SessionFactoryImplementor.java trunk/Hibernate3/src/org/hibernate/hql/ast/util/SessionFactoryHelper.java trunk/Hibernate3/src/org/hibernate/hql/classic/SelectParser.java trunk/Hibernate3/src/org/hibernate/impl/SessionFactoryImpl.java trunk/Hibernate3/src/org/hibernate/mapping/Column.java trunk/Hibernate3/src/org/hibernate/mapping/Formula.java trunk/Hibernate3/src/org/hibernate/mapping/Selectable.java trunk/Hibernate3/src/org/hibernate/persister/collection/AbstractCollectionPersister.java trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java trunk/Hibernate3/src/org/hibernate/persister/entity/SingleTableEntityPersister.java trunk/Hibernate3/src/org/hibernate/sql/Template.java trunk/Hibernate3/src/org/hibernate/util/FilterHelper.java trunk/Hibernate3/test/org/hibernate/test/TestCase.java trunk/Hibernate3/test/org/hibernate/test/criteria/CriteriaQueryTest.java trunk/Hibernate3/test/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java trunk/Hibernate3/test/org/hibernate/test/hql/HQLTest.java trunk/Hibernate3/test/org/hibernate/test/hql/QueryTranslatorTestCase.java trunk/Hibernate3/test/org/hibernate/test/immutable/ImmutableTest.java trunk/Hibernate3/test/org/hibernate/test/legacy/SQLFunctionsTest.java trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java trunk/Hibernate3/test/org/hibernate/test/ops/SaveOrUpdateTest.java Log: Revert HHH-1724 Criteria/HQL alignment Fixed HHH-1727 SQLFunctionRegistry instead. Modified: trunk/Hibernate3/src/org/hibernate/cfg/Configuration.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/cfg/Configuration.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/cfg/Configuration.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -39,6 +39,7 @@ import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.MySQLDialect; +import org.hibernate.dialect.function.SQLFunction; import org.hibernate.engine.FilterDefinition; import org.hibernate.engine.Mapping; import org.hibernate.event.AutoFlushEventListener; @@ -121,6 +122,7 @@ protected Map collections; protected Map tables; protected List auxiliaryDatabaseObjects; + protected Map sqlFunctions; protected Map namedQueries; protected Map namedSqlQueries; /** @@ -171,10 +173,13 @@ tableNameBinding = new HashMap(); columnNameBindingPerTable = new HashMap(); namingStrategy = DefaultNamingStrategy.INSTANCE; + sqlFunctions = new HashMap(); } private transient Mapping mapping = buildMapping(); + + protected Configuration(SettingsFactory settingsFactory) { this.settingsFactory = settingsFactory; reset(); @@ -2011,4 +2016,12 @@ public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject object) { auxiliaryDatabaseObjects.add( object ); } + + public Map getSqlFunctions() { + return sqlFunctions; + } + + public void addSqlFunction(String functionName, SQLFunction function) { + sqlFunctions.put( functionName, function ); + } } Modified: trunk/Hibernate3/src/org/hibernate/criterion/AggregateProjection.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/criterion/AggregateProjection.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/criterion/AggregateProjection.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -3,8 +3,6 @@ import org.hibernate.Criteria; import org.hibernate.HibernateException; -import org.hibernate.dialect.function.SQLFunction; -import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.type.Type; /** @@ -27,22 +25,9 @@ public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - SessionFactoryImplementor factory = criteriaQuery.getFactory(); - Type type = criteriaQuery.getType(criteria, propertyName); - - SQLFunction function = findSQLFunction( factory, aggregate ); - - if(function==null) { - return new Type[] { type }; - } else { - return new Type[] { function.getReturnType( type, factory ) }; - } + return new Type[] { criteriaQuery.getType(criteria, propertyName) }; } - protected SQLFunction findSQLFunction(SessionFactoryImplementor sfi, String functionName) { - return ( SQLFunction ) sfi.getDialect().getFunctions().get( functionName.toLowerCase() ); - } - public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) throws HibernateException { return new StringBuffer() Modified: trunk/Hibernate3/src/org/hibernate/criterion/AvgProjection.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/criterion/AvgProjection.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/criterion/AvgProjection.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -1,6 +1,11 @@ //$Id$ package org.hibernate.criterion; +import org.hibernate.Criteria; +import org.hibernate.Hibernate; +import org.hibernate.HibernateException; +import org.hibernate.type.Type; + /** * @author Gavin King */ @@ -8,5 +13,10 @@ public AvgProjection(String propertyName) { super("avg", propertyName); - } + } + + public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) + throws HibernateException { + return new Type[] { Hibernate.DOUBLE }; + } } Modified: trunk/Hibernate3/src/org/hibernate/criterion/CountProjection.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/criterion/CountProjection.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/criterion/CountProjection.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -26,6 +26,11 @@ } } + public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) + throws HibernateException { + return new Type[] { Hibernate.LONG }; + } + public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) throws HibernateException { StringBuffer buf = new StringBuffer(); Modified: trunk/Hibernate3/src/org/hibernate/criterion/RowCountProjection.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/criterion/RowCountProjection.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/criterion/RowCountProjection.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -4,8 +4,6 @@ import org.hibernate.Criteria; import org.hibernate.Hibernate; import org.hibernate.HibernateException; -import org.hibernate.dialect.function.SQLFunction; -import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.type.Type; /** @@ -22,22 +20,9 @@ public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - SessionFactoryImplementor factory = criteriaQuery.getFactory(); - - Type type = Hibernate.LONG; - SQLFunction function = findSQLFunction( factory, "count" ); - - if(function==null) { - return new Type[] { type }; - } else { - return new Type[] { function.getReturnType( type, factory ) }; - } + return new Type[] { Hibernate.INTEGER }; } - protected SQLFunction findSQLFunction(SessionFactoryImplementor sfi, String functionName) { - return ( SQLFunction ) sfi.getDialect().getFunctions().get( functionName.toLowerCase() ); - } - public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) throws HibernateException { return new StringBuffer() Modified: trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -18,7 +18,6 @@ import org.hibernate.LockMode; import org.hibernate.MappingException; import org.hibernate.QueryException; -import org.hibernate.persister.entity.Lockable; import org.hibernate.cfg.Environment; import org.hibernate.dialect.function.CastFunction; import org.hibernate.dialect.function.SQLFunction; @@ -34,6 +33,7 @@ import org.hibernate.id.SequenceGenerator; import org.hibernate.id.TableHiLoGenerator; import org.hibernate.mapping.Column; +import org.hibernate.persister.entity.Lockable; import org.hibernate.sql.ANSICaseFragment; import org.hibernate.sql.ANSIJoinFragment; import org.hibernate.sql.CaseFragment; @@ -61,35 +61,7 @@ static final String NO_BATCH = "0"; private static final Map STANDARD_AGGREGATE_FUNCTIONS = new HashMap(); - - private static SQLFunction classicCount = new StandardSQLFunction("count") { - public Type getReturnType(Type columnType, Mapping mapping) { - return Hibernate.INTEGER; - } - }; - private static SQLFunction classicAvg = new StandardSQLFunction("avg") { - public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { - int[] sqlTypes; - try { - sqlTypes = columnType.sqlTypes( mapping ); - } - catch ( MappingException me ) { - throw new QueryException( me ); - } - if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in avg()" ); - int sqlType = sqlTypes[0]; - if ( sqlType == Types.INTEGER || sqlType == Types.BIGINT || sqlType == Types.TINYINT ) { - return Hibernate.FLOAT; - } - else { - return columnType; - } - } - }; - - private static SQLFunction classicSum = new StandardSQLFunction("sum"); - static { STANDARD_AGGREGATE_FUNCTIONS.put( "count", new StandardSQLFunction("count") { public Type getReturnType(Type columnType, Mapping mapping) { @@ -213,16 +185,6 @@ return getClass().getName(); } - /** Registers the pre 3.2 return types for count, avg and sum. - * Call this method in the constructor of your dialect subclass if you need - * the old types for aggregations. - **/ - protected void registerClassicAggregationTypes() { - sqlFunctions.put( "sum", classicSum ); - sqlFunctions.put( "avg", classicAvg ); - sqlFunctions.put( "count", classicCount ); - } - /** * Characters used for quoting SQL identifiers */ Added: trunk/Hibernate3/src/org/hibernate/dialect/function/ClassicAvgFunction.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/dialect/function/ClassicAvgFunction.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/dialect/function/ClassicAvgFunction.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -0,0 +1,42 @@ +/** + * + */ +package org.hibernate.dialect.function; + +import java.sql.Types; + +import org.hibernate.Hibernate; +import org.hibernate.MappingException; +import org.hibernate.QueryException; +import org.hibernate.engine.Mapping; +import org.hibernate.type.Type; + +/** + * Classic AVG sqlfunction that return types as it was done in Hibernate 3.1 + * + * @author Max Rydahl Andersen + * + */ +public class ClassicAvgFunction extends StandardSQLFunction { + public ClassicAvgFunction() { + super( "avg" ); + } + + public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { + int[] sqlTypes; + try { + sqlTypes = columnType.sqlTypes( mapping ); + } + catch ( MappingException me ) { + throw new QueryException( me ); + } + if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in avg()" ); + int sqlType = sqlTypes[0]; + if ( sqlType == Types.INTEGER || sqlType == Types.BIGINT || sqlType == Types.TINYINT ) { + return Hibernate.FLOAT; + } + else { + return columnType; + } + } +} \ No newline at end of file Added: trunk/Hibernate3/src/org/hibernate/dialect/function/ClassicCountFunction.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/dialect/function/ClassicCountFunction.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/dialect/function/ClassicCountFunction.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -0,0 +1,25 @@ +/** + * + */ +package org.hibernate.dialect.function; + +import org.hibernate.Hibernate; +import org.hibernate.engine.Mapping; +import org.hibernate.type.Type; + + +/** + * Classic COUNT sqlfunction that return types as it was done in Hibernate 3.1 + * + * @author Max Rydahl Andersen + * + */ +public class ClassicCountFunction extends StandardSQLFunction { + public ClassicCountFunction() { + super( "count" ); + } + + public Type getReturnType(Type columnType, Mapping mapping) { + return Hibernate.INTEGER; + } +} \ No newline at end of file Added: trunk/Hibernate3/src/org/hibernate/dialect/function/ClassicSumFunction.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/dialect/function/ClassicSumFunction.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/dialect/function/ClassicSumFunction.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -0,0 +1,17 @@ +/** + * + */ +package org.hibernate.dialect.function; + + +/** + * Classic SUM sqlfunction that return types as it was done in Hibernate 3.1 + * + * @author Max Rydahl Andersen + * + */ +public class ClassicSumFunction extends StandardSQLFunction { + public ClassicSumFunction() { + super( "sum" ); + } +} \ No newline at end of file Added: trunk/Hibernate3/src/org/hibernate/dialect/function/SQLFunctionRegistry.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/dialect/function/SQLFunctionRegistry.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/dialect/function/SQLFunctionRegistry.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -0,0 +1,33 @@ +package org.hibernate.dialect.function; + +import java.util.HashMap; +import java.util.Map; + +import org.hibernate.dialect.Dialect; + +public class SQLFunctionRegistry { + + private final Dialect dialect; + private final Map userFunctions; + + public SQLFunctionRegistry(Dialect dialect, Map userFunctions) { + this.dialect = dialect; + this.userFunctions = new HashMap(); + this.userFunctions.putAll( userFunctions ); + } + + public SQLFunction findSQLFunction(String functionName) { + String name = functionName.toLowerCase(); + SQLFunction userFunction = (SQLFunction) userFunctions.get( name ); + + return userFunction!=null?userFunction:(SQLFunction) dialect.getFunctions().get(name); // TODO: lowercasing done here. Was done "at random" before; maybe not needed at all ? + } + + public boolean hasFunction(String functionName) { + String name = functionName.toLowerCase(); + boolean hasUserFunction = userFunctions.containsKey ( name ); + + return hasUserFunction || dialect.getFunctions().containsKey ( name ); // TODO: toLowerCase was not done before. Only used in Template. + } + +} Modified: trunk/Hibernate3/src/org/hibernate/engine/SessionFactoryImplementor.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/engine/SessionFactoryImplementor.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/engine/SessionFactoryImplementor.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -165,5 +165,7 @@ public Set getCollectionRolesByEntityParticipant(String entityName); public EntityNotFoundDelegate getEntityNotFoundDelegate(); + + public SQLFunctionRegistry getSqlFunctionRegistry(); } Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/util/SessionFactoryHelper.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/util/SessionFactoryHelper.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/util/SessionFactoryHelper.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -339,7 +339,7 @@ * @return The sql function, or null if not found. */ public SQLFunction findSQLFunction(String functionName) { - return ( SQLFunction ) sfi.getDialect().getFunctions().get( functionName.toLowerCase() ); + return sfi.getSqlFunctionRegistry().findSQLFunction( functionName.toLowerCase() ); } /** Modified: trunk/Hibernate3/src/org/hibernate/hql/classic/SelectParser.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/classic/SelectParser.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/hql/classic/SelectParser.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -209,7 +209,7 @@ } private SQLFunction getFunction(String name, QueryTranslatorImpl q) { - return ( SQLFunction ) q.getFactory().getDialect().getFunctions().get( name ); + return q.getFactory().getSqlFunctionRegistry().findSQLFunction( name ); } public void start(QueryTranslatorImpl q) { Modified: trunk/Hibernate3/src/org/hibernate/impl/SessionFactoryImpl.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/impl/SessionFactoryImpl.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/impl/SessionFactoryImpl.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -30,35 +30,35 @@ import org.hibernate.HibernateException; import org.hibernate.Interceptor; import org.hibernate.MappingException; +import org.hibernate.ObjectNotFoundException; import org.hibernate.QueryException; import org.hibernate.SessionFactory; import org.hibernate.StatelessSession; -import org.hibernate.ObjectNotFoundException; -import org.hibernate.proxy.EntityNotFoundDelegate; -import org.hibernate.context.CurrentSessionContext; -import org.hibernate.context.ThreadLocalSessionContext; -import org.hibernate.context.JTASessionContext; -import org.hibernate.context.ManagedSessionContext; import org.hibernate.cache.Cache; import org.hibernate.cache.CacheConcurrencyStrategy; import org.hibernate.cache.CacheFactory; import org.hibernate.cache.CacheKey; +import org.hibernate.cache.OptimisticCache; import org.hibernate.cache.QueryCache; import org.hibernate.cache.UpdateTimestampsCache; -import org.hibernate.cache.OptimisticCache; import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; import org.hibernate.cfg.Settings; -import org.hibernate.cfg.Environment; import org.hibernate.connection.ConnectionProvider; +import org.hibernate.context.CurrentSessionContext; +import org.hibernate.context.JTASessionContext; +import org.hibernate.context.ManagedSessionContext; +import org.hibernate.context.ThreadLocalSessionContext; import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.function.SQLFunctionRegistry; import org.hibernate.engine.FilterDefinition; import org.hibernate.engine.Mapping; import org.hibernate.engine.NamedQueryDefinition; import org.hibernate.engine.NamedSQLQueryDefinition; import org.hibernate.engine.ResultSetMappingDefinition; import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.query.NativeSQLQuerySpecification; import org.hibernate.engine.query.QueryPlanCache; -import org.hibernate.engine.query.NativeSQLQuerySpecification; import org.hibernate.event.EventListeners; import org.hibernate.exception.SQLExceptionConverter; import org.hibernate.id.IdentifierGenerator; @@ -74,6 +74,7 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Queryable; import org.hibernate.pretty.MessageHelper; +import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.stat.Statistics; import org.hibernate.stat.StatisticsImpl; import org.hibernate.stat.StatisticsImplementor; @@ -85,7 +86,6 @@ import org.hibernate.type.Type; import org.hibernate.util.CollectionHelper; import org.hibernate.util.ReflectHelper; -import org.hibernate.util.SerializationHelper; /** @@ -140,10 +140,12 @@ private final transient EventListeners eventListeners; private final transient CurrentSessionContext currentSessionContext; private final transient EntityNotFoundDelegate entityNotFoundDelegate; - + private final transient SQLFunctionRegistry sqlFunctionRegistry; + private final QueryPlanCache queryPlanCache = new QueryPlanCache( this ); private transient boolean isClosed = false; + private static final IdentifierGenerator UUID_GENERATOR = new UUIDHexGenerator(); @@ -162,6 +164,7 @@ this.properties.putAll( cfg.getProperties() ); this.interceptor = cfg.getInterceptor(); this.settings = settings; + this.sqlFunctionRegistry = new SQLFunctionRegistry(settings.getDialect(), cfg.getSqlFunctions()); this.eventListeners = listeners; this.filters = new HashMap(); this.filters.putAll( cfg.getFilterDefinitions() ); @@ -1039,4 +1042,8 @@ } return ( SessionFactoryImpl ) result; } + + public SQLFunctionRegistry getSqlFunctionRegistry() { + return sqlFunctionRegistry; + } } Modified: trunk/Hibernate3/src/org/hibernate/mapping/Column.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/mapping/Column.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/mapping/Column.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -6,6 +6,7 @@ import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.function.SQLFunctionRegistry; import org.hibernate.engine.Mapping; import org.hibernate.util.StringHelper; @@ -235,7 +236,7 @@ return checkConstraint!=null; } - public String getTemplate(Dialect dialect) { + public String getTemplate(Dialect dialect, SQLFunctionRegistry functionRegistry) { return getQuotedName(dialect); } Modified: trunk/Hibernate3/src/org/hibernate/mapping/Formula.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/mapping/Formula.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/mapping/Formula.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -4,6 +4,7 @@ import java.io.Serializable; import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.function.SQLFunctionRegistry; import org.hibernate.sql.Template; /** @@ -20,8 +21,8 @@ uniqueInteger = formulaUniqueInteger++; } - public String getTemplate(Dialect dialect) { - return Template.renderWhereStringTemplate(formula, dialect); + public String getTemplate(Dialect dialect, SQLFunctionRegistry functionRegistry) { + return Template.renderWhereStringTemplate(formula, dialect, functionRegistry); } public String getText(Dialect dialect) { return getFormula(); Modified: trunk/Hibernate3/src/org/hibernate/mapping/Selectable.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/mapping/Selectable.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/mapping/Selectable.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -2,12 +2,13 @@ package org.hibernate.mapping; import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.function.SQLFunctionRegistry; public interface Selectable { public String getAlias(Dialect dialect); public String getAlias(Dialect dialect, Table table); public boolean isFormula(); - public String getTemplate(Dialect dialect); + public String getTemplate(Dialect dialect, SQLFunctionRegistry functionRegistry); public String getText(Dialect dialect); public String getText(); } Modified: trunk/Hibernate3/src/org/hibernate/persister/collection/AbstractCollectionPersister.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/persister/collection/AbstractCollectionPersister.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/persister/collection/AbstractCollectionPersister.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -241,12 +241,12 @@ sqlOrderByString = collection.getOrderBy(); hasOrder = sqlOrderByString != null; sqlOrderByStringTemplate = hasOrder ? - Template.renderOrderByStringTemplate(sqlOrderByString, dialect) : + Template.renderOrderByStringTemplate(sqlOrderByString, dialect, factory.getSqlFunctionRegistry()) : null; sqlWhereString = collection.getWhere(); hasWhere = sqlWhereString != null; sqlWhereStringTemplate = hasWhere ? - Template.renderWhereStringTemplate(sqlWhereString, dialect) : + Template.renderWhereStringTemplate(sqlWhereString, dialect, factory.getSqlFunctionRegistry()) : null; hasOrphanDelete = collection.hasOrphanDelete(); @@ -310,7 +310,7 @@ elementColumnAliases[j] = selectable.getAlias(dialect); if ( selectable.isFormula() ) { Formula form = (Formula) selectable; - elementFormulaTemplates[j] = form.getTemplate(dialect); + elementFormulaTemplates[j] = form.getTemplate(dialect, factory.getSqlFunctionRegistry()); elementFormulas[j] = form.getFormula(); } else { @@ -356,7 +356,7 @@ indexColumnAliases[i] = s.getAlias(dialect); if ( s.isFormula() ) { Formula indexForm = (Formula) s; - indexFormulaTemplates[i] = indexForm.getTemplate(dialect); + indexFormulaTemplates[i] = indexForm.getTemplate(dialect, factory.getSqlFunctionRegistry()); indexFormulas[i] = indexForm.getFormula(); hasFormula = true; } @@ -497,18 +497,18 @@ } // Handle any filters applied to this collection - filterHelper = new FilterHelper( collection.getFilterMap(), dialect ); + filterHelper = new FilterHelper( collection.getFilterMap(), dialect, factory.getSqlFunctionRegistry() ); // Handle any filters applied to this collection for many-to-many - manyToManyFilterHelper = new FilterHelper( collection.getManyToManyFilterMap(), dialect ); + manyToManyFilterHelper = new FilterHelper( collection.getManyToManyFilterMap(), dialect, factory.getSqlFunctionRegistry() ); manyToManyWhereString = collection.getManyToManyWhere(); manyToManyWhereTemplate = manyToManyWhereString == null ? null : - Template.renderWhereStringTemplate( manyToManyWhereString, factory.getDialect() ); + Template.renderWhereStringTemplate( manyToManyWhereString, factory.getDialect(), factory.getSqlFunctionRegistry() ); manyToManyOrderByString = collection.getManyToManyOrdering(); manyToManyOrderByTemplate = manyToManyOrderByString == null ? null - : Template.renderOrderByStringTemplate( manyToManyOrderByString, factory.getDialect() ); + : Template.renderOrderByStringTemplate( manyToManyOrderByString, factory.getDialect(), factory.getSqlFunctionRegistry() ); initCollectionPropertyMap(); } Modified: trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -469,7 +469,7 @@ sqlWhereString = persistentClass.getWhere(); sqlWhereStringTemplate = sqlWhereString == null ? null : - Template.renderWhereStringTemplate( sqlWhereString, factory.getDialect() ); + Template.renderWhereStringTemplate( sqlWhereString, factory.getDialect(), factory.getSqlFunctionRegistry() ); // PROPERTIES @@ -513,10 +513,10 @@ colAliases[k] = thing.getAlias( factory.getDialect() , prop.getValue().getTable() ); if ( thing.isFormula() ) { foundFormula = true; - templates[k] = thing.getTemplate( factory.getDialect() ); + templates[k] = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() ); } else { - colNames[k] = thing.getTemplate( factory.getDialect() ); + colNames[k] = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() ); } k++; } @@ -590,7 +590,7 @@ while ( colIter.hasNext() ) { Selectable thing = ( Selectable ) colIter.next(); if ( thing.isFormula() ) { - String template = thing.getTemplate( factory.getDialect() ); + String template = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() ); formnos[l] = formulaTemplates.size(); colnos[l] = -1; formulaTemplates.add( template ); @@ -600,7 +600,7 @@ formulasLazy.add( lazy ); } else { - String colName = thing.getTemplate( factory.getDialect() ); + String colName = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() ); colnos[l] = columns.size(); //before add :-) formnos[l] = -1; columns.add( colName ); @@ -659,7 +659,7 @@ } // Handle any filters applied to the class level - filterHelper = new FilterHelper( persistentClass.getFilterMap(), factory.getDialect() ); + filterHelper = new FilterHelper( persistentClass.getFilterMap(), factory.getDialect(), factory.getSqlFunctionRegistry() ); temporaryIdTableName = persistentClass.getTemporaryIdTableName(); temporaryIdTableDDL = persistentClass.getTemporaryIdTableDDL(); @@ -2220,7 +2220,7 @@ final PreparedStatement update; if ( callable ) { CallableStatement callstatement = session.getBatcher().prepareCallableStatement( sql ); - callstatement.registerOutParameter( index++, Types.INTEGER ); // TODO: should we require users to return number of update rows ? + callstatement.registerOutParameter( index++, Types.NUMERIC ); // TODO: should we require users to return number of update rows ? (NUMERIC) update = callstatement; } else if ( useBatch ) { @@ -2267,13 +2267,11 @@ if ( useBatch ) { session.getBatcher().addToBatch( 1 ); return true; - } else if (!callable) { + } + else { return check( update.executeUpdate(), id, j ); - } else { - update.executeUpdate(); - CallableStatement cd = (CallableStatement)update; - return check( cd.getInt(1), id, j); } + } catch ( SQLException sqle ) { if ( useBatch ) { @@ -2338,7 +2336,7 @@ int index = 1; if ( callable ) { CallableStatement callstatement = session.getBatcher().prepareCallableStatement( sql ); - callstatement.registerOutParameter( index++, Types.INTEGER); // TODO: should we require users to return number of deleted rows ? + callstatement.registerOutParameter( index++, Types.NUMERIC ); // TODO: should we require users to return number of deleted rows ? delete = callstatement; } else if ( useBatch ) { @@ -2364,12 +2362,8 @@ if ( useBatch ) { session.getBatcher().addToBatch( 1 ); } - else if(!callable) { + else { check( delete.executeUpdate(), id, j ); - } else { - delete.executeUpdate(); - CallableStatement cd = (CallableStatement)delete; - check( cd.getInt(1), id, j); } } Modified: trunk/Hibernate3/src/org/hibernate/persister/entity/SingleTableEntityPersister.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/persister/entity/SingleTableEntityPersister.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/persister/entity/SingleTableEntityPersister.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -248,7 +248,7 @@ if ( discrimValue.hasFormula() ) { Formula formula = (Formula) selectable; discriminatorFormula = formula.getFormula(); - discriminatorFormulaTemplate = formula.getTemplate( factory.getDialect() ); + discriminatorFormulaTemplate = formula.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() ); discriminatorColumnName = null; discriminatorAlias = "clazz_"; } Modified: trunk/Hibernate3/src/org/hibernate/sql/Template.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/sql/Template.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/sql/Template.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -5,6 +5,7 @@ import java.util.StringTokenizer; import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.function.SQLFunctionRegistry; import org.hibernate.util.StringHelper; /** @@ -66,8 +67,8 @@ private Template() {} - public static String renderWhereStringTemplate(String sqlWhereString, Dialect dialect) { - return renderWhereStringTemplate(sqlWhereString, TEMPLATE, dialect); + public static String renderWhereStringTemplate(String sqlWhereString, Dialect dialect, SQLFunctionRegistry functionRegistry) { + return renderWhereStringTemplate(sqlWhereString, TEMPLATE, dialect, functionRegistry); } /** @@ -75,7 +76,7 @@ * Handles subselects, quoted identifiers, quoted strings, expressions, SQL functions, * named parameters. */ - public static String renderWhereStringTemplate(String sqlWhereString, String placeholder, Dialect dialect) { + public static String renderWhereStringTemplate(String sqlWhereString, String placeholder, Dialect dialect, SQLFunctionRegistry functionRegistry ) { //TODO: make this a bit nicer String symbols = new StringBuffer() .append("=><!+-*/()',|&`") @@ -160,7 +161,7 @@ } else if ( isIdentifier(token, dialect) && - !isFunctionOrKeyword(lcToken, nextToken, dialect) + !isFunctionOrKeyword(lcToken, nextToken, dialect , functionRegistry) ) { result.append(placeholder) .append('.') @@ -193,7 +194,7 @@ * Takes order by clause provided in the mapping attribute and interpolates the alias. * Handles asc, desc, SQL functions, quoted identifiers. */ - public static String renderOrderByStringTemplate(String sqlOrderByString, Dialect dialect) { + public static String renderOrderByStringTemplate(String sqlOrderByString, Dialect dialect, SQLFunctionRegistry functionRegistry) { //TODO: make this a bit nicer String symbols = new StringBuffer() .append("=><!+-*/()',|&`") @@ -263,7 +264,7 @@ } else if ( isIdentifier(token, dialect) && - !isFunctionOrKeyword(lcToken, nextToken, dialect) + !isFunctionOrKeyword(lcToken, nextToken, dialect, functionRegistry) ) { result.append(TEMPLATE) .append('.') @@ -280,10 +281,10 @@ return token.startsWith(":"); } - private static boolean isFunctionOrKeyword(String lcToken, String nextToken, Dialect dialect) { + private static boolean isFunctionOrKeyword(String lcToken, String nextToken, Dialect dialect, SQLFunctionRegistry functionRegistry) { return "(".equals(nextToken) || KEYWORDS.contains(lcToken) || - dialect.getFunctions().containsKey(lcToken) || + functionRegistry.hasFunction(lcToken) || dialect.getKeywords().contains(lcToken) || FUNCTION_KEYWORDS.contains(lcToken); } Modified: trunk/Hibernate3/src/org/hibernate/util/FilterHelper.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/util/FilterHelper.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/src/org/hibernate/util/FilterHelper.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -4,6 +4,7 @@ import org.hibernate.sql.Template; import org.hibernate.impl.FilterImpl; import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.function.SQLFunctionRegistry; import java.util.Map; import java.util.Iterator; @@ -25,8 +26,9 @@ * * @param filters The map of defined filters. * @param dialect The sql dialect + * @param functionRegistry The SQL function registry */ - public FilterHelper(Map filters, Dialect dialect) { + public FilterHelper(Map filters, Dialect dialect, SQLFunctionRegistry functionRegistry) { int filterCount = filters.size(); filterNames = new String[filterCount]; filterConditions = new String[filterCount]; @@ -38,7 +40,8 @@ filterConditions[filterCount] = Template.renderWhereStringTemplate( (String) entry.getValue(), FilterImpl.MARKER, - dialect + dialect, + functionRegistry ); filterConditions[filterCount] = StringHelper.replace( filterConditions[filterCount], ":", Modified: trunk/Hibernate3/test/org/hibernate/test/TestCase.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/TestCase.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/test/org/hibernate/test/TestCase.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -68,11 +68,10 @@ cfg.setProperty(Environment.HBM2DDL_AUTO, "create-drop"); } - for (int i=0; i<files.length; i++) { - if ( !files[i].startsWith("net/") ) files[i] = getBaseForMappings() + files[i]; - getCfg().addResource( files[i], TestCase.class.getClassLoader() ); - } + Configuration cfg2 = getCfg(); + addMappings( files, cfg2 ); + configure(cfg); if ( getCacheConcurrencyStrategy()!=null ) { @@ -109,7 +108,7 @@ } - setSessions( getCfg().buildSessionFactory( /*new TestInterceptor()*/ ) ); + setSessions( cfg2.buildSessionFactory( /*new TestInterceptor()*/ ) ); afterSessionFactoryBuilt(); } @@ -119,6 +118,13 @@ } } + protected void addMappings(String[] files, Configuration cfg) { + for (int i=0; i<files.length; i++) { + if ( !files[i].startsWith("net/") ) files[i] = getBaseForMappings() + files[i]; + cfg.addResource( files[i], TestCase.class.getClassLoader() ); + } + } + protected void afterSessionFactoryBuilt() throws Exception { // for subclasses to override in order to perform extra "stuff" only // when SF (re)built... Modified: trunk/Hibernate3/test/org/hibernate/test/criteria/CriteriaQueryTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/criteria/CriteriaQueryTest.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/test/org/hibernate/test/criteria/CriteriaQueryTest.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -319,10 +319,10 @@ //s.flush(); - Long count = (Long) s.createCriteria(Enrolment.class) + Integer count = (Integer) s.createCriteria(Enrolment.class) .setProjection( Projections.count("studentNumber").setDistinct() ) .uniqueResult(); - assertEquals(count, new Long(2)); + assertEquals(count, new Integer(2)); Object object = s.createCriteria(Enrolment.class) .setProjection( Projections.projectionList() @@ -334,7 +334,7 @@ .uniqueResult(); Object[] result = (Object[])object; - assertEquals(new Long(2),result[0]); + assertEquals(new Integer(2),result[0]); assertEquals(new Long(667),result[1]); assertEquals(new Long(101),result[2]); assertEquals( 384.0, ( (Double) result[3] ).doubleValue(), 0.01 ); @@ -493,10 +493,10 @@ s.flush(); - Long count = (Long) s.createCriteria(Enrolment.class) + Integer count = (Integer) s.createCriteria(Enrolment.class) .setProjection( Property.forName("studentNumber").count().setDistinct() ) .uniqueResult(); - assertEquals(count, new Long(2)); + assertEquals(count, new Integer(2)); Object object = s.createCriteria(Enrolment.class) .setProjection( Projections.projectionList() @@ -508,7 +508,7 @@ .uniqueResult(); Object[] result = (Object[])object; - assertEquals(new Long(2),result[0]); + assertEquals(new Integer(2),result[0]); assertEquals(new Long(667),result[1]); assertEquals(new Long(101),result[2]); assertEquals(384.0, ( (Double) result[3] ).doubleValue(), 0.01); Modified: trunk/Hibernate3/test/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/test/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -1,41 +1,23 @@ //$Id: HQLTest.java 9873 2006-05-04 13:42:48Z max...@jb... $ package org.hibernate.test.hql; -import java.io.PrintWriter; -import java.io.StringWriter; import java.math.BigDecimal; import java.math.BigInteger; -import java.util.*; import junit.framework.Test; import junit.framework.TestSuite; +import org.hibernate.Hibernate; +import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; import org.hibernate.criterion.Projections; -import org.hibernate.dialect.DB2Dialect; -import org.hibernate.dialect.HSQLDialect; -import org.hibernate.dialect.MySQLDialect; -import org.hibernate.dialect.Oracle9Dialect; -import org.hibernate.dialect.PostgreSQLDialect; -import org.hibernate.dialect.function.SQLFunction; -import org.hibernate.hql.ast.DetailedSemanticException; -import org.hibernate.hql.ast.QuerySyntaxException; -import org.hibernate.hql.ast.ASTQueryTranslatorFactory; +import org.hibernate.dialect.function.ClassicAvgFunction; +import org.hibernate.dialect.function.ClassicCountFunction; +import org.hibernate.dialect.function.ClassicSumFunction; +import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.hql.ast.QueryTranslatorImpl; -import org.hibernate.hql.ast.tree.ConstructorNode; -import org.hibernate.hql.ast.tree.DotNode; -import org.hibernate.hql.ast.tree.IndexNode; import org.hibernate.hql.ast.tree.SelectClause; -import org.hibernate.hql.QueryTranslatorFactory; -import org.hibernate.hql.QueryTranslator; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.query.HQLQueryPlan; -import org.hibernate.engine.query.ReturnMetadata; -import org.hibernate.Criteria; -import org.hibernate.Hibernate; -import antlr.RecognitionException; - /** * Tests cases for ensuring alignment between HQL and Criteria behavior. * @@ -117,7 +99,8 @@ assertEquals( "incorrect return type", Hibernate.BIG_DECIMAL, translator.getReturnTypes()[0] ); } - public void testCriteriaAggregationReturnType() { + // HHH-1724 Align Criteria with HQL aggregation return types. + public void testCriteriaAggregationReturnTypeFailureExpected() { Session s = openSession(); Human human = new Human(); human.setBigIntegerValue( new BigInteger("42") ); @@ -174,6 +157,72 @@ s.close(); } + public void testClassicTypes() { + Configuration classicCfg = new Configuration(); + classicCfg.addSqlFunction( "count", new ClassicCountFunction()); + classicCfg.addSqlFunction( "avg", new ClassicAvgFunction()); + classicCfg.addSqlFunction( "sum", new ClassicSumFunction()); + + addMappings(getMappings(), classicCfg); + SessionFactoryImplementor factory = (SessionFactoryImplementor) classicCfg.buildSessionFactory(); + + // EJB3: COUNT returns Long + QueryTranslatorImpl translator = createNewQueryTranslator( "select count(*) from Human h", factory ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.INTEGER, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select count(h.height) from Human h", factory ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.INTEGER, translator.getReturnTypes()[0] ); + + // MAX, MIN return the type of the state-field to which they are applied. + translator = createNewQueryTranslator( "select max(h.height) from Human h", factory ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select max(h.id) from Human h", factory ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.LONG, translator.getReturnTypes()[0] ); + + // AVG returns Float integrals, and otherwise the field type. + translator = createNewQueryTranslator( "select avg(h.height) from Human h", factory ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select avg(h.id) from Human h", factory ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.FLOAT, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select avg(h.bigIntegerValue) from Human h", factory ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.BIG_INTEGER, translator.getReturnTypes()[0] ); + + // SUM returns underlying type sum + translator = createNewQueryTranslator( "select sum(h.id) from Human h", factory ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.LONG, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select sum(h.intValue) from Human h", factory ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.INTEGER, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select sum(h.height) from Human h", factory ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select sum(h.floatValue) from Human h", factory ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.FLOAT, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select sum(h.bigIntegerValue) from Human h", factory ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.BIG_INTEGER, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select sum(h.bigDecimalValue) from Human h", factory ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.BIG_DECIMAL, translator.getReturnTypes()[0] ); + } + public static Test suite() { return new TestSuite( CriteriaHQLAlignmentTest.class ); } Modified: trunk/Hibernate3/test/org/hibernate/test/hql/HQLTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/HQLTest.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/test/org/hibernate/test/hql/HQLTest.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -571,7 +571,7 @@ assertTranslation( "from Animal an where an.bodyWeight > abs(3/5)" ); assertTranslation( "from Animal an where an.bodyWeight > abs(3+5)" ); assertTranslation( "from Animal an where an.bodyWeight > abs(3*5)" ); - SQLFunction concat = (SQLFunction) getDialect().getFunctions().get("concat"); + SQLFunction concat = getSessionFactoryImplementor().getSqlFunctionRegistry().findSQLFunction( "concat"); List list = new ArrayList(); list.add("'fat'"); list.add("'skinny'"); assertTranslation( "from Animal an where an.description = " + concat.render(list, getSessionFactoryImplementor()) ); } Modified: trunk/Hibernate3/test/org/hibernate/test/hql/QueryTranslatorTestCase.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/QueryTranslatorTestCase.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/test/org/hibernate/test/hql/QueryTranslatorTestCase.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -150,6 +150,10 @@ protected QueryTranslatorImpl createNewQueryTranslator(String hql, HashMap replacements, boolean scalar) { SessionFactoryImplementor factory = getSessionFactoryImplementor(); + return createNewQueryTranslator( hql, replacements, scalar, factory ); + } + + private QueryTranslatorImpl createNewQueryTranslator(String hql, HashMap replacements, boolean scalar, SessionFactoryImplementor factory) { QueryTranslatorFactory ast = new ASTQueryTranslatorFactory(); QueryTranslatorImpl newQueryTranslator = ( QueryTranslatorImpl ) ast.createQueryTranslator( hql, hql, Collections.EMPTY_MAP, factory ); newQueryTranslator.compile( replacements, scalar ); @@ -160,6 +164,10 @@ return createNewQueryTranslator( hql, new HashMap(), false ); } + protected QueryTranslatorImpl createNewQueryTranslator(String hql, SessionFactoryImplementor sfimpl) { + return createNewQueryTranslator( hql, new HashMap(), false, sfimpl ); + } + protected HQLQueryPlan createQueryPlan(String hql, boolean scalar) { return new HQLQueryPlan( hql, scalar, Collections.EMPTY_MAP, getSessionFactoryImplementor() ); } Modified: trunk/Hibernate3/test/org/hibernate/test/immutable/ImmutableTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/immutable/ImmutableTest.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/test/org/hibernate/test/immutable/ImmutableTest.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -44,8 +44,8 @@ cv1 = (ContractVariation) c.getVariations().iterator().next(); assertEquals( cv1.getText(), "expensive" ); s.delete(c); - assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Long(0) ); - assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Long(0) ); + assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) ); + assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) ); t.commit(); s.close(); } Modified: trunk/Hibernate3/test/org/hibernate/test/legacy/SQLFunctionsTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/legacy/SQLFunctionsTest.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/test/org/hibernate/test/legacy/SQLFunctionsTest.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -29,6 +29,7 @@ import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.TimesTenDialect; import org.hibernate.dialect.function.SQLFunction; +import org.hibernate.engine.SessionFactoryImplementor; public class SQLFunctionsTest extends LegacyTestCase { Modified: trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -262,7 +262,7 @@ s.createCriteria(NumberedNode.class) .setProjection( Projections.rowCount() ) .uniqueResult(), - new Long(2) + new Integer(2) ); s.delete(root); s.delete(mergedChild); Modified: trunk/Hibernate3/test/org/hibernate/test/ops/SaveOrUpdateTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/ops/SaveOrUpdateTest.java 2006-05-08 17:41:21 UTC (rev 9907) +++ trunk/Hibernate3/test/org/hibernate/test/ops/SaveOrUpdateTest.java 2006-05-08 20:59:20 UTC (rev 9908) @@ -242,7 +242,7 @@ s.createCriteria( NumberedNode.class ) .setProjection( Projections.rowCount() ) .uniqueResult(), - new Long( 2 ) + new Integer( 2 ) ); s.delete( root ); s.delete( child ); @@ -299,7 +299,7 @@ s.createCriteria( NumberedNode.class ) .setProjection( Projections.rowCount() ) .uniqueResult(), - new Long( 2 ) + new Integer( 2 ) ); s.delete( root ); s.delete( child ); @@ -353,7 +353,7 @@ s.createCriteria( Node.class ) .setProjection( Projections.rowCount() ) .uniqueResult(), - new Long( 2 ) + new Integer( 2 ) ); s.delete( root ); s.delete( child ); |
From: <hib...@li...> - 2006-05-08 17:41:38
|
Author: max...@jb... Date: 2006-05-08 13:41:21 -0400 (Mon, 08 May 2006) New Revision: 9907 Added: trunk/Hibernate3/test/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java Modified: trunk/Hibernate3/src/org/hibernate/criterion/AggregateProjection.java trunk/Hibernate3/src/org/hibernate/criterion/AvgProjection.java trunk/Hibernate3/src/org/hibernate/criterion/CountProjection.java trunk/Hibernate3/src/org/hibernate/criterion/RowCountProjection.java trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java trunk/Hibernate3/src/org/hibernate/engine/SessionFactoryImplementor.java trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java trunk/Hibernate3/test/org/hibernate/test/TestCase.java trunk/Hibernate3/test/org/hibernate/test/criteria/CriteriaQueryTest.java trunk/Hibernate3/test/org/hibernate/test/hql/HQLSuite.java trunk/Hibernate3/test/org/hibernate/test/hql/HQLTest.java trunk/Hibernate3/test/org/hibernate/test/immutable/ImmutableTest.java trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java trunk/Hibernate3/test/org/hibernate/test/ops/SaveOrUpdateTest.java Log: HHH-1724 Critieria needs to be aligned with new aggreation type rules. Done by having Criterion looking up SQLFunction via the dialect (before Criteria and HQL were seperately maintained) + added (optional) assertDataIsRemoved test function + fixed aggregation type tests. Modified: trunk/Hibernate3/src/org/hibernate/criterion/AggregateProjection.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/criterion/AggregateProjection.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/src/org/hibernate/criterion/AggregateProjection.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -3,6 +3,8 @@ import org.hibernate.Criteria; import org.hibernate.HibernateException; +import org.hibernate.dialect.function.SQLFunction; +import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.type.Type; /** @@ -25,9 +27,22 @@ public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return new Type[] { criteriaQuery.getType(criteria, propertyName) }; + SessionFactoryImplementor factory = criteriaQuery.getFactory(); + Type type = criteriaQuery.getType(criteria, propertyName); + + SQLFunction function = findSQLFunction( factory, aggregate ); + + if(function==null) { + return new Type[] { type }; + } else { + return new Type[] { function.getReturnType( type, factory ) }; + } } + protected SQLFunction findSQLFunction(SessionFactoryImplementor sfi, String functionName) { + return ( SQLFunction ) sfi.getDialect().getFunctions().get( functionName.toLowerCase() ); + } + public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) throws HibernateException { return new StringBuffer() Modified: trunk/Hibernate3/src/org/hibernate/criterion/AvgProjection.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/criterion/AvgProjection.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/src/org/hibernate/criterion/AvgProjection.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -1,11 +1,6 @@ //$Id$ package org.hibernate.criterion; -import org.hibernate.Criteria; -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; -import org.hibernate.type.Type; - /** * @author Gavin King */ @@ -13,10 +8,5 @@ public AvgProjection(String propertyName) { super("avg", propertyName); - } - - public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) - throws HibernateException { - return new Type[] { Hibernate.DOUBLE }; - } + } } Modified: trunk/Hibernate3/src/org/hibernate/criterion/CountProjection.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/criterion/CountProjection.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/src/org/hibernate/criterion/CountProjection.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -26,11 +26,6 @@ } } - public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) - throws HibernateException { - return new Type[] { Hibernate.INTEGER }; - } - public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) throws HibernateException { StringBuffer buf = new StringBuffer(); Modified: trunk/Hibernate3/src/org/hibernate/criterion/RowCountProjection.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/criterion/RowCountProjection.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/src/org/hibernate/criterion/RowCountProjection.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -4,6 +4,8 @@ import org.hibernate.Criteria; import org.hibernate.Hibernate; import org.hibernate.HibernateException; +import org.hibernate.dialect.function.SQLFunction; +import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.type.Type; /** @@ -20,9 +22,22 @@ public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { - return new Type[] { Hibernate.INTEGER }; + SessionFactoryImplementor factory = criteriaQuery.getFactory(); + + Type type = Hibernate.LONG; + SQLFunction function = findSQLFunction( factory, "count" ); + + if(function==null) { + return new Type[] { type }; + } else { + return new Type[] { function.getReturnType( type, factory ) }; + } } + protected SQLFunction findSQLFunction(SessionFactoryImplementor sfi, String functionName) { + return ( SQLFunction ) sfi.getDialect().getFunctions().get( functionName.toLowerCase() ); + } + public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) throws HibernateException { return new StringBuffer() Modified: trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/src/org/hibernate/dialect/Dialect.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -62,6 +62,34 @@ private static final Map STANDARD_AGGREGATE_FUNCTIONS = new HashMap(); + private static SQLFunction classicCount = new StandardSQLFunction("count") { + public Type getReturnType(Type columnType, Mapping mapping) { + return Hibernate.INTEGER; + } + }; + + private static SQLFunction classicAvg = new StandardSQLFunction("avg") { + public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { + int[] sqlTypes; + try { + sqlTypes = columnType.sqlTypes( mapping ); + } + catch ( MappingException me ) { + throw new QueryException( me ); + } + if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in avg()" ); + int sqlType = sqlTypes[0]; + if ( sqlType == Types.INTEGER || sqlType == Types.BIGINT || sqlType == Types.TINYINT ) { + return Hibernate.FLOAT; + } + else { + return columnType; + } + } + }; + + private static SQLFunction classicSum = new StandardSQLFunction("sum"); + static { STANDARD_AGGREGATE_FUNCTIONS.put( "count", new StandardSQLFunction("count") { public Type getReturnType(Type columnType, Mapping mapping) { @@ -104,9 +132,15 @@ } if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in sum()" ); int sqlType = sqlTypes[0]; - if ( sqlType == Types.FLOAT || sqlType == Types.DOUBLE ) { + if ( columnType == Hibernate.BIG_INTEGER ) { + return Hibernate.BIG_INTEGER; + } + if ( columnType == Hibernate.BIG_DECIMAL ) { + return Hibernate.BIG_DECIMAL; + } + if ( sqlType == Types.FLOAT || sqlType == Types.DOUBLE || sqlType == Types.NUMERIC ) { return Hibernate.DOUBLE; - } else if ( sqlType == Types.INTEGER || sqlType == Types.SMALLINT ) { + } else if ( sqlType == Types.INTEGER || sqlType == Types.SMALLINT || sqlType == Types.TINYINT ) { return Hibernate.LONG; } else { @@ -179,6 +213,16 @@ return getClass().getName(); } + /** Registers the pre 3.2 return types for count, avg and sum. + * Call this method in the constructor of your dialect subclass if you need + * the old types for aggregations. + **/ + protected void registerClassicAggregationTypes() { + sqlFunctions.put( "sum", classicSum ); + sqlFunctions.put( "avg", classicAvg ); + sqlFunctions.put( "count", classicCount ); + } + /** * Characters used for quoting SQL identifiers */ Modified: trunk/Hibernate3/src/org/hibernate/engine/SessionFactoryImplementor.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/engine/SessionFactoryImplementor.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/src/org/hibernate/engine/SessionFactoryImplementor.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -22,6 +22,7 @@ import org.hibernate.cfg.Settings; import org.hibernate.connection.ConnectionProvider; import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.function.SQLFunctionRegistry; import org.hibernate.exception.SQLExceptionConverter; import org.hibernate.id.IdentifierGenerator; import org.hibernate.stat.StatisticsImplementor; @@ -164,4 +165,5 @@ public Set getCollectionRolesByEntityParticipant(String entityName); public EntityNotFoundDelegate getEntityNotFoundDelegate(); + } Modified: trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/src/org/hibernate/persister/entity/AbstractEntityPersister.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -2220,7 +2220,7 @@ final PreparedStatement update; if ( callable ) { CallableStatement callstatement = session.getBatcher().prepareCallableStatement( sql ); - callstatement.registerOutParameter( index++, Types.NUMERIC ); // TODO: should we require users to return number of update rows ? + callstatement.registerOutParameter( index++, Types.INTEGER ); // TODO: should we require users to return number of update rows ? update = callstatement; } else if ( useBatch ) { @@ -2267,11 +2267,13 @@ if ( useBatch ) { session.getBatcher().addToBatch( 1 ); return true; - } - else { + } else if (!callable) { return check( update.executeUpdate(), id, j ); + } else { + update.executeUpdate(); + CallableStatement cd = (CallableStatement)update; + return check( cd.getInt(1), id, j); } - } catch ( SQLException sqle ) { if ( useBatch ) { @@ -2336,7 +2338,7 @@ int index = 1; if ( callable ) { CallableStatement callstatement = session.getBatcher().prepareCallableStatement( sql ); - callstatement.registerOutParameter( index++, Types.NUMERIC ); // TODO: should we require users to return number of deleted rows ? + callstatement.registerOutParameter( index++, Types.INTEGER); // TODO: should we require users to return number of deleted rows ? delete = callstatement; } else if ( useBatch ) { @@ -2362,8 +2364,12 @@ if ( useBatch ) { session.getBatcher().addToBatch( 1 ); } - else { + else if(!callable) { check( delete.executeUpdate(), id, j ); + } else { + delete.executeUpdate(); + CallableStatement cd = (CallableStatement)delete; + check( cd.getInt(1), id, j); } } Modified: trunk/Hibernate3/test/org/hibernate/test/TestCase.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/TestCase.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/test/org/hibernate/test/TestCase.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -142,7 +142,7 @@ lastTestClass = getClass(); } } - + protected void runTest() throws Throwable { final boolean stats = ( (SessionFactoryImplementor) sessions ).getStatistics().isStatisticsEnabled(); try { @@ -160,6 +160,9 @@ } else { session=null; + + //assertAllDataRemoved(); + } } catch (Throwable e) { @@ -181,6 +184,12 @@ } } + private void assertAllDataRemoved() { + Session tmpSession = openSession(); + assertEquals("Data is left in the database",0, tmpSession.createQuery( "from java.lang.Object" ).list().size()); + tmpSession.close(); + } + protected boolean dropAfterFailure() { return true; } Modified: trunk/Hibernate3/test/org/hibernate/test/criteria/CriteriaQueryTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/criteria/CriteriaQueryTest.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/test/org/hibernate/test/criteria/CriteriaQueryTest.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -319,10 +319,10 @@ //s.flush(); - Integer count = (Integer) s.createCriteria(Enrolment.class) + Long count = (Long) s.createCriteria(Enrolment.class) .setProjection( Projections.count("studentNumber").setDistinct() ) .uniqueResult(); - assertEquals(count, new Integer(2)); + assertEquals(count, new Long(2)); Object object = s.createCriteria(Enrolment.class) .setProjection( Projections.projectionList() @@ -334,7 +334,7 @@ .uniqueResult(); Object[] result = (Object[])object; - assertEquals(new Integer(2),result[0]); + assertEquals(new Long(2),result[0]); assertEquals(new Long(667),result[1]); assertEquals(new Long(101),result[2]); assertEquals( 384.0, ( (Double) result[3] ).doubleValue(), 0.01 ); @@ -493,10 +493,10 @@ s.flush(); - Integer count = (Integer) s.createCriteria(Enrolment.class) + Long count = (Long) s.createCriteria(Enrolment.class) .setProjection( Property.forName("studentNumber").count().setDistinct() ) .uniqueResult(); - assertEquals(count, new Integer(2)); + assertEquals(count, new Long(2)); Object object = s.createCriteria(Enrolment.class) .setProjection( Projections.projectionList() @@ -508,7 +508,7 @@ .uniqueResult(); Object[] result = (Object[])object; - assertEquals(new Integer(2),result[0]); + assertEquals(new Long(2),result[0]); assertEquals(new Long(667),result[1]); assertEquals(new Long(101),result[2]); assertEquals(384.0, ( (Double) result[3] ).doubleValue(), 0.01); Added: trunk/Hibernate3/test/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/test/org/hibernate/test/hql/CriteriaHQLAlignmentTest.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -0,0 +1,181 @@ +//$Id: HQLTest.java 9873 2006-05-04 13:42:48Z max...@jb... $ +package org.hibernate.test.hql; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.*; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.hibernate.classic.Session; +import org.hibernate.criterion.Projections; +import org.hibernate.dialect.DB2Dialect; +import org.hibernate.dialect.HSQLDialect; +import org.hibernate.dialect.MySQLDialect; +import org.hibernate.dialect.Oracle9Dialect; +import org.hibernate.dialect.PostgreSQLDialect; +import org.hibernate.dialect.function.SQLFunction; +import org.hibernate.hql.ast.DetailedSemanticException; +import org.hibernate.hql.ast.QuerySyntaxException; +import org.hibernate.hql.ast.ASTQueryTranslatorFactory; +import org.hibernate.hql.ast.QueryTranslatorImpl; +import org.hibernate.hql.ast.tree.ConstructorNode; +import org.hibernate.hql.ast.tree.DotNode; +import org.hibernate.hql.ast.tree.IndexNode; +import org.hibernate.hql.ast.tree.SelectClause; +import org.hibernate.hql.QueryTranslatorFactory; +import org.hibernate.hql.QueryTranslator; +import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.query.HQLQueryPlan; +import org.hibernate.engine.query.ReturnMetadata; +import org.hibernate.Criteria; +import org.hibernate.Hibernate; + +import antlr.RecognitionException; + +/** + * Tests cases for ensuring alignment between HQL and Criteria behavior. + * + * @author Max Rydahl Andersen + */ +public class CriteriaHQLAlignmentTest extends QueryTranslatorTestCase { + + public CriteriaHQLAlignmentTest(String x) { + super( x ); + SelectClause.VERSION2_SQL = true; + } + + protected boolean dropAfterFailure() { + return true; + } + + protected boolean recreateSchema() { + return true; // needed for the Criteria return type test + } + + public void testHQLAggregationReturnType() { + // EJB3: COUNT returns Long + QueryTranslatorImpl translator = createNewQueryTranslator( "select count(*) from Human h" ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.LONG, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select count(h.height) from Human h" ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.LONG, translator.getReturnTypes()[0] ); + + // MAX, MIN return the type of the state-field to which they are applied. + translator = createNewQueryTranslator( "select max(h.height) from Human h" ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select max(h.id) from Human h" ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.LONG, translator.getReturnTypes()[0] ); + + // AVG returns Double. + translator = createNewQueryTranslator( "select avg(h.height) from Human h" ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select avg(h.id) from Human h" ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select avg(h.bigIntegerValue) from Human h" ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); + + // SUM returns Long when applied to state-fields of integral types (other than BigInteger); + translator = createNewQueryTranslator( "select sum(h.id) from Human h" ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.LONG, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select sum(h.intValue) from Human h" ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.LONG, translator.getReturnTypes()[0] ); + + // SUM returns Double when applied to state-fields of floating point types; + translator = createNewQueryTranslator( "select sum(h.height) from Human h" ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); + + translator = createNewQueryTranslator( "select sum(h.floatValue) from Human h" ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); + + // SUM returns BigInteger when applied to state-fields of type BigInteger + translator = createNewQueryTranslator( "select sum(h.bigIntegerValue) from Human h" ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.BIG_INTEGER, translator.getReturnTypes()[0] ); + + // SUM and BigDecimal when applied to state-fields of type BigDecimal. + translator = createNewQueryTranslator( "select sum(h.bigDecimalValue) from Human h" ); + assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); + assertEquals( "incorrect return type", Hibernate.BIG_DECIMAL, translator.getReturnTypes()[0] ); + } + + public void testCriteriaAggregationReturnType() { + Session s = openSession(); + Human human = new Human(); + human.setBigIntegerValue( new BigInteger("42") ); + human.setBigDecimalValue( new BigDecimal(45) ); + s.save(human); + + // EJB3: COUNT returns Long + Long longValue = (Long) s.createCriteria( Human.class ).setProjection( Projections.rowCount()).uniqueResult(); + assertEquals(longValue, new Long(1)); + longValue = (Long) s.createCriteria( Human.class ).setProjection( Projections.count("height")).uniqueResult(); + assertEquals(longValue, new Long(1)); + + // MAX, MIN return the type of the state-field to which they are applied. + Double dblValue = (Double) s.createCriteria( Human.class ).setProjection( Projections.max( "height" )).uniqueResult(); + assertNotNull(dblValue); + + longValue = (Long) s.createCriteria( Human.class ).setProjection( Projections.max( "id" )).uniqueResult(); + assertNotNull(longValue); + + // AVG returns Double. + dblValue = (Double) s.createCriteria( Human.class ).setProjection( Projections.avg( "height" )).uniqueResult(); + assertNotNull(dblValue); + + dblValue = (Double) s.createCriteria( Human.class ).setProjection( Projections.avg( "id" )).uniqueResult(); + assertNotNull(dblValue); + + dblValue = (Double) s.createCriteria( Human.class ).setProjection( Projections.avg( "bigIntegerValue" )).uniqueResult(); + assertNotNull(dblValue); + + // SUM returns Long when applied to state-fields of integral types (other than BigInteger); + longValue = (Long) s.createCriteria( Human.class ).setProjection( Projections.sum( "id" )).uniqueResult(); + assertNotNull(longValue); + + longValue = (Long) s.createCriteria( Human.class ).setProjection( Projections.sum( "intValue" )).uniqueResult(); + assertNotNull(longValue); + + // SUM returns Double when applied to state-fields of floating point types; + dblValue = (Double) s.createCriteria( Human.class ).setProjection( Projections.sum( "height" )).uniqueResult(); + assertNotNull(dblValue); + + dblValue = (Double) s.createCriteria( Human.class ).setProjection( Projections.sum( "floatValue" )).uniqueResult(); + assertNotNull(dblValue); + + // SUM returns BigInteger when applied to state-fields of type BigInteger + BigInteger bigIValue = (BigInteger) s.createCriteria( Human.class ).setProjection( Projections.sum( "bigIntegerValue" )).uniqueResult(); + assertNotNull(bigIValue); + + // SUM and BigDecimal when applied to state-fields of type BigDecimal. + BigDecimal bigDValue = (BigDecimal) s.createCriteria( Human.class ).setProjection( Projections.sum( "bigDecimalValue" )).uniqueResult(); + assertNotNull(bigDValue); + + s.delete( human ); + s.flush(); + s.close(); + } + + public static Test suite() { + return new TestSuite( CriteriaHQLAlignmentTest.class ); + } + +} Modified: trunk/Hibernate3/test/org/hibernate/test/hql/HQLSuite.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/HQLSuite.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/test/org/hibernate/test/hql/HQLSuite.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -22,6 +22,7 @@ suite.addTest( HqlParserTest.suite() ); suite.addTest( ScrollableCollectionFetchingTest.suite() ); suite.addTest( ClassicTranslatorTest.suite() ); + suite.addTest( CriteriaHQLAlignmentTest.suite() ); return suite; } } Modified: trunk/Hibernate3/test/org/hibernate/test/hql/HQLTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/HQLTest.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/test/org/hibernate/test/hql/HQLTest.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -3,11 +3,15 @@ import java.io.PrintWriter; import java.io.StringWriter; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.*; import junit.framework.Test; import junit.framework.TestSuite; +import org.hibernate.classic.Session; +import org.hibernate.criterion.Projections; import org.hibernate.dialect.DB2Dialect; import org.hibernate.dialect.HSQLDialect; import org.hibernate.dialect.MySQLDialect; @@ -27,6 +31,7 @@ import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.engine.query.HQLQueryPlan; import org.hibernate.engine.query.ReturnMetadata; +import org.hibernate.Criteria; import org.hibernate.Hibernate; import antlr.RecognitionException; @@ -803,66 +808,8 @@ assertTranslation( "select count(distinct an) from Animal an" ); assertTranslation( "select count(distinct an.id) from Animal an" ); assertTranslation( "select count(all an.id) from Animal an" ); - } - - public void testAggregationReturnType() { - // EJB3: COUNT returns Long - QueryTranslatorImpl translator = createNewQueryTranslator( "select count(*) from Human h" ); - assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); - assertEquals( "incorrect return type", Hibernate.LONG, translator.getReturnTypes()[0] ); + } - // MAX, MIN return the type of the state-field to which they are applied. - translator = createNewQueryTranslator( "select max(h.height) from Human h" ); - assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); - assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); - - translator = createNewQueryTranslator( "select max(h.id) from Human h" ); - assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); - assertEquals( "incorrect return type", Hibernate.LONG, translator.getReturnTypes()[0] ); - - // AVG returns Double. - translator = createNewQueryTranslator( "select avg(h.height) from Human h" ); - assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); - assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); - - translator = createNewQueryTranslator( "select avg(h.id) from Human h" ); - assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); - assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); - - translator = createNewQueryTranslator( "select avg(h.bigIntegerValue) from Human h" ); - assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); - assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); - - // SUM returns Long when applied to state-fields of integral types (other than BigInteger); - translator = createNewQueryTranslator( "select sum(h.id) from Human h" ); - assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); - assertEquals( "incorrect return type", Hibernate.LONG, translator.getReturnTypes()[0] ); - - translator = createNewQueryTranslator( "select sum(h.intValue) from Human h" ); - assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); - assertEquals( "incorrect return type", Hibernate.LONG, translator.getReturnTypes()[0] ); - - // SUM returns Double when applied to state-fields of floating point types; - translator = createNewQueryTranslator( "select sum(h.height) from Human h" ); - assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); - assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); - - translator = createNewQueryTranslator( "select sum(h.floatValue) from Human h" ); - assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); - assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] ); - - // SUM returns BigInteger when applied to state-fields of type BigInteger - translator = createNewQueryTranslator( "select sum(h.bigIntegerValue) from Human h" ); - assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); - assertEquals( "incorrect return type", Hibernate.BIG_INTEGER, translator.getReturnTypes()[0] ); - - // SUM and BigDecimal when applied to state-fields of type BigDecimal. - translator = createNewQueryTranslator( "select sum(h.bigDecimalValue) from Human h" ); - assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length ); - assertEquals( "incorrect return type", Hibernate.BIG_DECIMAL, translator.getReturnTypes()[0] ); - - } - public void testSelectProperty() throws Exception { assertTranslation( "select an.bodyWeight, mo.bodyWeight from Animal an inner join an.mother mo where an.bodyWeight < mo.bodyWeight" ); } @@ -1327,5 +1274,5 @@ public static Test suite() { return new TestSuite( HQLTest.class ); } - + } Modified: trunk/Hibernate3/test/org/hibernate/test/immutable/ImmutableTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/immutable/ImmutableTest.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/test/org/hibernate/test/immutable/ImmutableTest.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -44,8 +44,8 @@ cv1 = (ContractVariation) c.getVariations().iterator().next(); assertEquals( cv1.getText(), "expensive" ); s.delete(c); - assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) ); - assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Integer(0) ); + assertEquals( s.createCriteria(Contract.class).setProjection( Projections.rowCount() ).uniqueResult(), new Long(0) ); + assertEquals( s.createCriteria(ContractVariation.class).setProjection( Projections.rowCount() ).uniqueResult(), new Long(0) ); t.commit(); s.close(); } Modified: trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/test/org/hibernate/test/ops/MergeTest.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -262,7 +262,7 @@ s.createCriteria(NumberedNode.class) .setProjection( Projections.rowCount() ) .uniqueResult(), - new Integer(2) + new Long(2) ); s.delete(root); s.delete(mergedChild); Modified: trunk/Hibernate3/test/org/hibernate/test/ops/SaveOrUpdateTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/ops/SaveOrUpdateTest.java 2006-05-07 15:49:16 UTC (rev 9906) +++ trunk/Hibernate3/test/org/hibernate/test/ops/SaveOrUpdateTest.java 2006-05-08 17:41:21 UTC (rev 9907) @@ -242,7 +242,7 @@ s.createCriteria( NumberedNode.class ) .setProjection( Projections.rowCount() ) .uniqueResult(), - new Integer( 2 ) + new Long( 2 ) ); s.delete( root ); s.delete( child ); @@ -299,7 +299,7 @@ s.createCriteria( NumberedNode.class ) .setProjection( Projections.rowCount() ) .uniqueResult(), - new Integer( 2 ) + new Long( 2 ) ); s.delete( root ); s.delete( child ); @@ -353,7 +353,7 @@ s.createCriteria( Node.class ) .setProjection( Projections.rowCount() ) .uniqueResult(), - new Integer( 2 ) + new Long( 2 ) ); s.delete( root ); s.delete( child ); |
From: <hib...@li...> - 2006-05-07 15:49:20
|
Author: max...@jb... Date: 2006-05-07 11:49:16 -0400 (Sun, 07 May 2006) New Revision: 9906 Modified: trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/pojo/EntityPOJOClass.java Log: removed NPE when table does not have a primary key Modified: trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/pojo/EntityPOJOClass.java =================================================================== --- trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/pojo/EntityPOJOClass.java 2006-05-06 04:46:06 UTC (rev 9905) +++ trunk/HibernateExt/tools/src/java/org/hibernate/tool/hbm2x/pojo/EntityPOJOClass.java 2006-05-07 15:49:16 UTC (rev 9906) @@ -174,7 +174,7 @@ while ( uniqueKeys.hasNext() ) { UniqueKey key = (UniqueKey) uniqueKeys.next(); - if (table.getPrimaryKey().getColumns().equals(key.getColumns())) { + if (table.hasPrimaryKey() && table.getPrimaryKey().getColumns().equals(key.getColumns())) { continue; } |
From: <hib...@li...> - 2006-05-06 04:46:11
|
Author: ste...@jb... Date: 2006-05-06 00:46:06 -0400 (Sat, 06 May 2006) New Revision: 9905 Added: tags/v32cr2/Hibernate3/ Log: tagging 3.2.0.cr2 Copied: tags/v32cr2/Hibernate3 (from rev 9904, trunk/Hibernate3) |
From: <hib...@li...> - 2006-05-06 04:44:38
|
Author: ste...@jb... Date: 2006-05-06 00:44:36 -0400 (Sat, 06 May 2006) New Revision: 9904 Added: tags/v32cr2/ Log: prep 3.2.0.cr2 release |
From: <hib...@li...> - 2006-05-06 04:41:26
|
Author: ste...@jb... Date: 2006-05-06 00:40:07 -0400 (Sat, 06 May 2006) New Revision: 9903 Modified: trunk/Hibernate3/build.xml trunk/Hibernate3/changelog.txt trunk/Hibernate3/doc/reference/en/master.xml trunk/Hibernate3/readme.txt trunk/Hibernate3/src/org/hibernate/cfg/Environment.java Log: prep 3.2.0.cr2 release Modified: trunk/Hibernate3/build.xml =================================================================== --- trunk/Hibernate3/build.xml 2006-05-06 03:53:35 UTC (rev 9902) +++ trunk/Hibernate3/build.xml 2006-05-06 04:40:07 UTC (rev 9903) @@ -19,7 +19,7 @@ <property name="version.major" value="3"/> <property name="version.minor" value="2"/> <property name="version.micro" value="0"/> - <property name="version.qualifier" value="cr1"/> + <property name="version.qualifier" value="cr2"/> <property name="version.full" value="${version.major}.${version.minor}.${version.micro}.${version.qualifier}"/> <property name="version.major_minor" value="${version.major}.${version.minor}"/> <property name="fullname" value="${name}-${version.full}"/> Modified: trunk/Hibernate3/changelog.txt =================================================================== --- trunk/Hibernate3/changelog.txt 2006-05-06 03:53:35 UTC (rev 9902) +++ trunk/Hibernate3/changelog.txt 2006-05-06 04:40:07 UTC (rev 9903) @@ -5,6 +5,33 @@ refer to the particular case on JIRA using the issue tracking number to learn more about each case. +Chages in version 3.2 cr2 (2006.05.05) +------------------------------------------- + +** Bug + * [HHH-1114] - The first (HSQL) Hibernate Application doesn't work as expected due to lack of database shutdown + * [HHH-1175] - Exception when loading inheritance mapping in single file + * [HHH-1560] - PropertiesHelper.resolvePlaceHolders() fails with non-String values in System properties + * [HHH-1620] - Errors on max_lo <=1 boundaries + * [HHH-1625] - Hibernate.isPropertyInitialized() returns false on instrumented transient object + * [HHH-1648] - Exception while resuming a transaction is silently eaten + * [HHH-1674] - Configuration serialization error: filterDefinitions map not serializable + * [HHH-1695] - subsequent calls to non-existent proxy causes NPE + +** Improvement + * [HHH-1266] - StatelessSession can implement refresh + * [HHH-1414] - many-to-many and metadata order-by based on column from the target table + * [HHH-1477] - Improve naming strategy for ANN-195 + * [HHH-1538] - aggregations functions in EJBQL queries does not return the appropriate types + * [HHH-1670] - Update EhCache and EhCache provider to support EhCache 1.2 + * [HHH-1704] - Deduplicate unique constraints generation sharing the same column(s) + +** New Feature + * [HHH-870] - support SQL updates in named queries + * [HHH-1591] - Replace LazyInitializationException by EntityNotFoundException + * [HHH-1719] - Provide a ClassTransformer interface to the BytecodeProvider + + Chages in version 3.2 cr1 (2006.03.27) ------------------------------------------- Modified: trunk/Hibernate3/doc/reference/en/master.xml =================================================================== --- trunk/Hibernate3/doc/reference/en/master.xml 2006-05-06 03:53:35 UTC (rev 9902) +++ trunk/Hibernate3/doc/reference/en/master.xml 2006-05-06 04:40:07 UTC (rev 9903) @@ -33,7 +33,7 @@ <bookinfo> <title>HIBERNATE - Relational Persistence for Idiomatic Java</title> <subtitle>Hibernate Reference Documentation</subtitle> - <releaseinfo>3.2 cr1</releaseinfo> + <releaseinfo>3.2 cr2</releaseinfo> </bookinfo> <toc/> Modified: trunk/Hibernate3/readme.txt =================================================================== --- trunk/Hibernate3/readme.txt 2006-05-06 03:53:35 UTC (rev 9902) +++ trunk/Hibernate3/readme.txt 2006-05-06 04:40:07 UTC (rev 9903) @@ -1,6 +1,6 @@ Hibernate - Relational Persistence for Idiomatic Java ===================================================== -version 3.2 cr1, Mar 27, 2006 +version 3.2 cr2, May 5, 2006 Instructions ------------ Modified: trunk/Hibernate3/src/org/hibernate/cfg/Environment.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/cfg/Environment.java 2006-05-06 03:53:35 UTC (rev 9902) +++ trunk/Hibernate3/src/org/hibernate/cfg/Environment.java 2006-05-06 04:40:07 UTC (rev 9903) @@ -153,7 +153,7 @@ */ public final class Environment { - public static final String VERSION = "3.2 cr1"; + public static final String VERSION = "3.2 cr2"; /** * <tt>ConnectionProvider</tt> implementor to use when obtaining connections |
From: <hib...@li...> - 2006-05-06 03:53:52
|
Author: ste...@jb... Date: 2006-05-05 23:53:35 -0400 (Fri, 05 May 2006) New Revision: 9902 Modified: trunk/Hibernate3/lib/version.properties Log: ehcache version info Modified: trunk/Hibernate3/lib/version.properties =================================================================== --- trunk/Hibernate3/lib/version.properties 2006-05-06 03:33:33 UTC (rev 9901) +++ trunk/Hibernate3/lib/version.properties 2006-05-06 03:53:35 UTC (rev 9902) @@ -159,8 +159,8 @@ ## cache providers -ehcache.lib=ehcache-1.1.jar -ehcache.version=1.1 +ehcache.lib=ehcache-1.2.jar +ehcache.version=1.2 ehcache.name=EHCache cache ehcache.when=runtime, optional (required if no other cache provider is set) |
From: <hib...@li...> - 2006-05-06 03:33:51
|
Author: ste...@jb... Date: 2006-05-05 23:33:33 -0400 (Fri, 05 May 2006) New Revision: 9901 Added: trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/ trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/FetchingTest.java trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/Person.hbm.xml trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/Person.java trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/Stay.java Modified: trunk/Hibernate3/test/org/hibernate/test/ejb3/EJB3Suite.java Log: copied over a test from annotations Modified: trunk/Hibernate3/test/org/hibernate/test/ejb3/EJB3Suite.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/ejb3/EJB3Suite.java 2006-05-06 00:13:44 UTC (rev 9900) +++ trunk/Hibernate3/test/org/hibernate/test/ejb3/EJB3Suite.java 2006-05-06 03:33:33 UTC (rev 9901) @@ -5,6 +5,7 @@ import org.hibernate.test.ejb3.lock.EJB3LockTest; import org.hibernate.test.ejb3.lock.RepeatableReadTest; import org.hibernate.test.ejb3.proxy.Ejb3ProxyTest; +import org.hibernate.test.ejb3.fetch.FetchingTest; /** * @author Steve Ebersole @@ -15,6 +16,7 @@ suite.addTest( EJB3LockTest.suite() ); suite.addTest( RepeatableReadTest.suite() ); suite.addTest( Ejb3ProxyTest.suite() ); + suite.addTest( FetchingTest.suite() ); return suite; } } Added: trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/FetchingTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/FetchingTest.java 2006-05-06 00:13:44 UTC (rev 9900) +++ trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/FetchingTest.java 2006-05-06 03:33:33 UTC (rev 9901) @@ -0,0 +1,83 @@ +package org.hibernate.test.ejb3.fetch; + +import java.util.Date; + +import org.hibernate.Hibernate; +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.hibernate.test.TestCase; +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * @author Emmanuel Bernard + */ +public class FetchingTest extends TestCase { + + public void testLazy() throws Exception { + Session s; + Transaction tx; + s = openSession(); + tx = s.beginTransaction(); + Person p = new Person( "Gavin", "King", "JBoss Inc" ); + Stay stay = new Stay( p, new Date(), new Date(), "A380", "Blah", "Blah" ); + p.addStay( stay ); + s.persist( p ); + tx.commit(); + s.clear(); + tx = s.beginTransaction(); + p = (Person) s.createQuery( "from Person p where p.firstName = :name" ) + .setParameter( "name", "Gavin" ).uniqueResult(); + assertFalse( Hibernate.isInitialized( p.getStays() ) ); + s.delete( p ); + tx.commit(); + s.close(); + } + + public void testHibernateFetchingLazy() throws Exception { + Session s; + Transaction tx; + s = openSession(); + tx = s.beginTransaction(); + Person p = new Person( "Gavin", "King", "JBoss Inc" ); + Stay stay = new Stay( null, new Date(), new Date(), "A380", "Blah", "Blah" ); + Stay stay2 = new Stay( null, new Date(), new Date(), "A320", "Blah", "Blah" ); + Stay stay3 = new Stay( null, new Date(), new Date(), "A340", "Blah", "Blah" ); + stay.setOldPerson( p ); + stay2.setVeryOldPerson( p ); + stay3.setVeryOldPerson( p ); + p.addOldStay( stay ); + p.addVeryOldStay( stay2 ); + p.addVeryOldStay( stay3 ); + s.persist( p ); + tx.commit(); + s.clear(); + tx = s.beginTransaction(); + p = (Person) s.createQuery( "from Person p where p.firstName = :name" ) + .setParameter( "name", "Gavin" ).uniqueResult(); + assertFalse( Hibernate.isInitialized( p.getOldStays() ) ); + assertEquals( 1, p.getOldStays().size() ); + assertFalse( "lazy extra is failing", Hibernate.isInitialized( p.getOldStays() ) ); + s.clear(); + stay = (Stay) s.get( Stay.class, stay.getId() ); + assertTrue( ! Hibernate.isInitialized( stay.getOldPerson() ) ); + s.clear(); + stay3 = (Stay) s.get( Stay.class, stay3.getId() ); + assertTrue( "FetchMode.JOIN should overrides lazy options", Hibernate.isInitialized( stay3.getVeryOldPerson() ) ); + s.delete( stay3.getVeryOldPerson() ); + tx.commit(); + s.close(); + } + + public FetchingTest(String x) { + super( x ); + } + + protected String[] getMappings() { + return new String[] { "ejb3/fetch/Person.hbm.xml" }; + } + + public static Test suite() { + return new TestSuite( FetchingTest.class ); + } +} Added: trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/Person.hbm.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/Person.hbm.xml 2006-05-06 00:13:44 UTC (rev 9900) +++ trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/Person.hbm.xml 2006-05-06 03:33:33 UTC (rev 9901) @@ -0,0 +1,48 @@ +<!DOCTYPE hibernate-mapping PUBLIC + "-//Hibernate/Hibernate Mapping DTD 3.0//EN" + "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> + +<hibernate-mapping package="org.hibernate.test.ejb3.fetch"> + + <class name="Person" table="PERSON"> + <id name="id" column="ID" type="long"> + <generator class="increment"/> + </id> + <property name="firstName"/> + <property name="lastName"/> + <property name="companyName"/> + + <bag name="stays" cascade="all" lazy="true" inverse="true"> + <key column="PERS_ID"/> + <one-to-many class="Stay"/> + </bag> + + <bag name="oldStays" cascade="all" lazy="extra" fetch="subselect" inverse="true"> + <key column="OLD_PERS_ID"/> + <one-to-many class="Stay"/> + </bag> + + <bag name="veryOldStays" cascade="all" lazy="true" fetch="select" inverse="true"> + <key column="VERY_OLD_PERS_ID"/> + <one-to-many class="Stay"/> + </bag> + </class> + + <class name="Stay" table="STAY"> + <id name="id" column="ID" type="long"> + <generator class="increment"/> + </id> + + <property name="startDate"/> + <property name="endDate"/> + <property name="vessel"/> + <property name="authoriser"/> + <property name="comments"/> + + <many-to-one name="person" column="PERS_ID" class="Person" cascade="all"/> + <many-to-one name="oldPerson" column="OLD_PERS_ID" class="Person" cascade="all" fetch="select"/> + <many-to-one name="veryOldPerson" column="VERY_OLD_PERS_ID" class="Person" cascade="all" fetch="join"/> + + </class> + +</hibernate-mapping> \ No newline at end of file Added: trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/Person.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/Person.java 2006-05-06 00:13:44 UTC (rev 9900) +++ trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/Person.java 2006-05-06 03:33:33 UTC (rev 9901) @@ -0,0 +1,137 @@ +package org.hibernate.test.ejb3.fetch; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; + +/** + * Copied over from annotations test suite... + * + * @author Emmanuel Bernard + */ +public class Person implements Serializable { + + // member declaration + private Long id; + private String firstName; + private String lastName; + private String companyName; + private Collection stays; + private Collection oldStays; + private Collection veryOldStays; + + // constructors + public Person() { + } + + public Person(String firstName, String lastName, String companyName) { + this.firstName = firstName; + this.lastName = lastName; + this.companyName = companyName; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getCompanyName() { + return companyName; + } + + public void setCompanyName(String companyName) { + this.companyName = companyName; + } + + public Collection getStays() { + return stays; + } + + public void setStays(Collection stays) { + this.stays = stays; + } + + public Collection getOldStays() { + return oldStays; + } + + public void setOldStays(Collection oldStays) { + this.oldStays = oldStays; + } + + public Collection getVeryOldStays() { + return veryOldStays; + } + + public void setVeryOldStays(Collection veryOldStays) { + this.veryOldStays = veryOldStays; + } + + + // business logic + public void addStay(Date startDate, Date endDate, String vessel, String authoriser, String comments) { + Stay stay = new Stay( this, startDate, endDate, vessel, authoriser, comments ); + addStay( stay ); + } + + public void addStay(Stay stay) { + Collection stays = getStays(); + if ( stays == null ) { + stays = new ArrayList(); + } + stays.add( stay ); + + this.stays = stays; + } + + public void addOldStay(Date startDate, Date endDate, String vessel, String authoriser, String comments) { + Stay stay = new Stay( this, startDate, endDate, vessel, authoriser, comments ); + addOldStay( stay ); + } + + public void addOldStay(Stay stay) { + Collection stays = getOldStays(); + if ( stays == null ) { + stays = new ArrayList(); + } + stays.add( stay ); + + this.oldStays = stays; + } + + public void addVeryOldStay(Date startDate, Date endDate, String vessel, String authoriser, String comments) { + Stay stay = new Stay( this, startDate, endDate, vessel, authoriser, comments ); + addVeryOldStay( stay ); + } + + public void addVeryOldStay(Stay stay) { + Collection stays = getVeryOldStays(); + if ( stays == null ) { + stays = new ArrayList(); + } + stays.add( stay ); + + this.veryOldStays = stays; + } +} + Added: trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/Stay.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/Stay.java 2006-05-06 00:13:44 UTC (rev 9900) +++ trunk/Hibernate3/test/org/hibernate/test/ejb3/fetch/Stay.java 2006-05-06 03:33:33 UTC (rev 9901) @@ -0,0 +1,107 @@ +package org.hibernate.test.ejb3.fetch; + +import java.io.Serializable; +import java.util.Date; + +/** + * @author Emmanuel Bernard + */ +public class Stay implements Serializable { + + // member declaration + private Long id; + private Person person; + private Person oldPerson; + private Person veryOldPerson; + private Date startDate; + private Date endDate; + private String vessel; + private String authoriser; + private String comments; + + + // constructors + public Stay() { + } + + public Stay(Person person, Date startDate, Date endDate, String vessel, String authoriser, String comments) { + this.authoriser = authoriser; + this.endDate = endDate; + this.person = person; + this.startDate = startDate; + this.vessel = vessel; + this.comments = comments; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Person getPerson() { + return person; + } + + public void setPerson(Person person) { + this.person = person; + } + + public Person getOldPerson() { + return oldPerson; + } + + public void setOldPerson(Person oldPerson) { + this.oldPerson = oldPerson; + } + + public Person getVeryOldPerson() { + return veryOldPerson; + } + + public void setVeryOldPerson(Person veryOldPerson) { + this.veryOldPerson = veryOldPerson; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public String getVessel() { + return vessel; + } + + public void setVessel(String vessel) { + this.vessel = vessel; + } + + public String getAuthoriser() { + return authoriser; + } + + public void setAuthoriser(String authoriser) { + this.authoriser = authoriser; + } + + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments; + } +} \ No newline at end of file |
From: <hib...@li...> - 2006-05-06 00:13:49
|
Author: epbernard Date: 2006-05-05 20:13:44 -0400 (Fri, 05 May 2006) New Revision: 9900 Modified: trunk/HibernateExt/ejb/build.xml trunk/HibernateExt/ejb/changelog.txt trunk/HibernateExt/ejb/doc/reference/en/modules/configuration.xml trunk/HibernateExt/ejb/lib/hibernate-annotations.jar trunk/HibernateExt/ejb/readme.txt trunk/HibernateExt/metadata/changelog.txt trunk/HibernateExt/metadata/readme.txt Log: update version Modified: trunk/HibernateExt/ejb/build.xml =================================================================== --- trunk/HibernateExt/ejb/build.xml 2006-05-05 23:37:20 UTC (rev 9899) +++ trunk/HibernateExt/ejb/build.xml 2006-05-06 00:13:44 UTC (rev 9900) @@ -16,7 +16,7 @@ <!-- Name of project and version, used to create filenames --> <property name="Name" value="Hibernate EntityManager"/> <property name="name" value="hibernate-entitymanager"/> - <property name="version" value="3.1.0.CR1"/> + <property name="version" value="3.2.0.CR1"/> <property name="javadoc.packagenames" value="org.hibernate.ejb.*"/> <property name="jdbc.dir" value="jdbc"/> <property name="copy.test" value="true"/> Modified: trunk/HibernateExt/ejb/changelog.txt =================================================================== --- trunk/HibernateExt/ejb/changelog.txt 2006-05-05 23:37:20 UTC (rev 9899) +++ trunk/HibernateExt/ejb/changelog.txt 2006-05-06 00:13:44 UTC (rev 9900) @@ -1,6 +1,29 @@ Hibernate EntityManager Changelog ================================== +3.2.0.CR1 (08-05-2006) +---------------------- +** Bug + * [EJB-9] - Proxied instances should raise ENFE not LIE + * [EJB-59] - count(*) return Integer and not Long + * [EJB-101] - callback method overriding should avoid supermethod calls + * [EJB-116] - The EntityManager's configuration overwites configurations from the hibernate.cfg.xml file + * [EJB-167] - EntityManager must return null, if entity does not exist. + * [EJB-168] - Do not register Synchronization on Transaction marked as rollback + * [EJB-169] - MappingException thrown when META-INF/orm.xml is not found + * [EJB-173] - Resetting joined transaction state on a closed entity manager raise an exception + + +** Improvement + * [EJB-84] - Integrate the ClassFileTransformer and pass the appropriate entities to enhance + * [EJB-159] - RESOURCE_LOCAL should be default in JavaSE + * [EJB-172] - Use Hibernate abstraction of the ByteCodeEnhancer for class file transformation + * [EJB-175] - Support for createNativeQuery.executeUpdate() + +** New Feature + * [EJB-165] - Support interceptor and callback XML overriding + * [EJB-170] - Try to find <mapping-file/> in the parsed JAR before delegating to the regular resource locator + 3.1.0.Beta8b (27-04-2006) ------------------------- Modified: trunk/HibernateExt/ejb/doc/reference/en/modules/configuration.xml =================================================================== --- trunk/HibernateExt/ejb/doc/reference/en/modules/configuration.xml 2006-05-05 23:37:20 UTC (rev 9899) +++ trunk/HibernateExt/ejb/doc/reference/en/modules/configuration.xml 2006-05-06 00:13:44 UTC (rev 9900) @@ -8,7 +8,7 @@ <para>The EJB3 compatible Hibernate EntityManager is built on top of Hibernate core and Hibernate Annotations. You have to use compatible versions of each module. This version is known to work on Hibernate - 3.2.0.CR2 and Hibernate Annotations 3.1.0.Beta10. The following libraries + 3.2.0.CR2 and Hibernate Annotations 3.2.0.CR1. The following libraries have to be in your classpath: hibernate3.jar, hibernate-annotations.jar, hibernate-entity-manager.jar and all needed third party libraries for each package.(incl. ejb-persistence.jar).</para> Modified: trunk/HibernateExt/ejb/lib/hibernate-annotations.jar =================================================================== (Binary files differ) Modified: trunk/HibernateExt/ejb/readme.txt =================================================================== --- trunk/HibernateExt/ejb/readme.txt 2006-05-05 23:37:20 UTC (rev 9899) +++ trunk/HibernateExt/ejb/readme.txt 2006-05-06 00:13:44 UTC (rev 9900) @@ -1,6 +1,6 @@ Hibernate EntityManager ================================================== -Version: 3.1.0.Beta8, 26.04.2006 +Version: 3.2.0.CR1, 8.05.2006 THIS RELEASE OF HIBERNATE ENTITYMANAGER REQUIRES HIBERNATE 3.2.0.CR2 AND DOES NOT WORK WITH HIBERNATE 3.1.x OR ANY OLDER VERSION OF HIBERNATE. Modified: trunk/HibernateExt/metadata/changelog.txt =================================================================== --- trunk/HibernateExt/metadata/changelog.txt 2006-05-05 23:37:20 UTC (rev 9899) +++ trunk/HibernateExt/metadata/changelog.txt 2006-05-06 00:13:44 UTC (rev 9900) @@ -1,6 +1,44 @@ Hibernate Annotations Changelog =============================== +3.1.0.CR1 (08-05-2006) +---------------------- +** Bug + * [ANN-95] - Cannot create a unique constraint on columns belonging to both the superclass and the class + * [ANN-97] - JoinColumn with referencedColumnName clashes with unique=true on target column + * [ANN-118] - Duplicate unique constraint may be created + * [ANN-281] - @Mapkey broken if key is Entity + * [ANN-288] - Hibernate chokes on methods in entities starting with get...() and returning int[] + * [ANN-289] - @OneToOne and @Column fails + * [ANN-305] - ImprovedNamingStrategy not compatible with Hibernate annotations (@Index in particular) + * [ANN-306] - "Unbound" @Transient properties not properly being ignored + * [ANN-307] - BindHelper.findPropertiesByColumns behaviour is non deterministic due to HashSet being used + * [ANN-310] - Dist is missing resource files + * [ANN-329] - Entity.name is ignored in inheritance mapping + * [ANN-330] - Entity name not used to build default table name (classname is used instead) + * [ANN-331] - Extra element concatenated to default columns in collection of elements + * [ANN-333] - CollectionOfElements not using specified JoinTable + * [ANN-335] - AnnotationBinder just throws NPE if @OneToMany annotation is not on a Collection or Array + * [ANN-339] - @OrderBy does not work when an association table is involved + + +** Improvement + * [ANN-120] - Map, OneToMany, join table or @ManyToMany does not work + * [ANN-195] - Potentially move from TableA_TableB to EntityA_EntityB on join tables is the spec remains + * [ANN-293] - Unidirectional @ManyToMany should throw and error or warning when target entity cannot be resolved + * [ANN-323] - XML overriding should have precedence over annotations for queries, rs, generators + * [ANN-325] - entity described in XML should be part of the mapped entities + * [ANN-327] - Support for Map<Entity,Entity> + * [ANN-337] - XML result-set-mapping should overrides @SqlResultSetMapping + * [ANN-338] - @Temporal no longer has default value + +** New Feature + * [ANN-40] - @Parent + * [ANN-89] - Support generated=true property option for automatic refresh + * [ANN-158] - Support for @ManyToOne or @OneToOne @JoinTable (bidirectional) + * [ANN-224] - Ability to override fetching and lazy options through annotations + * [ANN-276] - Proper support of @OneToOne @PrimaryKeyJoinColumns + 3.1.0.Beta10b Preview (27-04-2006) ---------------------------------- ** Bug Modified: trunk/HibernateExt/metadata/readme.txt =================================================================== --- trunk/HibernateExt/metadata/readme.txt 2006-05-05 23:37:20 UTC (rev 9899) +++ trunk/HibernateExt/metadata/readme.txt 2006-05-06 00:13:44 UTC (rev 9900) @@ -1,6 +1,6 @@ Hibernate Annotations ================================================== -Version: 3.1.0 beta 10, 26.04.2006 +Version: 3.2.0 CR1, 8.05.2006 THIS RELEASE OF HIBERNATE ANNOTATIONS REQUIRES HIBERNATE 3.2.0.CR2 AND DOES NOT WORK WITH HIBERNATE 3.1.x OR ANY OLDER VERSION OF HIBERNATE. |
Author: epbernard Date: 2006-05-05 19:37:20 -0400 (Fri, 05 May 2006) New Revision: 9899 Modified: trunk/HibernateExt/ejb/doc/reference/en/master.xml trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Version.java trunk/HibernateExt/metadata/build.xml trunk/HibernateExt/metadata/doc/reference/en/master.xml trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/Version.java Log: version Modified: trunk/HibernateExt/ejb/doc/reference/en/master.xml =================================================================== --- trunk/HibernateExt/ejb/doc/reference/en/master.xml 2006-05-05 21:09:25 UTC (rev 9898) +++ trunk/HibernateExt/ejb/doc/reference/en/master.xml 2006-05-05 23:37:20 UTC (rev 9899) @@ -16,7 +16,7 @@ <subtitle>User guide</subtitle> - <releaseinfo>3.1.0 beta 8</releaseinfo> + <releaseinfo>3.2.0 CR1</releaseinfo> <mediaobject> <imageobject> Modified: trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Version.java =================================================================== --- trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Version.java 2006-05-05 21:09:25 UTC (rev 9898) +++ trunk/HibernateExt/ejb/src/java/org/hibernate/ejb/Version.java 2006-05-05 23:37:20 UTC (rev 9899) @@ -8,7 +8,7 @@ * @author Emmanuel Bernard */ public class Version { - public static String VERSION = "3.1.0.Beta8b"; + public static String VERSION = "3.2.0.CR1"; private static Log log = LogFactory.getLog( Version.class ); static { Modified: trunk/HibernateExt/metadata/build.xml =================================================================== --- trunk/HibernateExt/metadata/build.xml 2006-05-05 21:09:25 UTC (rev 9898) +++ trunk/HibernateExt/metadata/build.xml 2006-05-05 23:37:20 UTC (rev 9899) @@ -16,7 +16,7 @@ <!-- Name of project and version, used to create filenames --> <property name="Name" value="Hibernate Annotations"/> <property name="name" value="hibernate-annotations"/> - <property name="version" value="3.1.0.CR1"/> + <property name="version" value="3.2.0.CR1"/> <property name="javadoc.packagenames" value="org.hibernate.*"/> <property name="jdbc.dir" value="jdbc"/> <property name="copy.test" value="true"/> Modified: trunk/HibernateExt/metadata/doc/reference/en/master.xml =================================================================== --- trunk/HibernateExt/metadata/doc/reference/en/master.xml 2006-05-05 21:09:25 UTC (rev 9898) +++ trunk/HibernateExt/metadata/doc/reference/en/master.xml 2006-05-05 23:37:20 UTC (rev 9899) @@ -13,7 +13,7 @@ <subtitle>Reference Guide</subtitle> - <releaseinfo>3.1.0 beta 10</releaseinfo> + <releaseinfo>3.2.0 CR1</releaseinfo> <mediaobject> <imageobject> Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/Version.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/Version.java 2006-05-05 21:09:25 UTC (rev 9898) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/Version.java 2006-05-05 23:37:20 UTC (rev 9899) @@ -8,7 +8,7 @@ * @author Emmanuel Bernard */ public class Version { - public static String VERSION = "3.1.0.Beta10b"; + public static String VERSION = "3.2.0.CR1"; private static Log log = LogFactory.getLog( Version.class ); static { |
From: <hib...@li...> - 2006-05-05 21:09:28
|
Author: epbernard Date: 2006-05-05 17:09:25 -0400 (Fri, 05 May 2006) New Revision: 9898 Modified: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/QueryTest.java Log: EJB-175 executeUpdate test Modified: trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/QueryTest.java =================================================================== --- trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/QueryTest.java 2006-05-05 20:50:27 UTC (rev 9897) +++ trunk/HibernateExt/ejb/src/test/org/hibernate/ejb/test/QueryTest.java 2006-05-05 21:09:25 UTC (rev 9898) @@ -287,6 +287,28 @@ em.close(); } + public void testUpdateQuery() { + + Item item = new Item( "Mouse", "Micro$oft mouse" ); + + EntityManager em = factory.createEntityManager(); + em.getTransaction().begin(); + em.persist( item ); + assertTrue( em.contains( item ) ); + + em.flush(); + em.clear(); + + assertEquals( 1, em.createNativeQuery( "update Item i set i.descr = 'Logitech Mouse' where i.name = 'Mouse'").executeUpdate() ); + item = em.find( Item.class, item.getName() ); + assertEquals( "Logitech Mouse", item.getDescr() ); + em.remove( item ); + em.getTransaction().rollback(); + + em.close(); + + } + public Class[] getAnnotatedClasses() { return new Class[]{ Item.class, |
From: <hib...@li...> - 2006-05-05 20:50:36
|
Author: max...@jb... Date: 2006-05-05 16:50:27 -0400 (Fri, 05 May 2006) New Revision: 9897 Modified: trunk/Hibernate3/src/org/hibernate/action/BulkOperationCleanupAction.java Log: HHH-870 support SQL updates in named queries + synchronize on everything if no synchronize is specified. Modified: trunk/Hibernate3/src/org/hibernate/action/BulkOperationCleanupAction.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/action/BulkOperationCleanupAction.java 2006-05-05 20:29:41 UTC (rev 9896) +++ trunk/Hibernate3/src/org/hibernate/action/BulkOperationCleanupAction.java 2006-05-05 20:50:27 UTC (rev 9897) @@ -57,40 +57,39 @@ public BulkOperationCleanupAction(SessionImplementor session, Set querySpaces) { this.session = session; - if(querySpaces!=null && !querySpaces.isEmpty()) { - Set tmpSpaces = new HashSet(querySpaces); - SessionFactoryImplementor factory = session.getFactory(); - Iterator iterator = factory.getAllClassMetadata().entrySet().iterator(); - while ( iterator.hasNext() ) { - Map.Entry entry = (Map.Entry) iterator.next(); - String entityName = (String) entry.getKey(); - EntityPersister persister = factory.getEntityPersister( entityName ); - Serializable[] entitySpaces = persister.getQuerySpaces(); + Set tmpSpaces = new HashSet(querySpaces); + SessionFactoryImplementor factory = session.getFactory(); + Iterator iterator = factory.getAllClassMetadata().entrySet().iterator(); + while ( iterator.hasNext() ) { + Map.Entry entry = (Map.Entry) iterator.next(); + String entityName = (String) entry.getKey(); + EntityPersister persister = factory.getEntityPersister( entityName ); + Serializable[] entitySpaces = persister.getQuerySpaces(); - if (affectedEntity( querySpaces, entitySpaces )) { - if ( persister.hasCache() ) { - affectedEntityNames.add( persister.getEntityName() ); - } - Set roles = session.getFactory().getCollectionRolesByEntityParticipant( persister.getEntityName() ); - if ( roles != null ) { - affectedCollectionRoles.addAll( roles ); - } - for ( int y = 0; y < entitySpaces.length; y++ ) { - tmpSpaces.add( entitySpaces[y] ); - } + if (affectedEntity( querySpaces, entitySpaces )) { + if ( persister.hasCache() ) { + affectedEntityNames.add( persister.getEntityName() ); } - + Set roles = session.getFactory().getCollectionRolesByEntityParticipant( persister.getEntityName() ); + if ( roles != null ) { + affectedCollectionRoles.addAll( roles ); + } + for ( int y = 0; y < entitySpaces.length; y++ ) { + tmpSpaces.add( entitySpaces[y] ); + } } - this.spaces = (Serializable[]) tmpSpaces.toArray( new Serializable[tmpSpaces.size()] ); - } else { - // TODO: no synchronize info, sync on *all* ? - this.spaces = new Serializable[0]; } + this.spaces = (Serializable[]) tmpSpaces.toArray( new Serializable[tmpSpaces.size()] ); } + /** returns true if no queryspaces or if there are a match */ private boolean affectedEntity(Set querySpaces, Serializable[] entitySpaces) { + if(querySpaces==null || querySpaces.isEmpty()) { + return true; + } + for ( int i = 0; i < entitySpaces.length; i++ ) { if ( querySpaces.contains( entitySpaces[i] ) ) { return true; |
Author: max...@jb... Date: 2006-05-05 16:29:41 -0400 (Fri, 05 May 2006) New Revision: 9896 Modified: trunk/Hibernate3/src/org/hibernate/action/BulkOperationCleanupAction.java trunk/Hibernate3/src/org/hibernate/engine/SessionImplementor.java trunk/Hibernate3/src/org/hibernate/engine/query/NativeSQLQueryPlan.java trunk/Hibernate3/src/org/hibernate/impl/AbstractQueryImpl.java trunk/Hibernate3/src/org/hibernate/impl/SQLQueryImpl.java trunk/Hibernate3/src/org/hibernate/impl/SessionImpl.java trunk/Hibernate3/src/org/hibernate/impl/StatelessSessionImpl.java trunk/Hibernate3/test/org/hibernate/test/hql/BulkManipulationTest.java trunk/Hibernate3/test/org/hibernate/test/hql/Vehicle.hbm.xml Log: HHH-870 support SQL updates in named queries Modified: trunk/Hibernate3/src/org/hibernate/action/BulkOperationCleanupAction.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/action/BulkOperationCleanupAction.java 2006-05-05 19:27:17 UTC (rev 9895) +++ trunk/Hibernate3/src/org/hibernate/action/BulkOperationCleanupAction.java 2006-05-05 20:29:41 UTC (rev 9896) @@ -2,10 +2,15 @@ package org.hibernate.action; import org.hibernate.HibernateException; +import org.hibernate.metadata.ClassMetadata; +import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Queryable; +import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.engine.SessionImplementor; import java.io.Serializable; +import java.util.List; +import java.util.Map; import java.util.Set; import java.util.Iterator; import java.util.HashSet; @@ -45,7 +50,55 @@ this.spaces[i] = ( Serializable ) tmpSpaces.get( i ); } } + + /** Create an action that will evict collection and entity regions based on queryspaces (table names). + * TODO: cache the autodetected information and pass it in instead. + **/ + public BulkOperationCleanupAction(SessionImplementor session, Set querySpaces) { + this.session = session; + if(querySpaces!=null && !querySpaces.isEmpty()) { + Set tmpSpaces = new HashSet(querySpaces); + SessionFactoryImplementor factory = session.getFactory(); + Iterator iterator = factory.getAllClassMetadata().entrySet().iterator(); + while ( iterator.hasNext() ) { + Map.Entry entry = (Map.Entry) iterator.next(); + String entityName = (String) entry.getKey(); + EntityPersister persister = factory.getEntityPersister( entityName ); + Serializable[] entitySpaces = persister.getQuerySpaces(); + + if (affectedEntity( querySpaces, entitySpaces )) { + if ( persister.hasCache() ) { + affectedEntityNames.add( persister.getEntityName() ); + } + Set roles = session.getFactory().getCollectionRolesByEntityParticipant( persister.getEntityName() ); + if ( roles != null ) { + affectedCollectionRoles.addAll( roles ); + } + for ( int y = 0; y < entitySpaces.length; y++ ) { + tmpSpaces.add( entitySpaces[y] ); + } + } + + } + + this.spaces = (Serializable[]) tmpSpaces.toArray( new Serializable[tmpSpaces.size()] ); + } else { + // TODO: no synchronize info, sync on *all* ? + this.spaces = new Serializable[0]; + } + } + + + private boolean affectedEntity(Set querySpaces, Serializable[] entitySpaces) { + for ( int i = 0; i < entitySpaces.length; i++ ) { + if ( querySpaces.contains( entitySpaces[i] ) ) { + return true; + } + } + return false; + } + public void init() { evictEntityRegions(); evictCollectionRegions(); @@ -69,7 +122,7 @@ } public void execute() throws HibernateException { - // nothing to do + // nothing to do } private void evictEntityRegions() { Modified: trunk/Hibernate3/src/org/hibernate/engine/SessionImplementor.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/engine/SessionImplementor.java 2006-05-05 19:27:17 UTC (rev 9895) +++ trunk/Hibernate3/src/org/hibernate/engine/SessionImplementor.java 2006-05-05 20:29:41 UTC (rev 9896) @@ -254,6 +254,11 @@ */ int executeUpdate(String query, QueryParameters queryParameters) throws HibernateException; + /** + * Execute a native SQL update or delete query + */ + int executeNativeUpdate(NativeSQLQuerySpecification specification, QueryParameters queryParameters) throws HibernateException; + // copied from Session: public EntityMode getEntityMode(); Modified: trunk/Hibernate3/src/org/hibernate/engine/query/NativeSQLQueryPlan.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/engine/query/NativeSQLQueryPlan.java 2006-05-05 19:27:17 UTC (rev 9895) +++ trunk/Hibernate3/src/org/hibernate/engine/query/NativeSQLQueryPlan.java 2006-05-05 20:29:41 UTC (rev 9896) @@ -1,30 +1,49 @@ package org.hibernate.engine.query; +import java.io.Serializable; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.HibernateException; +import org.hibernate.QueryException; +import org.hibernate.action.BulkOperationCleanupAction; +import org.hibernate.engine.QueryParameters; +import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.TypedValue; +import org.hibernate.event.EventSource; +import org.hibernate.exception.JDBCExceptionHelper; import org.hibernate.loader.custom.SQLCustomQuery; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.NamedSQLQueryDefinition; +import org.hibernate.pretty.Formatter; +import org.hibernate.type.Type; +import org.hibernate.util.ArrayHelper; -import java.io.Serializable; - /** * Defines a query execution plan for a native-SQL query. - * + * * @author <a href="mailto:st...@hi...">Steve Ebersole </a> */ public class NativeSQLQueryPlan implements Serializable { private final String sourceQuery; + private final SQLCustomQuery customQuery; - public NativeSQLQueryPlan(NativeSQLQuerySpecification specification, SessionFactoryImplementor factory) { + private static final Log log = LogFactory.getLog(NativeSQLQueryPlan.class); + + public NativeSQLQueryPlan(NativeSQLQuerySpecification specification, + SessionFactoryImplementor factory) { this.sourceQuery = specification.getQueryString(); - customQuery = new SQLCustomQuery( - specification.getSqlQueryReturns(), - specification.getSqlQueryScalarReturns(), - specification.getQueryString(), - specification.getQuerySpaces(), - factory - ); + customQuery = new SQLCustomQuery( specification.getSqlQueryReturns(), + specification.getSqlQueryScalarReturns(), specification + .getQueryString(), specification.getQuerySpaces(), + factory ); } public String getSourceQuery() { @@ -34,4 +53,129 @@ public SQLCustomQuery getCustomQuery() { return customQuery; } + + private int[] getNamedParameterLocs(String name) throws QueryException { + Object loc = customQuery.getNamedParameterBindPoints().get( name ); + if ( loc == null ) { + throw new QueryException( + "Named parameter does not appear in Query: " + name, + customQuery.getSQL() ); + } + if ( loc instanceof Integer ) { + return new int[] { ((Integer) loc ).intValue() }; + } + else { + return ArrayHelper.toIntArray( (List) loc ); + } + } + + /** + * Bind positional parameter values to the <tt>PreparedStatement</tt> + * (these are parameters specified by a JDBC-style ?). + */ + private int bindPositionalParameters(final PreparedStatement st, + final QueryParameters queryParameters, final int start, + final SessionImplementor session) throws SQLException, + HibernateException { + + final Object[] values = queryParameters + .getFilteredPositionalParameterValues(); + final Type[] types = queryParameters + .getFilteredPositionalParameterTypes(); + int span = 0; + for (int i = 0; i < values.length; i++) { + types[i].nullSafeSet( st, values[i], start + span, session ); + span += types[i].getColumnSpan( session.getFactory() ); + } + return span; + } + + /** + * Bind named parameters to the <tt>PreparedStatement</tt>. This has an + * empty implementation on this superclass and should be implemented by + * subclasses (queries) which allow named parameters. + */ + private int bindNamedParameters(final PreparedStatement ps, + final Map namedParams, final int start, + final SessionImplementor session) throws SQLException, + HibernateException { + + if ( namedParams != null ) { + // assumes that types are all of span 1 + Iterator iter = namedParams.entrySet().iterator(); + 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 ( log.isDebugEnabled() ) { + log.debug( "bindNamedParameters() " + + typedval.getValue() + " -> " + name + " [" + + (locs[i] + start ) + "]" ); + } + typedval.getType().nullSafeSet( ps, typedval.getValue(), + locs[i] + start, session ); + } + result += locs.length; + } + return result; + } + else { + return 0; + } + } + + protected void coordinateSharedCacheCleanup(SessionImplementor session) { + BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, getCustomQuery().getQuerySpaces() ); + + action.init(); + + if ( session.isEventSource() ) { + ( ( EventSource ) session ).getActionQueue().addAction( action ); + } + } + + public int performExecuteUpdate(QueryParameters queryParameters, + SessionImplementor session) throws HibernateException { + + coordinateSharedCacheCleanup( session ); + + if(queryParameters.isCallable()) { + throw new IllegalArgumentException("callable not yet supported for native queries"); + } + + int result = 0; + PreparedStatement ps = null; + try { + queryParameters.processFilters( this.customQuery.getSQL(), + session ); + String sql = queryParameters.getFilteredSQL(); + + ps = session.getBatcher().prepareStatement( sql ); + + try { + int col = 1; + col += bindPositionalParameters( ps, queryParameters, col, + session ); + col += bindNamedParameters( ps, queryParameters + .getNamedParameters(), col, session ); + result = ps.executeUpdate(); + } + finally { + if ( ps != null ) { + session.getBatcher().closeStatement( ps ); + } + } + } + catch (SQLException sqle) { + throw JDBCExceptionHelper.convert( session.getFactory() + .getSQLExceptionConverter(), sqle, + "could not execute native bulk manipulation query", this.sourceQuery ); + } + + return result; + } + } Modified: trunk/Hibernate3/src/org/hibernate/impl/AbstractQueryImpl.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/impl/AbstractQueryImpl.java 2006-05-05 19:27:17 UTC (rev 9895) +++ trunk/Hibernate3/src/org/hibernate/impl/AbstractQueryImpl.java 2006-05-05 20:29:41 UTC (rev 9896) @@ -756,10 +756,6 @@ return uniqueElement( list() ); } - public int executeUpdate() throws HibernateException { - throw new UnsupportedOperationException( "Update queries only supported through HQL" ); - } - static Object uniqueElement(List list) throws NonUniqueResultException { int size = list.size(); if (size==0) return null; Modified: trunk/Hibernate3/src/org/hibernate/impl/SQLQueryImpl.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/impl/SQLQueryImpl.java 2006-05-05 19:27:17 UTC (rev 9895) +++ trunk/Hibernate3/src/org/hibernate/impl/SQLQueryImpl.java 2006-05-05 20:29:41 UTC (rev 9896) @@ -317,4 +317,10 @@ } return this; } + + public int executeUpdate() throws HibernateException { + Map namedParams = getNamedParams(); + return getSession().executeNativeUpdate(generateQuerySpecification( namedParams ), getQueryParameters( namedParams )); + } + } Modified: trunk/Hibernate3/src/org/hibernate/impl/SessionImpl.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/impl/SessionImpl.java 2006-05-05 19:27:17 UTC (rev 9895) +++ trunk/Hibernate3/src/org/hibernate/impl/SessionImpl.java 2006-05-05 20:29:41 UTC (rev 9896) @@ -29,7 +29,6 @@ import org.hibernate.LockMode; import org.hibernate.MappingException; import org.hibernate.ObjectDeletedException; -import org.hibernate.ObjectNotFoundException; import org.hibernate.Query; import org.hibernate.QueryException; import org.hibernate.ReplicationMode; @@ -54,6 +53,8 @@ import org.hibernate.engine.Status; import org.hibernate.engine.query.FilterQueryPlan; import org.hibernate.engine.query.HQLQueryPlan; +import org.hibernate.engine.query.NativeSQLQueryPlan; +import org.hibernate.engine.query.NativeSQLQuerySpecification; import org.hibernate.event.AutoFlushEvent; import org.hibernate.event.AutoFlushEventListener; import org.hibernate.event.DeleteEvent; @@ -88,6 +89,8 @@ import org.hibernate.loader.criteria.CriteriaLoader; import org.hibernate.loader.custom.CustomLoader; import org.hibernate.loader.custom.CustomQuery; +import org.hibernate.loader.custom.SQLQueryReturn; +import org.hibernate.loader.custom.SQLQueryScalarReturn; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.OuterJoinLoadable; @@ -116,7 +119,7 @@ // todo : need to find a clean way to handle the "event source" role // a seperate classs responsible for generating/dispatching events just duplicates most of the Session methods... - // passing around seperate references to interceptor, factory, actionQueue, and persistentContext is not manageable... + // passing around seperate reto interceptor, factory, actionQueue, and persistentContext is not manageable... private static final Log log = LogFactory.getLog(SessionImpl.class); @@ -1137,6 +1140,27 @@ return result; } + public int executeNativeUpdate(NativeSQLQuerySpecification nativeQuerySpecification, + QueryParameters queryParameters) throws HibernateException { + errorIfClosed(); + checkTransactionSynchStatus(); + queryParameters.validateParameters(); + NativeSQLQueryPlan plan = getNativeSQLQueryPlan(nativeQuerySpecification); + + + autoFlushIfRequired( plan.getCustomQuery().getQuerySpaces() ); + + boolean success = false; + int result = 0; + try { + result = plan.performExecuteUpdate(queryParameters, this); + success = true; + } finally { + afterOperation(success); + } + return result; + } + public Iterator iterate(String query) throws HibernateException { return iterate( query, new QueryParameters() ); } Modified: trunk/Hibernate3/src/org/hibernate/impl/StatelessSessionImpl.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/impl/StatelessSessionImpl.java 2006-05-05 19:27:17 UTC (rev 9895) +++ trunk/Hibernate3/src/org/hibernate/impl/StatelessSessionImpl.java 2006-05-05 20:29:41 UTC (rev 9896) @@ -9,6 +9,8 @@ import java.util.Map; import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.hibernate.CacheMode; import org.hibernate.ConnectionReleaseMode; import org.hibernate.Criteria; @@ -26,7 +28,6 @@ import org.hibernate.Transaction; import org.hibernate.UnresolvableObjectException; import org.hibernate.cache.CacheKey; -import org.hibernate.pretty.MessageHelper; import org.hibernate.collection.PersistentCollection; import org.hibernate.engine.EntityKey; import org.hibernate.engine.PersistenceContext; @@ -34,6 +35,8 @@ import org.hibernate.engine.StatefulPersistenceContext; import org.hibernate.engine.Versioning; import org.hibernate.engine.query.HQLQueryPlan; +import org.hibernate.engine.query.NativeSQLQueryPlan; +import org.hibernate.engine.query.NativeSQLQuerySpecification; import org.hibernate.event.EventListeners; import org.hibernate.id.IdentifierGeneratorFactory; import org.hibernate.jdbc.Batcher; @@ -43,11 +46,10 @@ import org.hibernate.loader.custom.CustomQuery; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.OuterJoinLoadable; +import org.hibernate.pretty.MessageHelper; import org.hibernate.proxy.HibernateProxy; import org.hibernate.type.Type; import org.hibernate.util.CollectionHelper; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; /** * @author Gavin King @@ -606,4 +608,23 @@ // no auto-flushing to support in stateless session return false; } + + public int executeNativeUpdate(NativeSQLQuerySpecification nativeSQLQuerySpecification, + QueryParameters queryParameters) throws HibernateException { + errorIfClosed(); + queryParameters.validateParameters(); + NativeSQLQueryPlan plan = getNativeSQLQueryPlan(nativeSQLQuerySpecification); + + boolean success = false; + int result = 0; + try { + result = plan.performExecuteUpdate(queryParameters, this); + success = true; + } finally { + afterOperation(success); + } + temporaryPersistenceContext.clear(); + return result; + } + } Modified: trunk/Hibernate3/test/org/hibernate/test/hql/BulkManipulationTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/BulkManipulationTest.java 2006-05-05 19:27:17 UTC (rev 9895) +++ trunk/Hibernate3/test/org/hibernate/test/hql/BulkManipulationTest.java 2006-05-05 20:29:41 UTC (rev 9896) @@ -138,35 +138,43 @@ TestData data = new TestData(); data.prepare(); - try { - Session s = openSession(); - Transaction t = s.beginTransaction(); - - List l = s.createQuery("from Vehicle").list(); - assertEquals(l.size(),4); - - s.createSQLQuery( "insert into Pickup (id, vin, owner) select id, vin, owner from Car" ).executeUpdate(); - - l = s.createQuery("from Vehicle").list(); - assertEquals(l.size(),5); - - t.commit(); - t = s.beginTransaction(); - - s.createSQLQuery( "delete Vehicle" ).executeUpdate(); - - l = s.createQuery("from Vehicle").list(); - assertEquals(l.size(),0); - - t.commit(); - s.close(); - fail("native sql bulk manipulation should fail with UnsupportedOperationException"); - } catch(UnsupportedOperationException eo) { - // should happen - } + Session s = openSession(); + Transaction t = s.beginTransaction(); + + List l = s.createQuery("from Vehicle").list(); + assertEquals(l.size(),4); + + s.createSQLQuery( "insert into PICKUP (id, vin, owner) select id, vin, owner from Car" ).executeUpdate(); + + l = s.createQuery("from Vehicle").list(); + assertEquals(l.size(),5); + + t.commit(); + t = s.beginTransaction(); + + s.createSQLQuery( "delete from TRUCK" ).executeUpdate(); + + l = s.createQuery("from Vehicle").list(); + assertEquals(l.size(),4); + + Car c = (Car) s.createQuery( "from Car where owner = 'Kirsten'" ).uniqueResult(); + c.setOwner("NotKirsten"); + assertEquals(0,s.getNamedQuery( "native-delete-car" ).setString( 0, "Kirsten" ).executeUpdate()); + assertEquals(1,s.getNamedQuery( "native-delete-car" ).setString( 0, "NotKirsten" ).executeUpdate()); + assertEquals(0,s.createSQLQuery( "delete from SUV where owner = :owner" ).setString( "owner", "NotThere" ).executeUpdate()); + assertEquals(1,s.createSQLQuery( "delete from SUV where owner = :owner" ).setString( "owner", "Joe" ).executeUpdate()); + s.createSQLQuery( "delete from PICKUP" ).executeUpdate(); + l = s.createQuery("from Vehicle").list(); + assertEquals(l.size(),0); + + + t.commit(); + s.close(); + + data.cleanup(); } Modified: trunk/Hibernate3/test/org/hibernate/test/hql/Vehicle.hbm.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/Vehicle.hbm.xml 2006-05-05 19:27:17 UTC (rev 9895) +++ trunk/Hibernate3/test/org/hibernate/test/hql/Vehicle.hbm.xml 2006-05-05 20:29:41 UTC (rev 9896) @@ -24,4 +24,8 @@ </union-subclass> </class> + <sql-query name="native-delete-car"> + <synchronize table="Car"/> + delete from CAR where owner = ? + </sql-query> </hibernate-mapping> \ No newline at end of file |
From: <hib...@li...> - 2006-05-05 19:27:24
|
Author: epbernard Date: 2006-05-05 15:27:17 -0400 (Fri, 05 May 2006) New Revision: 9895 Added: trunk/Hibernate3/lib/ehcache-1.2.jar trunk/Hibernate3/test/org/hibernate/test/cache/ehcache/ trunk/Hibernate3/test/org/hibernate/test/cache/ehcache/EhCacheTest.java trunk/Hibernate3/test/org/hibernate/test/cache/ehcache/ehcache.xml Removed: trunk/Hibernate3/lib/ehcache-1.1.jar Modified: trunk/Hibernate3/src/org/hibernate/cache/EhCache.java trunk/Hibernate3/src/org/hibernate/cache/EhCacheProvider.java trunk/Hibernate3/src/org/hibernate/cache/OptimisticTreeCacheProvider.java trunk/Hibernate3/src/org/hibernate/cache/TreeCacheProvider.java trunk/Hibernate3/src/org/hibernate/cfg/Environment.java trunk/Hibernate3/test/org/hibernate/test/cache/BaseCacheProviderTestCase.java trunk/Hibernate3/test/org/hibernate/test/cache/CacheSuite.java trunk/Hibernate3/test/org/hibernate/test/cache/treecache/optimistic/OptimisticTreeCacheTest.java trunk/Hibernate3/test/org/hibernate/test/cache/treecache/pessimistic/TreeCacheTest.java Log: HHH-1670 ehcache 1.2 and bugfixes in the provider Support for Environment.CACHE_PROVIDER_CONFIG Deleted: trunk/Hibernate3/lib/ehcache-1.1.jar =================================================================== (Binary files differ) Added: trunk/Hibernate3/lib/ehcache-1.2.jar =================================================================== (Binary files differ) Property changes on: trunk/Hibernate3/lib/ehcache-1.2.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: trunk/Hibernate3/src/org/hibernate/cache/EhCache.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/cache/EhCache.java 2006-05-05 18:01:32 UTC (rev 9894) +++ trunk/Hibernate3/src/org/hibernate/cache/EhCache.java 2006-05-05 19:27:17 UTC (rev 9895) @@ -1,56 +1,18 @@ //$Id$ -/* ==================================================================== - * The Apache Software License, Version 1.1 +/** + * Copyright 2003-2006 Greg Luck, Jboss Inc * - * Copyright (c) 2003 - 2004 Greg Luck. All rights reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, if - * any, must include the following acknowlegement: - * "This product includes software developed by Greg Luck - * (http://sourceforge.net/users/gregluck) and contributors. - * See http://sourceforge.net/project/memberlist.php?group_id=93232 - * for a list of contributors" - * Alternately, this acknowledgement may appear in the software itself, - * if and wherever such third-party acknowlegements normally appear. - * - * 4. The names "EHCache" must not be used to endorse or promote products - * derived from this software without prior written permission. For written - * permission, please contact Greg Luck (gregluck at users.sourceforge.net). - * - * 5. Products derived from this software may not be called "EHCache" - * nor may "EHCache" appear in their names without prior written - * permission of Greg Luck. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL GREG LUCK OR OTHER - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by contributors - * individuals on behalf of the EHCache project. For more - * information on EHCache, please see <http://ehcache.sourceforge.net/>. - * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.hibernate.cache; @@ -62,207 +24,223 @@ import net.sf.ehcache.CacheManager; import net.sf.ehcache.Element; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * EHCache plugin for Hibernate - * + * <p/> * EHCache uses a {@link net.sf.ehcache.store.MemoryStore} and a - * {@link net.sf.ehcache.store.DiskStore}. The {@link net.sf.ehcache.store.DiskStore} - * requires that both keys and values be {@link Serializable}. For this reason - * this plugin throws Exceptions when either of these are not castable to {@link Serializable}. + * {@link net.sf.ehcache.store.DiskStore}. + * The {@link net.sf.ehcache.store.DiskStore} requires that both keys and values be {@link java.io.Serializable}. + * However the MemoryStore does not and in ehcache-1.2 nonSerializable Objects are permitted. They are discarded + * if an attempt it made to overflow them to Disk or to replicate them to remote cache peers. * - * @version Taken from EhCache 0.9 * @author Greg Luck * @author Emmanuel Bernard */ public class EhCache implements Cache { - private static final Log log = LogFactory.getLog(EhCache.class); + private static final Log log = LogFactory.getLog( EhCache.class ); - private net.sf.ehcache.Cache cache; + private static final int SIXTY_THOUSAND_MS = 60000; - /** - * Creates a new Hibernate pluggable cache based on a cache name. - * <p> - * @param cache The underlying EhCache instance to use. - */ - public EhCache(net.sf.ehcache.Cache cache) { - this.cache = cache; - } + private net.sf.ehcache.Cache cache; - /** - * Gets a value of an element which matches the given key. - * @param key the key of the element to return. - * @return The value placed into the cache with an earlier put, or null if not found or expired - * @throws CacheException - */ - public Object get(Object key) throws CacheException { - try { - if ( log.isDebugEnabled() ) { - log.debug("key: " + key); - } - if (key == null) { - return null; - } - else { - Element element = cache.get( (Serializable) key ); - if (element == null) { - if ( log.isDebugEnabled() ) { - log.debug("Element for " + key + " is null"); - } - return null; - } - else { - return element.getValue(); - } - } - } - catch (net.sf.ehcache.CacheException e) { - throw new CacheException(e); - } - } - + /** + * Creates a new Hibernate pluggable cache based on a cache name. + * <p/> + * + * @param cache The underlying EhCache instance to use. + */ + public EhCache(net.sf.ehcache.Cache cache) { + this.cache = cache; + } + + /** + * Gets a value of an element which matches the given key. + * + * @param key the key of the element to return. + * @return The value placed into the cache with an earlier put, or null if not found or expired + * @throws CacheException + */ + public Object get(Object key) throws CacheException { + try { + if ( log.isDebugEnabled() ) { + log.debug( "key: " + key ); + } + if ( key == null ) { + return null; + } + else { + Element element = cache.get( key ); + if ( element == null ) { + if ( log.isDebugEnabled() ) { + log.debug( "Element for " + key + " is null" ); + } + return null; + } + else { + return element.getObjectValue(); + } + } + } + catch (net.sf.ehcache.CacheException e) { + throw new CacheException( e ); + } + } + public Object read(Object key) throws CacheException { - return get(key); + return get( key ); } - /** - * Puts an object into the cache. - * @param key a {@link Serializable} key - * @param value a {@link Serializable} value - * @throws CacheException if the parameters are not {@link Serializable}, the {@link CacheManager} - * is shutdown or another {@link Exception} occurs. - */ - public void update(Object key, Object value) throws CacheException { - put(key, value); - } - - /** - * Puts an object into the cache. - * @param key a {@link Serializable} key - * @param value a {@link Serializable} value - * @throws CacheException if the parameters are not {@link Serializable}, the {@link CacheManager} - * is shutdown or another {@link Exception} occurs. - */ + /** + * Puts an object into the cache. + * + * @param key a {@link Serializable} key + * @param value a {@link Serializable} value + * @throws CacheException if the parameters are not {@link Serializable}, the {@link CacheManager} + * is shutdown or another {@link Exception} occurs. + */ + public void update(Object key, Object value) throws CacheException { + put( key, value ); + } + + /** + * Puts an object into the cache. + * + * @param key a {@link Serializable} key + * @param value a {@link Serializable} value + * @throws CacheException if the parameters are not {@link Serializable}, the {@link CacheManager} + * is shutdown or another {@link Exception} occurs. + */ public void put(Object key, Object value) throws CacheException { - try { - Element element = new Element( (Serializable) key, (Serializable) value ); - cache.put(element); - } - catch (IllegalArgumentException e) { - throw new CacheException(e); - } - catch (IllegalStateException e) { - throw new CacheException(e); - } + try { + Element element = new Element( key, value ); + cache.put( element ); + } + catch (IllegalArgumentException e) { + throw new CacheException( e ); + } + catch (IllegalStateException e) { + throw new CacheException( e ); + } - } + } - /** - * Removes the element which matches the key. - * <p> - * If no element matches, nothing is removed and no Exception is thrown. - * @param key the key of the element to remove - * @throws CacheException - */ - public void remove(Object key) throws CacheException { - try { - cache.remove( (Serializable) key ); - } - catch (ClassCastException e) { - throw new CacheException(e); - } - catch (IllegalStateException e) { - throw new CacheException(e); - } - } + /** + * Removes the element which matches the key. + * <p/> + * If no element matches, nothing is removed and no Exception is thrown. + * + * @param key the key of the element to remove + * @throws CacheException + */ + public void remove(Object key) throws CacheException { + try { + cache.remove( key ); + } + catch (ClassCastException e) { + throw new CacheException( e ); + } + catch (IllegalStateException e) { + throw new CacheException( e ); + } + } - /** - * Remove all elements in the cache, but leave the cache - * in a useable state. - * @throws CacheException - */ - public void clear() throws CacheException { - try { - cache.removeAll(); - } - catch (IllegalStateException e) { - throw new CacheException(e); - } - catch (IOException e) { - throw new CacheException(e); - } - } + /** + * Remove all elements in the cache, but leave the cache + * in a useable state. + * + * @throws CacheException + */ + public void clear() throws CacheException { + try { + cache.removeAll(); + } + catch (IllegalStateException e) { + throw new CacheException( e ); + } + catch (IOException e) { + throw new CacheException( e ); + } + } - /** - * Remove the cache and make it unuseable. - * @throws CacheException - */ - public void destroy() throws CacheException { - try { - CacheManager.getInstance().removeCache( cache.getName() ); - } - catch (IllegalStateException e) { - throw new CacheException(e); - } - catch (net.sf.ehcache.CacheException e) { - throw new CacheException(e); - } - } + /** + * Remove the cache and make it unuseable. + * + * @throws CacheException + */ + public void destroy() throws CacheException { + try { + cache.getCacheManager().removeCache( cache.getName() ); + } + catch (IllegalStateException e) { + throw new CacheException( e ); + } + catch (net.sf.ehcache.CacheException e) { + throw new CacheException( e ); + } + } - /** - * Calls to this method should perform there own synchronization. - * It is provided for distributed caches. Because EHCache is not distributed - * this method does nothing. - */ - public void lock(Object key) throws CacheException { - } + /** + * Calls to this method should perform there own synchronization. + * It is provided for distributed caches. Because EHCache is not distributed + * this method does nothing. + */ + public void lock(Object key) throws CacheException { + } - /** - * Calls to this method should perform there own synchronization. - * It is provided for distributed caches. Because EHCache is not distributed - * this method does nothing. - */ - public void unlock(Object key) throws CacheException { - } + /** + * Calls to this method should perform there own synchronization. + * It is provided for distributed caches. Because EHCache is not distributed + * this method does nothing. + */ + public void unlock(Object key) throws CacheException { + } - /** - * Gets the next timestamp; - */ - public long nextTimestamp() { - return Timestamper.next(); - } + /** + * Gets the next timestamp; + */ + public long nextTimestamp() { + return Timestamper.next(); + } - /** - * Returns the lock timeout for this cache. - */ - public int getTimeout() { - // 60 second lock timeout - return Timestamper.ONE_MS * 60000; - } + /** + * Returns the lock timeout for this cache. + */ + public int getTimeout() { + // 60 second lock timeout + return Timestamper.ONE_MS * SIXTY_THOUSAND_MS; + } public String getRegionName() { return cache.getName(); } + /** + * Warning: This method can be very expensive to run. Allow approximately 1 second + * per 1MB of entries. Running this method could create liveness problems + * because the object lock is held for a long period + * <p/> + * + * @return the approximate size of memory ehcache is using for the MemoryStore for this cache + */ public long getSizeInMemory() { try { return cache.calculateInMemorySize(); } - catch(Throwable t) { + catch (Throwable t) { return -1; } } public long getElementCountInMemory() { try { - return cache.getSize(); + return cache.getMemoryStoreSize(); } catch (net.sf.ehcache.CacheException ce) { - throw new CacheException(ce); + throw new CacheException( ce ); } } @@ -281,7 +259,7 @@ return result; } catch (Exception e) { - throw new CacheException(e); + throw new CacheException( e ); } } Modified: trunk/Hibernate3/src/org/hibernate/cache/EhCacheProvider.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/cache/EhCacheProvider.java 2006-05-05 18:01:32 UTC (rev 9894) +++ trunk/Hibernate3/src/org/hibernate/cache/EhCacheProvider.java 2006-05-05 19:27:17 UTC (rev 9895) @@ -1,65 +1,30 @@ //$Id$ -/* ==================================================================== - * The Apache Software License, Version 1.1 +/** + * Copyright 2003-2006 Greg Luck, Jboss Inc * - * Copyright (c) 2003 - 2004 Greg Luck. All rights reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * http://www.apache.org/licenses/LICENSE-2.0 * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, if - * any, must include the following acknowlegement: - * "This product includes software developed by Greg Luck - * (http://sourceforge.net/users/gregluck) and contributors. - * See http://sourceforge.net/project/memberlist.php?group_id=93232 - * for a list of contributors" - * Alternately, this acknowledgement may appear in the software itself, - * if and wherever such third-party acknowlegements normally appear. - * - * 4. The names "EHCache" must not be used to endorse or promote products - * derived from this software without prior written permission. For written - * permission, please contact Greg Luck (gregluck at users.sourceforge.net). - * - * 5. Products derived from this software may not be called "EHCache" - * nor may "EHCache" appear in their names without prior written - * permission of Greg Luck. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL GREG LUCK OR OTHER - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by contributors - * individuals on behalf of the EHCache project. For more - * information on EHCache, please see <http://ehcache.sourceforge.net/>. - * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.hibernate.cache; -import net.sf.ehcache.CacheManager; - import java.util.Properties; +import java.net.URL; +import net.sf.ehcache.CacheManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.hibernate.cfg.Environment; +import org.hibernate.util.StringHelper; +import org.hibernate.util.ConfigHelper; /** * Cache Provider plugin for Hibernate @@ -71,16 +36,34 @@ * @author Greg Luck * @author Emmanuel Bernard */ +/** + * Cache Provider plugin for ehcache-1.2. New in this provider are ehcache support for multiple + * Hibernate session factories, each with its own ehcache configuration, and non Serializable keys and values. + * Ehcache-1.2 also has many other features such as cluster support and listeners, which can be used seamlessly simply + * by configurion in ehcache.xml. + * <p/> + * Use <code>hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider</code> in the Hibernate configuration + * to enable this provider for Hibernate's second level cache. + * <p/> + * When configuring multiple ehcache CacheManagers, as you would where you have multiple Hibernate Configurations and + * multiple SessionFactories, specify in each Hibernate configuration the ehcache configuration using + * the property <code>hibernate.cache.provider_configuration_file_resource_path</code> An example to set an ehcache configuration + * called ehcache-2.xml would be <code>hibernate.cache.provider_configuration_file_resource_path=/ehcache-2.xml</code>. If the leading + * slash is not there one will be added. The configuration file will be looked for in the root of the classpath. + * <p/> + * Updated for ehcache-1.2. Note this provider requires ehcache-1.2.jar. Make sure ehcache-1.1.jar or earlier + * is not in the classpath or it will not work. + * <p/> + * See http://ehcache.sf.net for documentation on ehcache + * <p/> + * + * @author Greg Luck + * @author Emmanuel Bernard + */ public class EhCacheProvider implements CacheProvider { private static final Log log = LogFactory.getLog(EhCacheProvider.class); - // CacheManager.create() actually returns a singleton reference, which is causing - // problems with users attempting to use multiple SessionFactories all using the - // EhCacheProvider in the same classloader. The work-around is to use simple reference - // counting here... - private static int referenceCount = 0; - private CacheManager manager; /** @@ -126,26 +109,54 @@ * @param properties current configuration settings. */ public void start(Properties properties) throws CacheException { - try { - manager = CacheManager.create(); - referenceCount++; - } - catch (net.sf.ehcache.CacheException e) { - throw new CacheException(e); + if (manager != null) { + log.warn("Attempt to restart an already started EhCacheProvider. Use sessionFactory.close() " + + " between repeated calls to buildSessionFactory. Using previously created EhCacheProvider." + + " If this behaviour is required, consider using net.sf.ehcache.hibernate.SingletonEhCacheProvider."); + return; } + try { + String configurationResourceName = null; + if (properties != null) { + configurationResourceName = (String) properties.get( Environment.CACHE_PROVIDER_CONFIG ); + } + if ( StringHelper.isEmpty( configurationResourceName ) ) { + manager = new CacheManager(); + } else { + URL url = loadResource(configurationResourceName); + manager = new CacheManager(url); + } + } catch (net.sf.ehcache.CacheException e) { + //yukky! Don't you have subclasses for that! + if (e.getMessage().startsWith("Cannot parseConfiguration CacheManager. Attempt to create a new instance of " + + "CacheManager using the diskStorePath")) { + throw new CacheException("Attempt to restart an already started EhCacheProvider. Use sessionFactory.close() " + + " between repeated calls to buildSessionFactory. Consider using net.sf.ehcache.hibernate.SingletonEhCacheProvider. Error from " + + " ehcache was: " + e.getMessage()); + } else { + throw e; + } + } } + private URL loadResource(String configurationResourceName) { + URL url = ConfigHelper.locateConfig( configurationResourceName ); + if (log.isDebugEnabled()) { + log.debug("Creating EhCacheProvider from a specified resource: " + + configurationResourceName + " Resolved to URL: " + url); + } + return url; + } + /** * Callback to perform any necessary cleanup of the underlying cache implementation * during SessionFactory.close(). */ public void stop() { - if ( manager != null ) { - if ( --referenceCount == 0 ) { - manager.shutdown(); - } - manager = null; - } + if (manager != null) { + manager.shutdown(); + manager = null; + } } public boolean isMinimalPutsEnabledByDefault() { Modified: trunk/Hibernate3/src/org/hibernate/cache/OptimisticTreeCacheProvider.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/cache/OptimisticTreeCacheProvider.java 2006-05-05 18:01:32 UTC (rev 9894) +++ trunk/Hibernate3/src/org/hibernate/cache/OptimisticTreeCacheProvider.java 2006-05-05 19:27:17 UTC (rev 9895) @@ -1,16 +1,16 @@ //$Id$ package org.hibernate.cache; -import org.jboss.cache.PropertyConfigurator; +import java.util.Properties; +import javax.transaction.TransactionManager; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.cfg.Environment; import org.hibernate.transaction.TransactionManagerLookup; import org.hibernate.transaction.TransactionManagerLookupFactory; -import org.hibernate.cfg.Environment; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.jboss.cache.PropertyConfigurator; -import javax.transaction.TransactionManager; -import java.util.Properties; - /** * Support for a standalone JBossCache TreeCache instance utilizing TreeCache's * optimistic locking capabilities. This capability was added in JBossCache @@ -25,6 +25,9 @@ */ public class OptimisticTreeCacheProvider implements CacheProvider { + /** + * @deprecated use {@link Environment.CACHE_PROVIDER_CONFIG} + */ public static final String CONFIG_RESOURCE = "hibernate.cache.opt_tree_cache.config"; public static final String DEFAULT_CONFIG = "treecache.xml"; @@ -58,7 +61,10 @@ * Indicates a problem preparing cache for use. */ public void start(Properties properties) { - String resource = properties.getProperty( CONFIG_RESOURCE ); + String resource = properties.getProperty( Environment.CACHE_PROVIDER_CONFIG ); + if (resource == null) { + resource = properties.getProperty( CONFIG_RESOURCE ); + } if ( resource == null ) { resource = DEFAULT_CONFIG; } Modified: trunk/Hibernate3/src/org/hibernate/cache/TreeCacheProvider.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/cache/TreeCacheProvider.java 2006-05-05 18:01:32 UTC (rev 9894) +++ trunk/Hibernate3/src/org/hibernate/cache/TreeCacheProvider.java 2006-05-05 19:27:17 UTC (rev 9895) @@ -1,15 +1,16 @@ //$Id$ package org.hibernate.cache; -import org.jboss.cache.PropertyConfigurator; +import java.util.Properties; +import javax.transaction.TransactionManager; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.hibernate.transaction.TransactionManagerLookup; import org.hibernate.transaction.TransactionManagerLookupFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.hibernate.cfg.Environment; +import org.jboss.cache.PropertyConfigurator; -import javax.transaction.TransactionManager; -import java.util.Properties; - /** * Support for a standalone JBossCache (TreeCache) instance. The JBossCache is configured * via a local config resource. @@ -18,6 +19,9 @@ */ public class TreeCacheProvider implements CacheProvider { + /** + * @deprecated use {@link org.hibernate.cfg.Environment.CACHE_PROVIDER_CONFIG} + */ public static final String CONFIG_RESOURCE = "hibernate.cache.tree_cache.config"; public static final String DEFAULT_CONFIG = "treecache.xml"; @@ -50,8 +54,12 @@ * @throws CacheException Indicates a problem preparing cache for use. */ public void start(Properties properties) { - String resource = properties.getProperty( CONFIG_RESOURCE ); + String resource = properties.getProperty( Environment.CACHE_PROVIDER_CONFIG ); + if ( resource == null ) { + resource = properties.getProperty( CONFIG_RESOURCE ); + } + if ( resource == null ) { resource = DEFAULT_CONFIG; } log.debug( "Configuring TreeCache from resource [" + resource + "]" ); Modified: trunk/Hibernate3/src/org/hibernate/cfg/Environment.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/cfg/Environment.java 2006-05-05 18:01:32 UTC (rev 9894) +++ trunk/Hibernate3/src/org/hibernate/cfg/Environment.java 2006-05-05 19:27:17 UTC (rev 9895) @@ -366,6 +366,10 @@ */ public static final String CACHE_PROVIDER = "hibernate.cache.provider_class"; /** + * The <tt>CacheProvider</tt> implementation class + */ + public static final String CACHE_PROVIDER_CONFIG = "hibernate.cache.provider_configuration_file_resource_path"; + /** * The <tt>CacheProvider</tt> JNDI namespace, if pre-bound to JNDI. */ public static final String CACHE_NAMESPACE = "hibernate.cache.jndi"; Modified: trunk/Hibernate3/test/org/hibernate/test/cache/BaseCacheProviderTestCase.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/cache/BaseCacheProviderTestCase.java 2006-05-05 18:01:32 UTC (rev 9894) +++ trunk/Hibernate3/test/org/hibernate/test/cache/BaseCacheProviderTestCase.java 2006-05-05 19:27:17 UTC (rev 9895) @@ -1,10 +1,13 @@ package org.hibernate.test.cache; +import java.util.Map; +import java.util.HashMap; + import org.hibernate.Session; import org.hibernate.Transaction; +import org.hibernate.cache.ReadWriteCache; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; -import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.stat.SecondLevelCacheStatistics; import org.hibernate.stat.Statistics; import org.hibernate.test.TestCase; @@ -12,17 +15,15 @@ import org.hibernate.test.tm.DummyTransactionManagerLookup; import org.hibernate.transaction.JDBCTransactionFactory; -import java.util.Map; - /** * Common requirement testing for each {@link org.hibernate.cache.CacheProvider} impl. * * @author Steve Ebersole */ public abstract class BaseCacheProviderTestCase extends TestCase { - - // note that a lot of the fucntionality here is intended to be used - // in creating specific tests for each CacheProvider that would extend + + // note that a lot of the fucntionality here is intended to be used + // in creating specific tests for each CacheProvider that would extend // from a base test case (this) for common requirement testing... public BaseCacheProviderTestCase(String x) { @@ -50,7 +51,7 @@ cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, DummyTransactionManagerLookup.class.getName() ); } else { - cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, JDBCTransactionFactory.class.getName() ); + cfg.setProperty( Environment.TRANSACTION_STRATEGY, JDBCTransactionFactory.class.getName() ); } } @@ -116,7 +117,15 @@ assertEquals( slcs.getPutCount(), 2 ); - Map map = (Map) slcs.getEntries().get( i.getId() ); + Object entry = slcs.getEntries().get( i.getId() ); + Map map; + if ( entry instanceof ReadWriteCache.Item ) { + map = new HashMap(); + map = (Map) ( (ReadWriteCache.Item) entry ).getValue(); + } + else { + map = (Map) entry; + } assertTrue( map.get("description").equals("A bog standard item") ); assertTrue( map.get("name").equals("widget") ); @@ -183,10 +192,19 @@ // check the version value in the cache... SecondLevelCacheStatistics slcs = sfi().getStatistics() .getSecondLevelCacheStatistics( VersionedItem.class.getName() ); - Map map = ( Map ) slcs.getEntries().get( item.getId() ); - Long cachedVersionValue = ( Long ) map.get( "_version" ); - assertEquals( initialVersion.longValue(), cachedVersionValue.longValue() ); + Object entry = slcs.getEntries().get( item.getId() ); + Long cachedVersionValue; + if ( entry instanceof ReadWriteCache.Lock ) { + //FIXME don't know what to test here + cachedVersionValue = new Long( ( (ReadWriteCache.Lock) entry).getUnlockTimestamp() ); + } + else { + cachedVersionValue = ( Long ) ( (Map) entry ).get( "_version" ); + assertEquals( initialVersion.longValue(), cachedVersionValue.longValue() ); + } + + // cleanup s = openSession(); txn = s.beginTransaction(); Modified: trunk/Hibernate3/test/org/hibernate/test/cache/CacheSuite.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/cache/CacheSuite.java 2006-05-05 18:01:32 UTC (rev 9894) +++ trunk/Hibernate3/test/org/hibernate/test/cache/CacheSuite.java 2006-05-05 19:27:17 UTC (rev 9895) @@ -4,6 +4,7 @@ import junit.framework.TestSuite; import org.hibernate.test.cache.treecache.optimistic.OptimisticTreeCacheTest; import org.hibernate.test.cache.treecache.pessimistic.TreeCacheTest; +import org.hibernate.test.cache.ehcache.EhCacheTest; /** * @author Steve Ebersole @@ -14,6 +15,7 @@ TestSuite suite = new TestSuite( "CacheProvider tests"); suite.addTest( OptimisticTreeCacheTest.suite() ); suite.addTest( TreeCacheTest.suite() ); + suite.addTest( EhCacheTest.suite() ); return suite; } } Added: trunk/Hibernate3/test/org/hibernate/test/cache/ehcache/EhCacheTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/cache/ehcache/EhCacheTest.java 2006-05-05 18:01:32 UTC (rev 9894) +++ trunk/Hibernate3/test/org/hibernate/test/cache/ehcache/EhCacheTest.java 2006-05-05 19:27:17 UTC (rev 9895) @@ -0,0 +1,47 @@ +//$Id: $ +package org.hibernate.test.cache.ehcache; + +import junit.framework.Test; +import junit.framework.TestSuite; +import org.hibernate.cache.EhCacheProvider; +import org.hibernate.cfg.Environment; +import org.hibernate.test.cache.BaseCacheProviderTestCase; + +/** + * @author Emmanuel Bernard + */ +public class EhCacheTest extends BaseCacheProviderTestCase { + + // note that a lot of the fucntionality here is intended to be used + // in creating specific tests for each CacheProvider that would extend + // from a base test case (this) for common requirement testing... + + public EhCacheTest(String x) { + super( x ); + } + + public static Test suite() { + return new TestSuite( EhCacheTest.class ); + } + + public String getCacheConcurrencyStrategy() { + return "read-write"; + } + + protected Class getCacheProvider() { + return EhCacheProvider.class; + } + + protected String getConfigResourceKey() { + return Environment.CACHE_PROVIDER_CONFIG; + } + + protected String getConfigResourceLocation() { + return "org/hibernate/test/cache/ehcache/ehcache.xml"; + } + + protected boolean useTransactionManager() { + return false; + } + +} Added: trunk/Hibernate3/test/org/hibernate/test/cache/ehcache/ehcache.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/cache/ehcache/ehcache.xml 2006-05-05 18:01:32 UTC (rev 9894) +++ trunk/Hibernate3/test/org/hibernate/test/cache/ehcache/ehcache.xml 2006-05-05 19:27:17 UTC (rev 9895) @@ -0,0 +1,88 @@ +<ehcache> + + <!-- Sets the path to the directory where cache .data files are created. + + If the path is a Java System Property it is replaced by + its value in the running VM. + + The following properties are translated: + user.home - User's home directory + user.dir - User's current working directory + java.io.tmpdir - Default temp file path --> + <diskStore path="java.io.tmpdir"/> + + + <!--Default Cache configuration. These will applied to caches programmatically created through + the CacheManager. + + The following attributes are required for defaultCache: + + maxInMemory - Sets the maximum number of objects that will be created in memory + eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element + is never expired. + timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used + if the element is not eternal. Idle time is now - last accessed time + timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used + if the element is not eternal. TTL is now - creation time + overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache + has reached the maxInMemory limit. + + --> + <defaultCache + maxElementsInMemory="10000" + eternal="false" + timeToIdleSeconds="120" + timeToLiveSeconds="120" + overflowToDisk="true" + /> + + <!--Predefined caches. Add your cache configuration settings here. + If you do not have a configuration for your cache a WARNING will be issued when the + CacheManager starts + + The following attributes are required for defaultCache: + + name - Sets the name of the cache. This is used to identify the cache. It must be unique. + maxInMemory - Sets the maximum number of objects that will be created in memory + eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element + is never expired. + timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used + if the element is not eternal. Idle time is now - last accessed time + timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used + if the element is not eternal. TTL is now - creation time + overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache + has reached the maxInMemory limit. + + --> + + <!-- Sample cache named sampleCache1 + This cache contains a maximum in memory of 10000 elements, and will expire + an element if it is idle for more than 5 minutes and lives for more than + 10 minutes. + + If there are more than 10000 elements it will overflow to the + disk cache, which in this configuration will go to wherever java.io.tmp is + defined on your system. On a standard Linux system this will be /tmp" + --> + <cache name="sampleCache1" + maxElementsInMemory="10000" + eternal="false" + timeToIdleSeconds="300" + timeToLiveSeconds="600" + overflowToDisk="true" + /> + + <!-- Sample cache named sampleCache2 + This cache contains 1000 elements. Elements will always be held in memory. + They are not expired. --> + <cache name="sampleCache2" + maxElementsInMemory="1000" + eternal="true" + timeToIdleSeconds="0" + timeToLiveSeconds="0" + overflowToDisk="false" + /> --> + + <!-- Place configuration for your caches following --> + +</ehcache> Modified: trunk/Hibernate3/test/org/hibernate/test/cache/treecache/optimistic/OptimisticTreeCacheTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/cache/treecache/optimistic/OptimisticTreeCacheTest.java 2006-05-05 18:01:32 UTC (rev 9894) +++ trunk/Hibernate3/test/org/hibernate/test/cache/treecache/optimistic/OptimisticTreeCacheTest.java 2006-05-05 19:27:17 UTC (rev 9895) @@ -1,15 +1,15 @@ package org.hibernate.test.cache.treecache.optimistic; +import junit.framework.Test; +import junit.framework.TestSuite; +import org.hibernate.cache.OptimisticTreeCacheProvider; +import org.hibernate.cfg.Environment; import org.hibernate.test.cache.BaseCacheProviderTestCase; import org.hibernate.test.tm.DummyTransactionManager; -import org.hibernate.cache.OptimisticTreeCacheProvider; -import org.hibernate.engine.SessionFactoryImplementor; +import org.jboss.cache.Fqn; import org.jboss.cache.TreeCache; -import org.jboss.cache.Fqn; +import org.jboss.cache.config.Option; import org.jboss.cache.optimistic.DataVersion; -import org.jboss.cache.config.Option; -import junit.framework.Test; -import junit.framework.TestSuite; /** * @author Steve Ebersole @@ -37,7 +37,7 @@ } protected String getConfigResourceKey() { - return OptimisticTreeCacheProvider.CONFIG_RESOURCE; + return Environment.CACHE_PROVIDER_CONFIG; } protected String getConfigResourceLocation() { Modified: trunk/Hibernate3/test/org/hibernate/test/cache/treecache/pessimistic/TreeCacheTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/cache/treecache/pessimistic/TreeCacheTest.java 2006-05-05 18:01:32 UTC (rev 9894) +++ trunk/Hibernate3/test/org/hibernate/test/cache/treecache/pessimistic/TreeCacheTest.java 2006-05-05 19:27:17 UTC (rev 9895) @@ -2,6 +2,7 @@ import org.hibernate.test.cache.BaseCacheProviderTestCase; import org.hibernate.cache.TreeCacheProvider; +import org.hibernate.cfg.Environment; import junit.framework.Test; import junit.framework.TestSuite; @@ -31,7 +32,7 @@ } protected String getConfigResourceKey() { - return TreeCacheProvider.CONFIG_RESOURCE; + return Environment.CACHE_PROVIDER_CONFIG; } protected String getConfigResourceLocation() { |
From: <hib...@li...> - 2006-05-05 18:01:45
|
Author: epbernard Date: 2006-05-05 14:01:32 -0400 (Fri, 05 May 2006) New Revision: 9894 Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/SingleTableTest.java trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/onetomany/City.java Log: ANN-120 support association table MapKey through formula Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java =================================================================== --- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java 2006-05-05 16:58:38 UTC (rev 9893) +++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/MapBinder.java 2006-05-05 18:01:32 UTC (rev 9894) @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.Random; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Embeddable; @@ -12,6 +13,9 @@ import org.hibernate.AssertionFailure; import org.hibernate.FetchMode; import org.hibernate.MappingException; +import org.hibernate.dialect.HSQLDialect; +import org.hibernate.sql.Template; +import org.hibernate.util.StringHelper; import org.hibernate.annotations.AccessType; import org.hibernate.cfg.AnnotatedClassType; import org.hibernate.cfg.AnnotationBinder; @@ -28,12 +32,16 @@ import org.hibernate.mapping.Collection; import org.hibernate.mapping.Column; import org.hibernate.mapping.Component; +import org.hibernate.mapping.DependantValue; import org.hibernate.mapping.Formula; import org.hibernate.mapping.Join; import org.hibernate.mapping.ManyToOne; +import org.hibernate.mapping.OneToMany; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.mapping.SimpleValue; +import org.hibernate.mapping.Table; +import org.hibernate.mapping.ToOne; import org.hibernate.mapping.Value; import org.hibernate.reflection.XAnnotatedElement; import org.hibernate.reflection.XClass; @@ -69,7 +77,8 @@ ); bindKeyFromAssociationTable( collType, persistentClasses, mapKeyPropertyName, property, isEmbedded, mappings, - mapKeyColumns, mapKeyManyToManyColumns + mapKeyColumns, mapKeyManyToManyColumns, + inverseColumns != null ? inverseColumns[0].getPropertyName() : null ); } }; @@ -78,7 +87,7 @@ private void bindKeyFromAssociationTable( String collType, Map persistentClasses, String mapKeyPropertyName, XProperty property, boolean isEmbedded, ExtendedMappings mappings, Ejb3Column[] mapKeyColumns, - Ejb3JoinColumn[] mapKeyManyToManyColumns + Ejb3JoinColumn[] mapKeyManyToManyColumns, String targetPropertyName ) { if ( mapKeyPropertyName != null ) { //this is an EJB3 @MapKey @@ -91,7 +100,7 @@ ); } org.hibernate.mapping.Map map = (org.hibernate.mapping.Map) this.collection; - Value indexValue = createFormulatedValue( mapProperty.getValue(), map ); + Value indexValue = createFormulatedValue( mapProperty.getValue(), map, targetPropertyName, associatedClass ); map.setIndex( indexValue ); } else { @@ -218,7 +227,52 @@ } } - protected Value createFormulatedValue(Value value, Collection collection) { + protected Value createFormulatedValue( + Value value, Collection collection, String targetPropertyName, PersistentClass associatedClass + ) { + Value element = collection.getElement(); + String fromAndWhere = null; + if ( ! ( element instanceof OneToMany ) ) { + String referencedPropertyName= null; + if ( element instanceof ToOne ) { + referencedPropertyName = ( (ToOne) element ).getReferencedPropertyName(); + } + else if ( element instanceof DependantValue ) { + //TODO this never happen I think + if ( propertyName != null ) { + Collection coll = (Collection) associatedClass.getProperty( propertyName ) + .getValue(); + referencedPropertyName = collection.getReferencedPropertyName(); + } + else { + throw new AnnotationException( "SecondaryTable JoinColumn cannot reference a non primary key" ); + } + } + Table table; + Iterator referencedEntityColumns; + if (referencedPropertyName == null) { + table = associatedClass.getTable(); + referencedEntityColumns = associatedClass.getIdentifier().getColumnIterator(); + } + else { + Property referencedProperty = associatedClass.getProperty( referencedPropertyName ); + table = referencedProperty.getValue().getTable(); + referencedEntityColumns = referencedProperty.getColumnIterator(); + } + String alias = "$alias$"; + StringBuilder fromAndWhereSb = new StringBuilder( " from " ) + .append( associatedClass.getTable().getName() ) + .append(" as ").append(alias).append(" where "); + Iterator collectionTableColumns = element.getColumnIterator(); + while ( collectionTableColumns.hasNext() ) { + Column colColumn = (Column) collectionTableColumns.next(); + Column refColumn = (Column) referencedEntityColumns.next(); + fromAndWhereSb.append(alias).append('.').append( refColumn.getQuotedName() ) + .append('=').append( colColumn.getQuotedName() ).append(','); + } + fromAndWhere = fromAndWhereSb.substring(0, fromAndWhereSb.length() - 1 ); + } + if ( value instanceof Component ) { Component component = (Component) value; Iterator properties = component.getPropertyIterator(); @@ -239,7 +293,9 @@ newProperty.setPersistentClass( current.getPersistentClass() ); newProperty.setPropertyAccessorName( current.getPropertyAccessorName() ); newProperty.setSelectable( current.isSelectable() ); - newProperty.setValue( createFormulatedValue( current.getValue(), collection) ); + newProperty.setValue( createFormulatedValue( current.getValue(), collection, targetPropertyName, + associatedClass + ) ); indexComponent.addProperty( newProperty ); } return indexComponent; @@ -262,19 +318,31 @@ targetValue.setTypeParameters( sourceValue.getTypeParameters() ); } Iterator columns = sourceValue.getColumnIterator(); + Random random = new Random(); while ( columns.hasNext() ) { Object current = columns.next(); Formula formula = new Formula(); + String formulaString; if ( current instanceof Column ) { - formula.setFormula( ( (Column) current ).getName() ); + formulaString = ( (Column) current ).getName(); //FIXME support quoted name } else if ( current instanceof Formula ) { - formula.setFormula( ( (Formula) current ).getFormula() ); + formulaString = ( (Formula) current ).getFormula(); } else { throw new AssertionFailure( "Unknown element in column iterator: " + current.getClass() ); } + if (fromAndWhere != null) { + formulaString = Template.renderWhereStringTemplate( formulaString, "$alias$", new HSQLDialect() ); + formulaString = "select " + formulaString + fromAndWhere; + formulaString = StringHelper.replace( + formulaString, + "$alias$", + "a" + random.nextInt( 16 ) + ); + } + formula.setFormula( formulaString ); targetValue.addFormula( formula ); } Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java 2006-05-05 16:58:38 UTC (rev 9893) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/entity/BasicHibernateAnnotationsTest.java 2006-05-05 18:01:32 UTC (rev 9894) @@ -214,12 +214,12 @@ s = openSession(); tx = s.beginTransaction(); s.enableFilter( "betweenLength" ).setParameter( "minLength", 5 ).setParameter( "maxLength", 50 ); - int count = ( (Integer) s.createQuery( "select count(*) from Forest" ).iterate().next() ).intValue(); + long count = ( (Long) s.createQuery( "select count(*) from Forest" ).iterate().next() ).intValue(); assertEquals( 1, count ); s.disableFilter( "betweenLength" ); s.enableFilter( "minLength" ).setParameter( "minLength", 5 ); - count = ( (Integer) s.createQuery( "select count(*) from Forest" ).iterate().next() ).intValue(); - assertEquals( 2, count ); + count = ( (Long) s.createQuery( "select count(*) from Forest" ).iterate().next() ).longValue(); + assertEquals( 2l, count ); s.disableFilter( "minLength" ); tx.rollback(); s.close(); Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/SingleTableTest.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/SingleTableTest.java 2006-05-05 16:58:38 UTC (rev 9893) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/inheritance/singletable/SingleTableTest.java 2006-05-05 18:01:32 UTC (rev 9894) @@ -41,7 +41,7 @@ s = openSession(); tx = s.beginTransaction(); - assertEquals( 1, s.createQuery( "select count(*) from Fruit f where f.class = 'Apple'" ).uniqueResult() ); + assertEquals( 1l, s.createQuery( "select count(*) from Fruit f where f.class = 'Apple'" ).uniqueResult() ); List result = s.createCriteria( Fruit.class ).list(); assertNotNull( result ); assertEquals( 2, result.size() ); @@ -70,7 +70,7 @@ s = openSession(); tx = s.beginTransaction(); assertEquals( - 1, s.createQuery( "select count(*) from Trash f where f.class = :disc" ) + 1l, s.createQuery( "select count(*) from Trash f where f.class = :disc" ) .setString( "disc", String.valueOf( "PaperTrash".hashCode() ) ).uniqueResult() ); List result = s.createCriteria( Trash.class ).list(); Modified: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/onetomany/City.java =================================================================== --- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/onetomany/City.java 2006-05-05 16:58:38 UTC (rev 9893) +++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/onetomany/City.java 2006-05-05 18:01:32 UTC (rev 9894) @@ -14,7 +14,7 @@ * @author Emmanuel Bernard */ @Entity -public class City { +class City { private Integer id; private String name; private List<Street> streets; @@ -40,7 +40,7 @@ @OneToMany(mappedBy = "city") @OrderBy("streetName, id") - public List<Street> getStreets() { + public synchronized List<Street> getStreets() { return streets; } |
From: <hib...@li...> - 2006-05-05 16:58:52
|
Author: ste...@jb... Date: 2006-05-05 12:58:38 -0400 (Fri, 05 May 2006) New Revision: 9893 Added: trunk/Hibernate3/lib/antlr-2.7.6.jar Removed: trunk/Hibernate3/lib/antlr-2.7.6rc1.jar Modified: trunk/Hibernate3/lib/version.properties Log: upgraded antlr to 2.7.6 Added: trunk/Hibernate3/lib/antlr-2.7.6.jar =================================================================== (Binary files differ) Property changes on: trunk/Hibernate3/lib/antlr-2.7.6.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Deleted: trunk/Hibernate3/lib/antlr-2.7.6rc1.jar =================================================================== (Binary files differ) Modified: trunk/Hibernate3/lib/version.properties =================================================================== --- trunk/Hibernate3/lib/version.properties 2006-05-05 12:17:17 UTC (rev 9892) +++ trunk/Hibernate3/lib/version.properties 2006-05-05 16:58:38 UTC (rev 9893) @@ -80,8 +80,8 @@ commons-logging.name=Commons Logging commons-logging.when=runtime, required -antlr.lib=antlr-2.7.6rc1.jar -antlr.version=2.7.6rc1 +antlr.lib=antlr-2.7.6.jar +antlr.version=2.7.6 antlr.name=ANother Tool for Language Recognition antlr.when=runtime, required |
From: <hib...@li...> - 2006-05-05 12:17:23
|
Author: max...@jb... Date: 2006-05-05 08:17:17 -0400 (Fri, 05 May 2006) New Revision: 9892 Modified: trunk/Hibernate3/test/org/hibernate/test/criteria/CriteriaQueryTest.java Log: ref to bug id Modified: trunk/Hibernate3/test/org/hibernate/test/criteria/CriteriaQueryTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/criteria/CriteriaQueryTest.java 2006-05-05 12:05:04 UTC (rev 9891) +++ trunk/Hibernate3/test/org/hibernate/test/criteria/CriteriaQueryTest.java 2006-05-05 12:17:17 UTC (rev 9892) @@ -116,7 +116,7 @@ .add( Subqueries.eq("Gavin King", dc2) ) .list(); - //TODO: join in subselect + //TODO: join in subselect: HHH-952 /*DetachedCriteria dc3 = DetachedCriteria.forClass(Student.class, "st") .createCriteria("enrolments") .createCriteria("course") |
From: <hib...@li...> - 2006-05-05 12:05:15
|
Author: max...@jb... Date: 2006-05-05 08:05:04 -0400 (Fri, 05 May 2006) New Revision: 9891 Modified: trunk/Hibernate3/test/org/hibernate/test/optlock/OptimisticLockTest.java Log: added failureexpected test for HHH-1677 Modified: trunk/Hibernate3/test/org/hibernate/test/optlock/OptimisticLockTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/optlock/OptimisticLockTest.java 2006-05-05 11:44:34 UTC (rev 9890) +++ trunk/Hibernate3/test/org/hibernate/test/optlock/OptimisticLockTest.java 2006-05-05 12:05:04 UTC (rev 9891) @@ -5,6 +5,7 @@ import junit.framework.TestSuite; import org.hibernate.Session; +import org.hibernate.StaleObjectStateException; import org.hibernate.Transaction; import org.hibernate.test.TestCase; @@ -57,6 +58,90 @@ s.close(); } + //TODO: also test that non-overlapping changes behavior. + public void testOptimisticLockDirtyDeleteFailureExpected() { + //HHH-1677 + + Session s = openSession(); + Transaction t = s.beginTransaction(); + Document doc = new Document(); + doc.setTitle("Hibernate in Action"); + doc.setAuthor("Bauer et al"); + doc.setSummary("Very boring book about persistence"); + doc.setText("blah blah yada yada yada"); + doc.setPubDate( new PublicationDate(2004) ); + s.save("Dirty", doc); + s.flush(); + doc.setSummary("A modern classic"); + s.flush(); + doc.getPubDate().setMonth( new Integer(3) ); + s.flush(); + t.commit(); + s.close(); + + s = openSession(); + t = s.beginTransaction(); + doc = (Document) s.get("Dirty", doc.getId()); + + Session other = openSession(); + Transaction othert = other.beginTransaction(); + Document otherDoc = (Document) other.get("Dirty", doc.getId()); + otherDoc.setSummary( "my other summary" ); + other.flush(); + othert.commit(); + other.close(); + + try { + s.delete(doc); + t.commit(); + fail("Should fail since other session have update the summary"); + } catch(StaleObjectStateException soe) { + // expected + } + s.close(); + } + + public void testOptimisticLockAllDeleteFailureExpected() { + //HHH-1677 + Session s = openSession(); + Transaction t = s.beginTransaction(); + Document doc = new Document(); + doc.setTitle("Hibernate in Action"); + doc.setAuthor("Bauer et al"); + doc.setSummary("Very boring book about persistence"); + doc.setText("blah blah yada yada yada"); + doc.setPubDate( new PublicationDate(2004) ); + s.save("Dirty", doc); + s.flush(); + doc.setSummary("A modern classic"); + s.flush(); + doc.getPubDate().setMonth( new Integer(3) ); + s.flush(); + t.commit(); + s.close(); + + s = openSession(); + t = s.beginTransaction(); + doc = (Document) s.get("All", doc.getId()); + + Session other = openSession(); + Transaction othert = other.beginTransaction(); + Document otherDoc = (Document) other.get("All", doc.getId()); + otherDoc.setSummary( "my other summary" ); + other.flush(); + othert.commit(); + other.close(); + + try { + s.delete(doc); + t.commit(); + fail("Should fail since other session have update the summary"); + } catch(StaleObjectStateException soe) { + // expected + } + s.close(); + } + protected String[] getMappings() { return new String[] { "optlock/Document.hbm.xml" }; |
From: <hib...@li...> - 2006-05-05 11:44:36
|
Author: max...@jb... Date: 2006-05-05 07:44:34 -0400 (Fri, 05 May 2006) New Revision: 9890 Modified: trunk/Hibernate3/src/org/hibernate/mapping/PersistentClass.java Log: minor: more informative exception Modified: trunk/Hibernate3/src/org/hibernate/mapping/PersistentClass.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/mapping/PersistentClass.java 2006-05-05 01:24:12 UTC (rev 9889) +++ trunk/Hibernate3/src/org/hibernate/mapping/PersistentClass.java 2006-05-05 11:44:34 UTC (rev 9890) @@ -411,7 +411,7 @@ while ( iter.hasNext() ) { Property prop = (Property) iter.next(); if ( !names.add( prop.getName() ) ) { - throw new MappingException( "duplicate property mapping: " + prop.getName() ); + throw new MappingException( "Duplicate property mapping of " + prop.getName() + " found in " + getEntityName()); } } } |
From: <hib...@li...> - 2006-05-05 01:24:45
|
Author: ste...@jb... Date: 2006-05-04 21:24:12 -0400 (Thu, 04 May 2006) New Revision: 9889 Modified: trunk/Hibernate3/src/org/hibernate/loader/JoinWalker.java trunk/Hibernate3/src/org/hibernate/loader/entity/CascadeEntityJoinWalker.java Log: fixed small bug in disallowing multiple bag fetches Modified: trunk/Hibernate3/src/org/hibernate/loader/JoinWalker.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/loader/JoinWalker.java 2006-05-05 01:04:16 UTC (rev 9888) +++ trunk/Hibernate3/src/org/hibernate/loader/JoinWalker.java 2006-05-05 01:24:12 UTC (rev 9889) @@ -565,7 +565,7 @@ if ( !isJoinedFetchEnabled(type, config, cascadeStyle) ) return -1; - if ( isTooDeep(currentDepth) || isTooManyCollections() ) return -1; + if ( isTooDeep(currentDepth) || ( type.isCollectionType() && isTooManyCollections() ) ) return -1; final boolean dupe = isDuplicateAssociation(lhsTable, lhsColumns, type); if (dupe) return -1; Modified: trunk/Hibernate3/src/org/hibernate/loader/entity/CascadeEntityJoinWalker.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/loader/entity/CascadeEntityJoinWalker.java 2006-05-05 01:04:16 UTC (rev 9888) +++ trunk/Hibernate3/src/org/hibernate/loader/entity/CascadeEntityJoinWalker.java 2006-05-05 01:24:12 UTC (rev 9889) @@ -33,7 +33,7 @@ } protected boolean isTooManyCollections() { - return countCollectionPersisters(associations)>1; + return countCollectionPersisters(associations)>0; } public String getComment() { |
From: <hib...@li...> - 2006-05-05 01:04:33
|
Author: ste...@jb... Date: 2006-05-04 21:04:16 -0400 (Thu, 04 May 2006) New Revision: 9888 Modified: trunk/Hibernate3/test/org/hibernate/test/legacy/ParentChildTest.java Log: fixed failures from "select count(*)" return type changing to LongType Modified: trunk/Hibernate3/test/org/hibernate/test/legacy/ParentChildTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/legacy/ParentChildTest.java 2006-05-05 01:02:49 UTC (rev 9887) +++ trunk/Hibernate3/test/org/hibernate/test/legacy/ParentChildTest.java 2006-05-05 01:04:16 UTC (rev 9888) @@ -628,7 +628,7 @@ s = openSession(); t = s.beginTransaction(); - Integer count = (Integer) s.createQuery("select count(*) from ContainerX as c join c.components as ce join ce.simple as s where ce.name='foo'").uniqueResult(); + Long count = (Long) s.createQuery("select count(*) from ContainerX as c join c.components as ce join ce.simple as s where ce.name='foo'").uniqueResult(); assertTrue( count.intValue()==1 ); List res = s.find("select c, s from ContainerX as c join c.components as ce join ce.simple as s where ce.name='foo'"); assertTrue(res.size()==1); |
From: <hib...@li...> - 2006-05-05 01:03:07
|
Author: ste...@jb... Date: 2006-05-04 21:02:49 -0400 (Thu, 04 May 2006) New Revision: 9887 Modified: trunk/Hibernate3/test/org/hibernate/test/legacy/MultiTableTest.java Log: fixed failures from "select count(*)" return type changing to LongType Modified: trunk/Hibernate3/test/org/hibernate/test/legacy/MultiTableTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/legacy/MultiTableTest.java 2006-05-05 00:51:27 UTC (rev 9886) +++ trunk/Hibernate3/test/org/hibernate/test/legacy/MultiTableTest.java 2006-05-05 01:02:49 UTC (rev 9887) @@ -123,7 +123,7 @@ assertTrue( sm.getChildren().size()==2 ); assertEquals( s.filter( sm.getMoreChildren(), "select count(*) where this.amount>-1 and this.name is null" ).iterator().next(), - new Integer(2) + new Long(2) ); assertEquals( "FOO", sm.getDerived() ); assertSame( |
From: <hib...@li...> - 2006-05-05 00:51:44
|
Author: ste...@jb... Date: 2006-05-04 20:51:27 -0400 (Thu, 04 May 2006) New Revision: 9886 Modified: trunk/Hibernate3/test/org/hibernate/test/instrument/runtime/InstrumentedClassLoader.java Log: minor clean ups Modified: trunk/Hibernate3/test/org/hibernate/test/instrument/runtime/InstrumentedClassLoader.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/instrument/runtime/InstrumentedClassLoader.java 2006-05-05 00:45:49 UTC (rev 9885) +++ trunk/Hibernate3/test/org/hibernate/test/instrument/runtime/InstrumentedClassLoader.java 2006-05-05 00:51:27 UTC (rev 9886) @@ -19,12 +19,11 @@ this.classTransformer = classTransformer; } - @Override - public Class<?> loadClass(String name) throws ClassNotFoundException { + public Class loadClass(String name) throws ClassNotFoundException { if ( name.startsWith( "java" ) ) return getParent().loadClass( name ); Class c = findLoadedClass( name ); if ( c != null ) return c; - InputStream is = this.getResourceAsStream( name.replace( ".", "/" ) + ".class" ); + InputStream is = this.getResourceAsStream( name.replace( '.', '/' ) + ".class" ); if ( is == null ) throw new ClassNotFoundException( name ); byte[] buffer = new byte[409600]; byte[] originalClass = new byte[0]; |
From: <hib...@li...> - 2006-05-05 00:46:53
|
Author: ste...@jb... Date: 2006-05-04 20:45:49 -0400 (Thu, 04 May 2006) New Revision: 9885 Modified: trunk/Hibernate3/src/org/hibernate/bytecode/AbstractClassTransformerImpl.java trunk/Hibernate3/src/org/hibernate/bytecode/ClassTransformer.java trunk/Hibernate3/src/org/hibernate/bytecode/cglib/CglibClassTransformer.java trunk/Hibernate3/src/org/hibernate/bytecode/javassist/JavassistClassTransformer.java Log: minor clean ups Modified: trunk/Hibernate3/src/org/hibernate/bytecode/AbstractClassTransformerImpl.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/bytecode/AbstractClassTransformerImpl.java 2006-05-04 22:39:06 UTC (rev 9884) +++ trunk/Hibernate3/src/org/hibernate/bytecode/AbstractClassTransformerImpl.java 2006-05-05 00:45:49 UTC (rev 9885) @@ -10,7 +10,7 @@ */ public abstract class AbstractClassTransformerImpl implements ClassTransformer { - final private Set<String> entities; + final private Set entities; final private String[] packages; @@ -20,20 +20,21 @@ this.entities = null; } else { - this.entities = new HashSet<String>(); - for ( String clazz : classes ) { - entities.add( clazz ); + this.entities = new HashSet(); + for ( int i = 0; i < classes.length; i++ ) { + entities.add( classes[i] ); } } } - public byte[] - transform( - ClassLoader loader, String className, Class<?> classBeingRedefined, - ProtectionDomain protectionDomain, byte[] classfileBuffer - ) { + public byte[] transform( + ClassLoader loader, + String className, + Class classBeingRedefined, + ProtectionDomain protectionDomain, + byte[] classfileBuffer) { boolean enhance = false; - String safeClassName = className.replace( "/", "." ); + String safeClassName = className.replace( '/', '.' ); if ( entities == null && packages == null ) { enhance = true; } @@ -41,8 +42,8 @@ enhance = true; } if ( ! enhance && packages != null ) { - for ( String packageName : packages ) { - if ( safeClassName.startsWith( packageName ) ) { + for ( int i = 0; i < packages.length; i++ ) { + if ( safeClassName.startsWith( packages[i] ) ) { enhance = true; break; } @@ -54,7 +55,9 @@ } protected abstract byte[] doTransform( - ClassLoader loader, String className, Class<?> classBeingRedefined, - ProtectionDomain protectionDomain, byte[] classfileBuffer - ); + ClassLoader loader, + String className, + Class classBeingRedefined, + ProtectionDomain protectionDomain, + byte[] classfileBuffer); } Modified: trunk/Hibernate3/src/org/hibernate/bytecode/ClassTransformer.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/bytecode/ClassTransformer.java 2006-05-04 22:39:06 UTC (rev 9884) +++ trunk/Hibernate3/src/org/hibernate/bytecode/ClassTransformer.java 2006-05-05 00:45:49 UTC (rev 9885) @@ -26,9 +26,9 @@ * @param classfileBuffer The input byte buffer in class file format * @return A well-formed class file that can be loaded */ - byte[] transform(ClassLoader loader, + public byte[] transform(ClassLoader loader, String classname, - Class<?> classBeingRedefined, + Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer); } Modified: trunk/Hibernate3/src/org/hibernate/bytecode/cglib/CglibClassTransformer.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/bytecode/cglib/CglibClassTransformer.java 2006-05-04 22:39:06 UTC (rev 9884) +++ trunk/Hibernate3/src/org/hibernate/bytecode/cglib/CglibClassTransformer.java 2006-05-05 00:45:49 UTC (rev 9885) @@ -40,9 +40,11 @@ } protected byte[] doTransform( - ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, - byte[] classfileBuffer - ) { + ClassLoader loader, + String className, + Class classBeingRedefined, + ProtectionDomain protectionDomain, + byte[] classfileBuffer) { ClassReader reader; try { reader = new ClassReader( new ByteArrayInputStream( classfileBuffer ) ); @@ -52,9 +54,9 @@ throw new HibernateException( "Unable to read class: " + e.getMessage() ); } - String name[] = ClassNameReader.getClassInfo( reader ); + String[] names = ClassNameReader.getClassInfo( reader ); ClassWriter w = new DebuggingClassWriter( true ); - ClassTransformer t = getClassTransformer( name ); + ClassTransformer t = getClassTransformer( names ); if ( t != null ) { if ( log.isDebugEnabled() ) { log.debug( "Enhancing " + className ); @@ -64,10 +66,7 @@ try { reader = new ClassReader( new ByteArrayInputStream( classfileBuffer ) ); new TransformingClassGenerator( - new ClassReaderGenerator( - reader, - attributes(), skipDebug() - ), t + new ClassReaderGenerator( reader, attributes(), skipDebug() ), t ).generateClass( w ); out = new ByteArrayOutputStream(); out.write( w.toByteArray() ); @@ -93,7 +92,6 @@ } private ClassTransformer getClassTransformer(String[] classInfo) { - if ( Arrays.asList( classInfo ).contains( InterceptFieldEnabled.class.getName() ) ) { return null; } @@ -110,6 +108,5 @@ } ); } - } } Modified: trunk/Hibernate3/src/org/hibernate/bytecode/javassist/JavassistClassTransformer.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/bytecode/javassist/JavassistClassTransformer.java 2006-05-04 22:39:06 UTC (rev 9884) +++ trunk/Hibernate3/src/org/hibernate/bytecode/javassist/JavassistClassTransformer.java 2006-05-05 00:45:49 UTC (rev 9885) @@ -32,10 +32,12 @@ } protected byte[] doTransform( - ClassLoader loader, String className, Class<?> classBeingRedefined, - ProtectionDomain protectionDomain, byte[] classfileBuffer - ) { - ClassFile classfile = null; + ClassLoader loader, + String className, + Class classBeingRedefined, + ProtectionDomain protectionDomain, + byte[] classfileBuffer) { + ClassFile classfile; try { // WARNING: classfile only classfile = new ClassFile( new DataInputStream( new ByteArrayInputStream( classfileBuffer ) ) ); |