Index: 3rdParty_sources/versions.txt =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/versions.txt,v diff -u -r1.11.2.1 -r1.11.2.2 --- 3rdParty_sources/versions.txt 30 Jul 2014 08:37:35 -0000 1.11.2.1 +++ 3rdParty_sources/versions.txt 30 Jul 2014 16:17:10 -0000 1.11.2.2 @@ -19,7 +19,7 @@ gson 2.2.4 -Hibernate Core 3.3.1 GA +Hibernate Core 4.3.5 httpunit 1.7 Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/AnnotationException.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/AssertionFailure.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/AssertionFailure.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/AssertionFailure.java 17 Aug 2012 14:36:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/AssertionFailure.java 30 Jul 2014 16:16:04 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,36 +20,44 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; -import org.hibernate.exception.NestableRuntimeException; +import org.hibernate.internal.CoreMessageLogger; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.jboss.logging.Logger; /** * Indicates failure of an assertion: a possible bug in Hibernate. * * @author Gavin King */ -public class AssertionFailure extends NestableRuntimeException { +public class AssertionFailure extends RuntimeException { + private static final long serialVersionUID = 1L; - private static final Logger log = LoggerFactory.getLogger( AssertionFailure.class ); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + AssertionFailure.class.getName() + ); - private static final String MESSAGE = "an assertion failure occured" + - " (this may indicate a bug in Hibernate, but is more likely due" + - " to unsafe use of the session)"; - - public AssertionFailure(String s) { - super( s ); - log.error( MESSAGE, this ); + /** + * Creates an instance of AssertionFailure using the given message. + * + * @param message The message explaining the reason for the exception + */ + public AssertionFailure(String message) { + super( message ); + LOG.failed( this ); } - public AssertionFailure(String s, Throwable t) { - super( s, t ); - log.error( MESSAGE, t ); + /** + * Creates an instance of AssertionFailure using the given message and underlying cause. + * + * @param message The message explaining the reason for the exception + * @param cause The underlying cause. + */ + public AssertionFailure(String message, Throwable cause) { + super( message, cause ); + LOG.failed( cause ); } - } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/BaseSessionEventListener.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/BasicQueryContract.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/CallbackException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/CallbackException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/CallbackException.java 17 Aug 2012 14:36:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/CallbackException.java 30 Jul 2014 16:16:05 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,37 +20,44 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; /** - * Should be thrown by persistent objects from Lifecycle - * or Interceptor callbacks. + * Intended to be thrown from {@link org.hibernate.classic.Lifecycle} and {@link Interceptor} callbacks. + *

+ * IMPL NOTE : This is a legacy exception type from back in the day before Hibernate moved to a untyped (runtime) + * exception strategy. * - * @see org.hibernate.classic.Lifecycle - * @see Interceptor * @author Gavin King */ - public class CallbackException extends HibernateException { - - public CallbackException(Exception root) { - super("An exception occurred in a callback", root); + /** + * Creates a CallbackException using the given underlying cause. + * + * @param cause The underlying cause + */ + public CallbackException(Exception cause) { + this( "An exception occurred in a callback", cause ); } + /** + * Creates a CallbackException using the given message. + * + * @param message The message explaining the reason for the exception + */ public CallbackException(String message) { - super(message); + super( message ); } - public CallbackException(String message, Exception e) { - super(message, e); + /** + * Creates a CallbackException using the given message and underlying cause. + * + * @param message The message explaining the reason for the exception + * @param cause The underlying cause + */ + public CallbackException(String message, Exception cause) { + super( message, cause ); } } - - - - - - Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/CustomEntityDirtinessStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/EmptyInterceptor.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/EmptyInterceptor.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/EmptyInterceptor.java 17 Aug 2012 14:36:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/EmptyInterceptor.java 30 Jul 2014 16:16:05 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; @@ -30,24 +29,28 @@ import org.hibernate.type.Type; /** - * An interceptor that does nothing. May be used as a base class - * for application-defined custom interceptors. + * An interceptor that does nothing. May be used as a base class for application-defined custom interceptors. * * @author Gavin King */ public class EmptyInterceptor implements Interceptor, Serializable { - + /** + * The singleton reference. + */ public static final Interceptor INSTANCE = new EmptyInterceptor(); - - protected EmptyInterceptor() {} + protected EmptyInterceptor() { + } + + @Override public void onDelete( Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {} + @Override public boolean onFlushDirty( Object entity, Serializable id, @@ -58,6 +61,7 @@ return false; } + @Override public boolean onLoad( Object entity, Serializable id, @@ -67,6 +71,7 @@ return false; } + @Override public boolean onSave( Object entity, Serializable id, @@ -76,18 +81,27 @@ return false; } - public void postFlush(Iterator entities) {} - public void preFlush(Iterator entities) {} + @Override + public void postFlush(Iterator entities) { + } + @Override + public void preFlush(Iterator entities) { + } + + @Override public Boolean isTransient(Object entity) { return null; } + @Override public Object instantiate(String entityName, EntityMode entityMode, Serializable id) { return null; } - public int[] findDirty(Object entity, + @Override + public int[] findDirty( + Object entity, Serializable id, Object[] currentState, Object[] previousState, @@ -96,26 +110,43 @@ return null; } + @Override public String getEntityName(Object object) { return null; } + @Override public Object getEntity(String entityName, Serializable id) { return null; } - public void afterTransactionBegin(Transaction tx) {} - public void afterTransactionCompletion(Transaction tx) {} - public void beforeTransactionCompletion(Transaction tx) {} + @Override + public void afterTransactionBegin(Transaction tx) { + } + @Override + public void afterTransactionCompletion(Transaction tx) { + } + + @Override + public void beforeTransactionCompletion(Transaction tx) { + } + + @Override public String onPrepareStatement(String sql) { return sql; } - public void onCollectionRemove(Object collection, Serializable key) throws CallbackException {} + @Override + public void onCollectionRemove(Object collection, Serializable key) throws CallbackException { + } - public void onCollectionRecreate(Object collection, Serializable key) throws CallbackException {} + @Override + public void onCollectionRecreate(Object collection, Serializable key) throws CallbackException { + } - public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException {} + @Override + public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException { + } -} \ No newline at end of file +} Index: 3rdParty_sources/hibernate-core/org/hibernate/FetchMode.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/FetchMode.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/FetchMode.java 17 Aug 2012 14:36:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/FetchMode.java 30 Jul 2014 16:16:06 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,14 +20,9 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - /** * Represents an association fetching strategy. This is used * together with the Criteria API to specify runtime @@ -36,58 +31,37 @@ * For HQL queries, use the FETCH keyword instead. * * @see Criteria#setFetchMode(java.lang.String, FetchMode) + * * @author Gavin King */ -public final class FetchMode implements Serializable { - private final String name; - private static final Map INSTANCES = new HashMap(); - - private FetchMode(String name) { - this.name=name; - } - public String toString() { - return name; - } +public enum FetchMode { /** * Default to the setting configured in the mapping file. */ - public static final FetchMode DEFAULT = new FetchMode("DEFAULT"); + DEFAULT, /** * Fetch using an outer join. Equivalent to fetch="join". */ - public static final FetchMode JOIN = new FetchMode("JOIN"); + JOIN, /** * Fetch eagerly, using a separate select. Equivalent to * fetch="select". */ - public static final FetchMode SELECT = new FetchMode("SELECT"); + SELECT; /** * Fetch lazily. Equivalent to outer-join="false". + * * @deprecated use FetchMode.SELECT */ + @Deprecated public static final FetchMode LAZY = SELECT; /** - * Fetch eagerly, using an outer join. Equivalent to - * outer-join="true". + * Fetch eagerly, using an outer join. Equivalent to outer-join="true". + * * @deprecated use FetchMode.JOIN */ + @Deprecated public static final FetchMode EAGER = JOIN; - - static { - INSTANCES.put( JOIN.name, JOIN ); - INSTANCES.put( SELECT.name, SELECT ); - INSTANCES.put( DEFAULT.name, DEFAULT ); - } - - private Object readResolve() { - return INSTANCES.get(name); - } - } - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/FlushMode.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/FlushMode.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/FlushMode.java 17 Aug 2012 14:36:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/FlushMode.java 30 Jul 2014 16:16:05 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008 Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,14 +20,9 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - /** * Represents a flushing strategy. The flush process synchronizes * database state with session state by detecting state changes @@ -39,77 +34,95 @@ * * @author Gavin King */ -public final class FlushMode implements Serializable { - private static final Map INSTANCES = new HashMap(); - - private final int level; - private final String name; - - private FlushMode(int level, String name) { - this.level = level; - this.name = name; - } - - public String toString() { - return name; - } - +public enum FlushMode { /** * The {@link Session} is never flushed unless {@link Session#flush} * is explicitly called by the application. This mode is very * efficient for read only transactions. * * @deprecated use {@link #MANUAL} instead. */ - public static final FlushMode NEVER = new FlushMode( 0, "NEVER" ); + @Deprecated + NEVER ( 0 ), /** * The {@link Session} is only ever flushed when {@link Session#flush} * is explicitly called by the application. This mode is very * efficient for read only transactions. */ - public static final FlushMode MANUAL = new FlushMode( 0, "MANUAL" ); + MANUAL( 0 ), /** * The {@link Session} is flushed when {@link Transaction#commit} * is called. */ - public static final FlushMode COMMIT = new FlushMode(5, "COMMIT"); + COMMIT(5 ), /** * The {@link Session} is sometimes flushed before query execution * in order to ensure that queries never return stale state. This * is the default flush mode. */ - public static final FlushMode AUTO = new FlushMode(10, "AUTO"); + AUTO(10 ), /** * The {@link Session} is flushed before every query. This is * almost always unnecessary and inefficient. */ - public static final FlushMode ALWAYS = new FlushMode(20, "ALWAYS"); - - public boolean lessThan(FlushMode other) { - return this.level
+ * * Inspection occurs before property values are written and after they are read - * from the database.
- *
+ * from the database. + * * There might be a single instance of Interceptor for a SessionFactory, or a new instance * might be specified for each Session. Whichever approach is used, the interceptor must be * serializable if the Session is to be serializable. This means that SessionFactory-scoped - * interceptors should implement readResolve().
- *
+ * interceptors should implement readResolve(). + * * The Session may not be invoked from a callback (nor may a callback cause a collection or proxy to - * be lazily initialized).
- *
+ * be lazily initialized). + * * Instead of implementing this interface directly, it is usually better to extend EmptyInterceptor * and override only the callback methods of interest. * - * @see SessionFactory#openSession(Interceptor) + * @see SessionBuilder#interceptor(Interceptor) + * @see SharedSessionBuilder#interceptor() * @see org.hibernate.cfg.Configuration#setInterceptor(Interceptor) * @see EmptyInterceptor + * * @author Gavin King */ public interface Interceptor { /** * Called just before an object is initialized. The interceptor may change the state, which will * be propagated to the persistent object. Note that when this method is called, entity will be * an empty uninitialized instance of the class. + *

+ * NOTE: The indexes across the state, propertyNames and types arrays match. * - * @return true if the user modified the state in any way. + * @param entity The entity instance being loaded + * @param id The identifier value being loaded + * @param state The entity state (which will be pushed into the entity instance) + * @param propertyNames The names of the entity properties, corresponding to the state. + * @param types The types of the entity properties, corresponding to the state. + * + * @return {@code true} if the user modified the state in any way. + * + * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. */ public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException; + /** * Called when an object is detected to be dirty, during a flush. The interceptor may modify the detected * currentState, which will be propagated to both the database and the persistent object. * Note that not all flushes end in actual synchronization with the database, in which case the * new currentState will be propagated to the object, but not necessarily (immediately) to * the database. It is strongly recommended that the interceptor not modify the previousState. + *

+ * NOTE: The indexes across the currentState, previousState, propertyNames and + * types arrays match. * - * @return true if the user modified the currentState in any way. + * @param entity The entity instance detected as being dirty and being flushed + * @param id The identifier of the entity + * @param currentState The entity's current state + * @param previousState The entity's previous (load time) state. + * @param propertyNames The names of the entity properties + * @param types The types of the entity properties + * + * @return {@code true} if the user modified the currentState in any way. + * + * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. */ public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) throws CallbackException; + /** * Called before an object is saved. The interceptor may modify the state, which will be used for * the SQL INSERT and propagated to the persistent object. * + * @param entity The entity instance whose state is being inserted + * @param id The identifier of the entity + * @param state The state of the entity which will be inserted + * @param propertyNames The names of the entity properties. + * @param types The types of the entity properties + * * @return true if the user modified the state in any way. + * + * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. */ public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException; + /** * Called before an object is deleted. It is not recommended that the interceptor modify the state. + * + * @param entity The entity instance being deleted + * @param id The identifier of the entity + * @param state The state of the entity + * @param propertyNames The names of the entity properties. + * @param types The types of the entity properties + * + * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. */ public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException; + /** * Called before a collection is (re)created. + * + * @param collection The collection instance. + * @param key The collection key value. + * + * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. */ public void onCollectionRecreate(Object collection, Serializable key) throws CallbackException; + /** * Called before a collection is deleted. + * + * @param collection The collection instance. + * @param key The collection key value. + * + * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. */ public void onCollectionRemove(Object collection, Serializable key) throws CallbackException; + /** * Called before a collection is updated. + * + * @param collection The collection instance. + * @param key The collection key value. + * + * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. */ public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException; + /** - * Called before a flush + * Called before a flush. + * + * @param entities The entities to be flushed. + * + * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. */ public void preFlush(Iterator entities) throws CallbackException; + /** * Called after a flush that actually ends in execution of the SQL statements required to synchronize * in-memory state with the database. + * + * @param entities The entities that were flushed. + * + * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. */ public void postFlush(Iterator entities) throws CallbackException; + /** * Called to distinguish between transient and detached entities. The return value determines the * state of the entity with respect to the current session. @@ -115,15 +186,25 @@ * @return Boolean or null to choose default behaviour */ public Boolean isTransient(Object entity); + /** * Called from flush(). The return value determines whether the entity is updated *

- * @param entity a persistent entity - * @return array of dirty property indices or null to choose default behaviour + * + * @param entity The entity for which to find dirty properties. + * @param id The identifier of the entity + * @param currentState The current entity state as taken from the entity instance + * @param previousState The state of the entity when it was last synchronized (generally when it was loaded) + * @param propertyNames The names of the entity properties. + * @param types The types of the entity properties + * + * @return array of dirty property indices or {@code null} to indicate Hibernate should perform default behaviour + * + * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. */ public int[] findDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types); /** @@ -134,38 +215,56 @@ * @param entityName the name of the entity * @param entityMode The type of entity instance to be returned. * @param id the identifier of the new instance + * * @return an instance of the class, or null to choose default behaviour + * + * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. */ public Object instantiate(String entityName, EntityMode entityMode, Serializable id) throws CallbackException; /** - * Get the entity name for a persistent or transient instance + * Get the entity name for a persistent or transient instance. + * * @param object an entity instance + * * @return the name of the entity + * + * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. */ public String getEntityName(Object object) throws CallbackException; /** - * Get a fully loaded entity instance that is cached externally + * Get a fully loaded entity instance that is cached externally. + * * @param entityName the name of the entity * @param id the instance identifier + * * @return a fully initialized entity - * @throws CallbackException + * + * @throws CallbackException Thrown if the interceptor encounters any problems handling the callback. */ public Object getEntity(String entityName, Serializable id) throws CallbackException; /** * Called when a Hibernate transaction is begun via the Hibernate Transaction * API. Will not be called if transactions are being controlled via some other * mechanism (CMT, for example). + * + * @param tx The Hibernate transaction facade object */ public void afterTransactionBegin(Transaction tx); + /** * Called before a transaction is committed (but not before rollback). + * + * @param tx The Hibernate transaction facade object */ public void beforeTransactionCompletion(Transaction tx); + /** * Called after a transaction is committed or rolled back. + * + * @param tx The Hibernate transaction facade object */ public void afterTransactionCompletion(Transaction tx); Index: 3rdParty_sources/hibernate-core/org/hibernate/InvalidMappingException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/InvalidMappingException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/InvalidMappingException.java 17 Aug 2012 14:36:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/InvalidMappingException.java 30 Jul 2014 16:16:05 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 20082011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,42 +20,125 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; +import org.hibernate.internal.jaxb.Origin; +import org.hibernate.internal.util.xml.XmlDocument; + /** * Thrown when a mapping is found to be invalid. - * Similar to MappingException, but this contains more info about the path and type of mapping (e.g. file, resource or url) + * + * Similar to MappingException, but this contains more info about the path and type of + * mapping (e.g. file, resource or url) * * @author Max Rydahl Andersen - * + * @author Steve Ebersole */ public class InvalidMappingException extends MappingException { - private final String path; private final String type; + /** + * Constructs an InvalidMappingException using the given information. + * + * @param customMessage The custom message explaining the exception condition + * @param type The type of invalid mapping document + * @param path The path (type specific) of the invalid mapping document + * @param cause The underlying cause + */ public InvalidMappingException(String customMessage, String type, String path, Throwable cause) { - super(customMessage, cause); - this.type=type; - this.path=path; + super( customMessage, cause ); + this.type = type; + this.path = path; } - + + /** + * Constructs an InvalidMappingException using the given information. + * + * @param customMessage The custom message explaining the exception condition + * @param type The type of invalid mapping document + * @param path The path (type specific) of the invalid mapping document + */ public InvalidMappingException(String customMessage, String type, String path) { - super(customMessage); + super( customMessage ); this.type=type; this.path=path; } - + + /** + * Constructs an InvalidMappingException using the given information. + * + * @param customMessage The custom message explaining the exception condition + * @param xmlDocument The document that was invalid + * @param cause The underlying cause + */ + public InvalidMappingException(String customMessage, XmlDocument xmlDocument, Throwable cause) { + this( customMessage, xmlDocument.getOrigin().getType(), xmlDocument.getOrigin().getName(), cause ); + } + + /** + * Constructs an InvalidMappingException using the given information. + * + * @param customMessage The custom message explaining the exception condition + * @param xmlDocument The document that was invalid + */ + public InvalidMappingException(String customMessage, XmlDocument xmlDocument) { + this( customMessage, xmlDocument.getOrigin().getType(), xmlDocument.getOrigin().getName() ); + } + + /** + * Constructs an InvalidMappingException using the given information. + * + * @param customMessage The custom message explaining the exception condition + * @param origin The origin of the invalid mapping document + */ + public InvalidMappingException(String customMessage, Origin origin) { + this( customMessage, origin.getType().toString(), origin.getName() ); + } + + /** + * Constructs an InvalidMappingException using the given information and a standard message. + * + * @param type The type of invalid mapping document + * @param path The path (type specific) of the invalid mapping document + */ public InvalidMappingException(String type, String path) { - this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path); + this( "Could not parse mapping document from " + type + (path==null?"":" " + path), type, path ); } + /** + * Constructs an InvalidMappingException using the given information and a standard message. + * + * @param type The type of invalid mapping document + * @param path The path (type specific) of the invalid mapping document + * @param cause The underlying cause + */ public InvalidMappingException(String type, String path, Throwable cause) { - this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path, cause); + this( "Could not parse mapping document from " + type + (path==null?"":" " + path), type, path, cause ); } + /** + * Constructs an InvalidMappingException using the given information. + * + * @param customMessage The custom message explaining the exception condition + * @param origin The origin of the invalid mapping document + * @param cause The underlying cause + */ + public InvalidMappingException(String customMessage, org.hibernate.internal.util.xml.Origin origin, Exception cause) { + this( customMessage, origin.getType(), origin.getName(), cause ); + } + + /** + * Constructs an InvalidMappingException using the given information. + * + * @param customMessage The custom message explaining the exception condition + * @param origin The origin of the invalid mapping document + */ + public InvalidMappingException(String customMessage, org.hibernate.internal.util.xml.Origin origin) { + this( customMessage, origin, null ); + } + public String getType() { return type; } Index: 3rdParty_sources/hibernate-core/org/hibernate/JDBCException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/JDBCException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/JDBCException.java 17 Aug 2012 14:36:38 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/JDBCException.java 30 Jul 2014 16:16:05 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,64 +20,80 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; import java.sql.SQLException; - /** - * Wraps an SQLException. Indicates that an exception - * occurred during a JDBC call. + * Wraps a {@link SQLException}. Indicates that an exception occurred during a JDBC call. * - * @see java.sql.SQLException * @author Gavin King + * + * @see java.sql.SQLException */ public class JDBCException extends HibernateException { + private final SQLException sqlException; + private final String sql; - private SQLException sqle; - private String sql; - - public JDBCException(String string, SQLException root) { - super(string, root); - sqle=root; + /** + * Constructs a JDBCException using the given information. + * + * @param message The message explaining the exception condition + * @param cause The underlying cause + */ + public JDBCException(String message, SQLException cause) { + this( message, cause, null ); } - public JDBCException(String string, SQLException root, String sql) { - this(string, root); + /** + * Constructs a JDBCException using the given information. + * + * @param message The message explaining the exception condition + * @param cause The underlying cause + * @param sql The sql being executed when the exception occurred + */ + public JDBCException(String message, SQLException cause, String sql) { + super( message, cause ); + this.sqlException = cause; this.sql = sql; } /** - * Get the SQLState of the underlying SQLException. - * @see java.sql.SQLException - * @return String + * Get the X/Open or ANSI SQL SQLState error code from the underlying {@link SQLException}. + * + * @return The X/Open or ANSI SQL SQLState error code; may return null. + * + * @see java.sql.SQLException#getSQLState() */ public String getSQLState() { - return sqle.getSQLState(); + return sqlException.getSQLState(); } /** - * Get the errorCode of the underlying SQLException. - * @see java.sql.SQLException - * @return int the error code + * Get the vendor specific error code from the underlying {@link SQLException}. + * + * @return The vendor specific error code + * + * @see java.sql.SQLException#getErrorCode() */ public int getErrorCode() { - return sqle.getErrorCode(); + return sqlException.getErrorCode(); } /** - * Get the underlying SQLException. - * @return SQLException + * Get the underlying {@link SQLException}. + * + * @return The SQLException */ public SQLException getSQLException() { - return sqle; + return sqlException; } /** - * Get the actual SQL statement that caused the exception - * (may be null) + * Get the actual SQL statement being executed when the exception occurred. + * + * @return The SQL statement; may return null. */ public String getSQL() { return sql; Index: 3rdParty_sources/hibernate-core/org/hibernate/LazyInitializationException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/LazyInitializationException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/LazyInitializationException.java 17 Aug 2012 14:36:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/LazyInitializationException.java 30 Jul 2014 16:16:06 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,32 +20,37 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; -import org.slf4j.LoggerFactory; +import org.hibernate.internal.CoreMessageLogger; +import org.jboss.logging.Logger; + /** - * Indicates access to unfetched data outside of a session context. - * For example, when an uninitialized proxy or collection is accessed - * after the session was closed. + * Indicates an attempt to access not-yet-fetched data outside of a session context. * + * For example, when an uninitialized proxy or collection is accessed after the session was closed. + * * @see Hibernate#initialize(java.lang.Object) * @see Hibernate#isInitialized(java.lang.Object) * @author Gavin King */ public class LazyInitializationException extends HibernateException { - public LazyInitializationException(String msg) { - super(msg); - LoggerFactory.getLogger( LazyInitializationException.class ).error( msg, this ); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + LazyInitializationException.class.getName() + ); + + /** + * Constructs a LazyInitializationException using the given message. + * + * @param message A message explaining the exception condition + */ + public LazyInitializationException(String message) { + super( message ); + LOG.trace( message, this ); } } - - - - - - Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/LobHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/LockMode.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/LockMode.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/LockMode.java 17 Aug 2012 14:36:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/LockMode.java 30 Jul 2014 16:16:04 -0000 1.1.2.1 @@ -24,10 +24,6 @@ */ package org.hibernate; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - /** * Instances represent a lock mode for a row of a relational * database table. It is not intended that users spend much @@ -36,94 +32,123 @@ * Some "advanced" users may wish to explicitly specify lock * levels. * - * @see Session#lock(Object,LockMode) * @author Gavin King + * @see Session#lock(Object, LockMode) */ -public final class LockMode implements Serializable { - private final int level; - private final String name; - private static final Map INSTANCES = new HashMap(); - - private LockMode(int level, String name) { - this.level=level; - this.name=name; - } - public String toString() { - return name; - } +public enum LockMode { /** - * Check if this lock mode is more restrictive than the given lock mode. - * - * @param mode LockMode to check - * @return true if this lock mode is more restrictive than given lock mode - */ - public boolean greaterThan(LockMode mode) { - return level > mode.level; - } - /** - * Check if this lock mode is less restrictive than the given lock mode. - * - * @param mode LockMode to check - * @return true if this lock mode is less restrictive than given lock mode - */ - public boolean lessThan(LockMode mode) { - return level < mode.level; - } - /** * No lock required. If an object is requested with this lock * mode, a READ lock will be obtained if it is * necessary to actually read the state from the database, * rather than pull it from a cache.
*
* This is the "default" lock mode. */ - public static final LockMode NONE = new LockMode(0, "NONE"); + NONE( 0 ), /** * A shared lock. Objects in this lock mode were read from * the database in the current transaction, rather than being * pulled from a cache. */ - public static final LockMode READ = new LockMode(5, "READ"); + READ( 5 ), /** * An upgrade lock. Objects loaded in this lock mode are * materialized using an SQL select ... for update. + * + * @deprecated instead use PESSIMISTIC_WRITE */ - public static final LockMode UPGRADE = new LockMode(10, "UPGRADE"); + @Deprecated + UPGRADE( 10 ), /** * Attempt to obtain an upgrade lock, using an Oracle-style * select for update nowait. The semantics of * this lock mode, once obtained, are the same as * UPGRADE. */ - public static final LockMode UPGRADE_NOWAIT = new LockMode(10, "UPGRADE_NOWAIT"); + UPGRADE_NOWAIT( 10 ), + /** + * Attempt to obtain an upgrade lock, using an Oracle-style + * select for update skip locked. The semantics of + * this lock mode, once obtained, are the same as + * UPGRADE. + */ + UPGRADE_SKIPLOCKED( 10 ), + + /** * A WRITE lock is obtained when an object is updated * or inserted. This lock mode is for internal use only and is * not a valid mode for load() or lock() (both * of which throw exceptions if WRITE is specified). */ - public static final LockMode WRITE = new LockMode(10, "WRITE"); + WRITE( 10 ), /** - * Similiar to {@link #UPGRADE} except that, for versioned entities, + * Similar to {@link #UPGRADE} except that, for versioned entities, * it results in a forced version increment. + * + * @deprecated instead use PESSIMISTIC_FORCE_INCREMENT */ - public static final LockMode FORCE = new LockMode( 15, "FORCE" ); + @Deprecated + FORCE( 15 ), - static { - INSTANCES.put( NONE.name, NONE ); - INSTANCES.put( READ.name, READ ); - INSTANCES.put( UPGRADE.name, UPGRADE ); - INSTANCES.put( UPGRADE_NOWAIT.name, UPGRADE_NOWAIT ); - INSTANCES.put( WRITE.name, WRITE ); - INSTANCES.put( FORCE.name, FORCE ); + /** + * start of javax.persistence.LockModeType equivalent modes + */ + + /** + * Optimistically assume that transaction will not experience contention for + * entities. The entity version will be verified near the transaction end. + */ + OPTIMISTIC( 6 ), + + /** + * Optimistically assume that transaction will not experience contention for + * entities. The entity version will be verified and incremented near the transaction end. + */ + OPTIMISTIC_FORCE_INCREMENT( 7 ), + + /** + * Implemented as PESSIMISTIC_WRITE. + * TODO: introduce separate support for PESSIMISTIC_READ + */ + PESSIMISTIC_READ( 12 ), + + /** + * Transaction will obtain a database lock immediately. + * TODO: add PESSIMISTIC_WRITE_NOWAIT + */ + PESSIMISTIC_WRITE( 13 ), + + /** + * Transaction will immediately increment the entity version. + */ + PESSIMISTIC_FORCE_INCREMENT( 17 ); + private final int level; + + private LockMode(int level) { + this.level = level; } - private Object readResolve() { - return parse( name ); + /** + * Check if this lock mode is more restrictive than the given lock mode. + * + * @param mode LockMode to check + * + * @return true if this lock mode is more restrictive than given lock mode + */ + public boolean greaterThan(LockMode mode) { + return level > mode.level; } - public static LockMode parse(String name) { - return ( LockMode ) INSTANCES.get(name); + /** + * Check if this lock mode is less restrictive than the given lock mode. + * + * @param mode LockMode to check + * + * @return true if this lock mode is less restrictive than given lock mode + */ + public boolean lessThan(LockMode mode) { + return level < mode.level; } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/LockOptions.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/MappingNotFoundException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/MappingNotFoundException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/MappingNotFoundException.java 17 Aug 2012 14:36:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/MappingNotFoundException.java 30 Jul 2014 16:16:06 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; @@ -30,28 +29,55 @@ * @author Max Rydahl Andersen */ public class MappingNotFoundException extends MappingException { - private final String path; private final String type; + /** + * Constructs a MappingNotFoundException using the given information. + * + * @param customMessage A message explaining the exception condition + * @param type The type of mapping that could not be found + * @param path The path (type specific) of the mapping that could not be found + * @param cause The underlying cause + */ public MappingNotFoundException(String customMessage, String type, String path, Throwable cause) { - super(customMessage, cause); - this.type=type; - this.path=path; + super( customMessage, cause ); + this.type = type; + this.path = path; } - + + /** + * Constructs a MappingNotFoundException using the given information. + * + * @param customMessage A message explaining the exception condition + * @param type The type of mapping that could not be found + * @param path The path (type specific) of the mapping that could not be found + */ public MappingNotFoundException(String customMessage, String type, String path) { - super(customMessage); - this.type=type; - this.path=path; + super( customMessage ); + this.type = type; + this.path = path; } - + + /** + * Constructs a MappingNotFoundException using the given information, using a standard message. + * + * @param type The type of mapping that could not be found + * @param path The path (type specific) of the mapping that could not be found + */ public MappingNotFoundException(String type, String path) { - this(type + ": " + path + " not found", type, path); + this( type + ": " + path + " not found", type, path ); } + /** + * Constructs a MappingNotFoundException using the given information, using a standard message. + * + * @param type The type of mapping that could not be found + * @param path The path (type specific) of the mapping that could not be found + * @param cause The underlying cause + */ public MappingNotFoundException(String type, String path, Throwable cause) { - this(type + ": " + path + " not found", type, path, cause); + this( type + ": " + path + " not found", type, path, cause ); } public String getType() { Index: 3rdParty_sources/hibernate-core/org/hibernate/NonUniqueObjectException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/NonUniqueObjectException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/NonUniqueObjectException.java 17 Aug 2012 14:36:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/NonUniqueObjectException.java 30 Jul 2014 16:16:06 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; @@ -29,39 +28,53 @@ import org.hibernate.pretty.MessageHelper; /** - * This exception is thrown when an operation would - * break session-scoped identity. This occurs if the - * user tries to associate two different instances of - * the same Java class with a particular identifier, - * in the scope of a single Session. + * This exception is thrown when an operation would break session-scoped identity. This occurs if the + * user tries to associate two different instances of the same Java class with a particular identifier, + * in the scope of a single Session. * * @author Gavin King */ public class NonUniqueObjectException extends HibernateException { private final Serializable identifier; private final String entityName; - public NonUniqueObjectException(String message, Serializable id, String clazz) { - super(message); - this.entityName = clazz; - this.identifier = id; + /** + * Constructs a NonUniqueObjectException using the given information. + * + * @param message A message explaining the exception condition + * @param entityId The identifier of the entity + * @param entityName The name of the entity + */ + public NonUniqueObjectException(String message, Serializable entityId, String entityName) { + super( message ); + this.entityName = entityName; + this.identifier = entityId; } - public NonUniqueObjectException(Serializable id, String clazz) { - this("a different object with the same identifier value was already associated with the session", id, clazz); + /** + * Constructs a NonUniqueObjectException using the given information, using a standard message. + * + * @param entityId The identifier of the entity + * @param entityName The name of the entity + */ + public NonUniqueObjectException(Serializable entityId, String entityName) { + this( + "A different object with the same identifier value was already associated with the session", + entityId, + entityName + ); } + public String getEntityName() { + return entityName; + } + public Serializable getIdentifier() { return identifier; } + @Override public String getMessage() { - return super.getMessage() + ": " + - MessageHelper.infoString(entityName, identifier); + return super.getMessage() + " : " + MessageHelper.infoString( entityName, identifier ); } - - public String getEntityName() { - return entityName; - } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/ObjectDeletedException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/ObjectDeletedException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/ObjectDeletedException.java 17 Aug 2012 14:36:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/ObjectDeletedException.java 30 Jul 2014 16:16:05 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,22 +20,26 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; import java.io.Serializable; /** - * Thrown when the user tries to do something illegal with a deleted - * object. + * Thrown when the user tries to do something illegal with a deleted object. * * @author Gavin King */ public class ObjectDeletedException extends UnresolvableObjectException { - - public ObjectDeletedException(String message, Serializable identifier, String clazz) { - super(message, identifier, clazz); + /** + * Constructs an ObjectDeletedException using the given information. + * + * @param message A message explaining the exception condition + * @param identifier The identifier of the entity + * @param entityName The name of the entity + */ + public ObjectDeletedException(String message, Serializable identifier, String entityName) { + super( message, identifier, entityName ); } } Index: 3rdParty_sources/hibernate-core/org/hibernate/ObjectNotFoundException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/ObjectNotFoundException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/ObjectNotFoundException.java 17 Aug 2012 14:36:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/ObjectNotFoundException.java 30 Jul 2014 16:16:06 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; @@ -40,8 +39,13 @@ * @author Gavin King */ public class ObjectNotFoundException extends UnresolvableObjectException { - - public ObjectNotFoundException(Serializable identifier, String clazz) { - super(identifier, clazz); + /** + * Constructs a ObjectNotFoundException using the given information. + * + * @param identifier The identifier of the entity + * @param entityName The name of the entity + */ + public ObjectNotFoundException(Serializable identifier, String entityName) { + super( identifier, entityName ); } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/OptimisticLockException.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/PropertyNotFoundException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/PropertyNotFoundException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/PropertyNotFoundException.java 17 Aug 2012 14:36:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/PropertyNotFoundException.java 30 Jul 2014 16:16:04 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; @@ -31,9 +30,12 @@ * @author Gavin King */ public class PropertyNotFoundException extends MappingException { - - public PropertyNotFoundException(String s) { - super(s); + /** + * Constructs a PropertyNotFoundException given the specified message. + * + * @param message A message explaining the exception condition + */ + public PropertyNotFoundException(String message) { + super( message ); } - } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/PropertySetterAccessException.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/QueryException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/QueryException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/QueryException.java 17 Aug 2012 14:36:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/QueryException.java 30 Jul 2014 16:16:04 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,52 +20,120 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; /** - * A problem occurred translating a Hibernate query to SQL - * due to invalid query syntax, etc. + * A problem occurred translating a Hibernate query to SQL due to invalid query syntax, etc. */ public class QueryException extends HibernateException { + private final String queryString; - private String queryString; - + /** + * Constructs a QueryException using the specified exception message. + * + * @param message A message explaining the exception condition + */ public QueryException(String message) { - super(message); + this( message, null, null ); } - public QueryException(String message, Throwable e) { - super(message, e); + + /** + * Constructs a QueryException using the specified exception message and cause. + * + * @param message A message explaining the exception condition + * @param cause The underlying cause + */ + public QueryException(String message, Exception cause) { + this( message, null, cause ); } + /** + * Constructs a QueryException using the specified exception message and query-string. + * + * @param message A message explaining the exception condition + * @param queryString The query being evaluated when the exception occurred + */ public QueryException(String message, String queryString) { - super(message); + this( message, queryString, null ); + } + + /** + * Constructs a QueryException using the specified exception message and query-string. + * + * @param message A message explaining the exception condition + * @param queryString The query being evaluated when the exception occurred + * @param cause The underlying cause + */ + public QueryException(String message, String queryString, Exception cause) { + super( message, cause ); this.queryString = queryString; } - public QueryException(Exception e) { - super(e); + /** + * Constructs a QueryException using the specified cause. + * + * @param cause The underlying cause + */ + public QueryException(Exception cause) { + this( "A query exception occurred", null, cause ); } + + /** + * Retrieve the query being evaluated when the exception occurred. May be null, but generally should not. + * + * @return The query string + */ public String getQueryString() { return queryString; } - public void setQueryString(String queryString) { - this.queryString = queryString; - } - + @Override public String getMessage() { - String msg = super.getMessage(); - if ( queryString!=null ) msg += " [" + queryString + ']'; + String msg = getOriginalMessage(); + if ( queryString != null ) { + msg += " [" + queryString + ']'; + } return msg; } -} + protected final String getOriginalMessage() { + return super.getMessage(); + } + /** + * Wraps this exception with another, of same kind, with the specified queryString. If this exception already + * has a queryString defined, the same exception ({@code this}) is returned. Otherwise the protected + * {@link #generateQueryException(String)} is called, to allow subclasses to properly create the correct + * subclass for return. + * + * @param queryString The query string that led to the QueryException + * + * @return {@code this}, if {@code this} has {@code null} for {@link #getQueryString()}; otherwise a new + * QueryException (or subclass) is returned. + */ + public final QueryException wrapWithQueryString(String queryString) { + if ( this.getQueryString() != null ) { + return this; + } + return generateQueryException( queryString ); + } - - - - + /** + * Called from {@link #wrapWithQueryString(String)} when we really need to generate a new QueryException + * (or subclass). + *

+ * NOTE : implementors should take care to use {@link #getOriginalMessage()} for the message, not + * {@link #getMessage()} + * + * @param queryString The query string + * + * @return The generated QueryException (or subclass) + * + * @see #getOriginalMessage() + */ + protected QueryException generateQueryException(String queryString) { + return new QueryException( getOriginalMessage(), queryString, this ); + } +} Index: 3rdParty_sources/hibernate-core/org/hibernate/ReplicationMode.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/ReplicationMode.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/ReplicationMode.java 17 Aug 2012 14:36:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/ReplicationMode.java 30 Jul 2014 16:16:06 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,78 +20,69 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - import org.hibernate.type.VersionType; /** * Represents a replication strategy. * - * @see Session#replicate(Object, ReplicationMode) * @author Gavin King + * @see Session#replicate(Object, ReplicationMode) */ -public abstract class ReplicationMode implements Serializable { - private final String name; - private static final Map INSTANCES = new HashMap(); - - public ReplicationMode(String name) { - this.name=name; - } - public String toString() { - return name; - } - public abstract boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType); +public enum ReplicationMode { /** * Throw an exception when a row already exists. */ - public static final ReplicationMode EXCEPTION = new ReplicationMode("EXCEPTION") { + EXCEPTION { + @Override public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) { - throw new AssertionFailure("should not be called"); + throw new AssertionFailure( "should not be called" ); } - }; + }, /** * Ignore replicated entities when a row already exists. */ - public static final ReplicationMode IGNORE = new ReplicationMode("IGNORE") { + IGNORE { + @Override public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) { return false; } - }; + }, /** * Overwrite existing rows when a row already exists. */ - public static final ReplicationMode OVERWRITE = new ReplicationMode("OVERWRITE") { + OVERWRITE { + @Override public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) { return true; } - }; + }, /** * When a row already exists, choose the latest version. */ - public static final ReplicationMode LATEST_VERSION = new ReplicationMode("LATEST_VERSION") { + LATEST_VERSION { + @Override + @SuppressWarnings("unchecked") public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) { - if (versionType==null) return true; //always overwrite nonversioned data - return versionType.getComparator().compare(currentVersion, newVersion) <= 0; + // always overwrite non-versioned data (because we don't know which is newer) + return versionType == null || versionType.getComparator().compare( currentVersion, newVersion ) <= 0; } }; - static { - INSTANCES.put( LATEST_VERSION.name, LATEST_VERSION ); - INSTANCES.put( IGNORE.name, IGNORE ); - INSTANCES.put( OVERWRITE.name, OVERWRITE ); - INSTANCES.put( EXCEPTION.name, EXCEPTION ); - } + /** + * Determine whether the mode dictates that the data being replicated should overwrite the data found. + * + * @param entity The entity being replicated + * @param currentVersion The version currently on the target database table. + * @param newVersion The replicating version + * @param versionType The version type + * + * @return {@code true} indicates the data should be overwritten; {@code false} indicates it should not. + */ + public abstract boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType); - private Object readResolve() { - return INSTANCES.get(name); - } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/ScrollMode.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/ScrollMode.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/ScrollMode.java 17 Aug 2012 14:36:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/ScrollMode.java 30 Jul 2014 16:16:05 -0000 1.1.2.1 @@ -24,74 +24,63 @@ */ package org.hibernate; -import java.io.Serializable; import java.sql.ResultSet; -import java.util.HashMap; -import java.util.Map; /** - * Specifies the type of JDBC scrollable result set to use - * underneath a ScrollableResults + * Specifies the type of JDBC scrollable result set to use underneath a {@link ScrollableResults}. * - * @see Query#scroll(ScrollMode) - * @see ScrollableResults * @author Gavin King */ -public final class ScrollMode implements Serializable { +public enum ScrollMode { + /** + * Requests a scrollable result that is only scrollable forwards. + * + * @see java.sql.ResultSet#TYPE_FORWARD_ONLY + */ + FORWARD_ONLY( ResultSet.TYPE_FORWARD_ONLY ), + + /** + * Requests a scrollable result which is sensitive to changes in the underlying data. + * + * @see java.sql.ResultSet#TYPE_SCROLL_SENSITIVE + */ + SCROLL_SENSITIVE( ResultSet.TYPE_SCROLL_SENSITIVE ), + + /** + * Requests a scrollable result which is insensitive to changes in the underlying data. + * + * Note that since the Hibernate session acts as a cache, you + * might need to explicitly evict objects, if you need to see + * changes made by other transactions. + * + * @see java.sql.ResultSet#TYPE_SCROLL_INSENSITIVE + */ + SCROLL_INSENSITIVE( ResultSet.TYPE_SCROLL_INSENSITIVE ); + private final int resultSetType; - private final String name; - private static final Map INSTANCES = new HashMap(); - private ScrollMode(int level, String name) { - this.resultSetType=level; - this.name=name; + private ScrollMode(int level) { + this.resultSetType = level; } - - public String toString() { - return name; - } - + /** + * Get the corresponding JDBC scroll type code constant value. + * * @return the JDBC result set type code */ public int toResultSetType() { return resultSetType; } - + /** - * @see java.sql.ResultSet.TYPE_FORWARD_ONLY + * Determine if {@code this} mode is "less than" the provided mode. + * + * @param other The provided mode + * + * @return {@code true} if this mode is less than the other. */ - public static final ScrollMode FORWARD_ONLY = new ScrollMode(ResultSet.TYPE_FORWARD_ONLY, "FORWARD_ONLY"); - /** - * @see java.sql.ResultSet.TYPE_SCROLL_SENSITIVE - */ - public static final ScrollMode SCROLL_SENSITIVE = new ScrollMode(ResultSet.TYPE_SCROLL_SENSITIVE, "SCROLL_SENSITIVE"); - /** - * Note that since the Hibernate session acts as a cache, you - * might need to expicitly evict objects, if you need to see - * changes made by other transactions. - * @see java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE - */ - public static final ScrollMode SCROLL_INSENSITIVE = new ScrollMode(ResultSet.TYPE_SCROLL_INSENSITIVE, "SCROLL_INSENSITIVE"); - public boolean lessThan(ScrollMode other) { - return this.resultSetTypeSessions. Usually an application has a single SessionFactory. - * Threads servicing client requests obtain Sessions from the factory.
- *
- * Implementors must be threadsafe.
- *
- * SessionFactorys are immutable. The behaviour of a SessionFactory is - * controlled by properties supplied at configuration time. These properties are defined - * on Environment. + * The main contract here is the creation of {@link Session} instances. Usually + * an application has a single {@link SessionFactory} instance and threads + * servicing client requests obtain {@link Session} instances from this factory. + *

+ * The internal state of a {@link SessionFactory} is immutable. Once it is created + * this internal state is set. This internal state includes all of the metadata + * about Object/Relational Mapping. + *

+ * Implementors must be threadsafe. * - * @see Session - * @see org.hibernate.cfg.Environment * @see org.hibernate.cfg.Configuration - * @see org.hibernate.connection.ConnectionProvider - * @see org.hibernate.transaction.TransactionFactory + * * @author Gavin King + * @author Steve Ebersole */ public interface SessionFactory extends Referenceable, Serializable { - /** - * Open a Session on the given connection. - *

- * Note that the second-level cache will be disabled if you - * supply a JDBC connection. Hibernate will not be able to track - * any statements you might have executed in the same transaction. - * Consider implementing your own ConnectionProvider. - * - * @param connection a connection provided by the application. - * @return Session + * Aggregator of special options used to build the SessionFactory. */ - public org.hibernate.classic.Session openSession(Connection connection); + public interface SessionFactoryOptions { + /** + * The service registry to use in building the factory. + * + * @return The service registry to use. + */ + public StandardServiceRegistry getServiceRegistry(); + /** + * Get the interceptor to use by default for all sessions opened from this factory. + * + * @return The interceptor to use factory wide. May be {@code null} + */ + public Interceptor getInterceptor(); + + /** + * Get the delegate for handling entity-not-found exception conditions. + * + * @return The specific EntityNotFoundDelegate to use, May be {@code null} + */ + public EntityNotFoundDelegate getEntityNotFoundDelegate(); + } + /** - * Create database connection and open a Session on it, specifying an - * interceptor. + * Get the special options used to build the factory. * - * @param interceptor a session-scoped interceptor - * @return Session - * @throws HibernateException + * @return The special options used to build the factory. */ - public org.hibernate.classic.Session openSession(Interceptor interceptor) throws HibernateException; + public SessionFactoryOptions getSessionFactoryOptions(); /** - * Open a Session on the given connection, specifying an interceptor. - *

- * Note that the second-level cache will be disabled if you - * supply a JDBC connection. Hibernate will not be able to track - * any statements you might have executed in the same transaction. - * Consider implementing your own ConnectionProvider. + * Obtain a {@link Session} builder. * - * @param connection a connection provided by the application. - * @param interceptor a session-scoped interceptor - * @return Session + * @return The session builder */ - public org.hibernate.classic.Session openSession(Connection connection, Interceptor interceptor); + public SessionBuilder withOptions(); /** - * Create database connection and open a Session on it. + * Open a {@link Session}. + *

+ * JDBC {@link Connection connection(s} will be obtained from the + * configured {@link org.hibernate.engine.jdbc.connections.spi.ConnectionProvider} as needed + * to perform requested work. * - * @return Session - * @throws HibernateException + * @return The created session. + * + * @throws HibernateException Indicates a problem opening the session; pretty rare here. */ - public org.hibernate.classic.Session openSession() throws HibernateException; + public Session openSession() throws HibernateException; /** * Obtains the current session. The definition of what exactly "current" - * means controlled by the {@link org.hibernate.context.CurrentSessionContext} impl configured + * means controlled by the {@link org.hibernate.context.spi.CurrentSessionContext} impl configured * for use. *

- * Note that for backwards compatibility, if a {@link org.hibernate.context.CurrentSessionContext} - * is not configured but a JTA {@link org.hibernate.transaction.TransactionManagerLookup} - * is configured this will default to the {@link org.hibernate.context.JTASessionContext} + * Note that for backwards compatibility, if a {@link org.hibernate.context.spi.CurrentSessionContext} + * is not configured but JTA is configured this will default to the {@link org.hibernate.context.internal.JTASessionContext} * impl. * * @return The current session. + * * @throws HibernateException Indicates an issue locating a suitable current session. */ - public org.hibernate.classic.Session getCurrentSession() throws HibernateException; + public Session getCurrentSession() throws HibernateException; /** - * Get the ClassMetadata associated with the given entity class + * Obtain a {@link StatelessSession} builder. * - * @see org.hibernate.metadata.ClassMetadata + * @return The stateless session builder */ - public ClassMetadata getClassMetadata(Class persistentClass) throws HibernateException; + public StatelessSessionBuilder withStatelessOptions(); /** - * Get the ClassMetadata associated with the given entity name + * Open a new stateless session. * - * @see org.hibernate.metadata.ClassMetadata - * @since 3.0 + * @return The created stateless session. */ - public ClassMetadata getClassMetadata(String entityName) throws HibernateException; + public StatelessSession openStatelessSession(); /** - * Get the CollectionMetadata associated with the named collection role + * Open a new stateless session, utilizing the specified JDBC + * {@link Connection}. * - * @see org.hibernate.metadata.CollectionMetadata + * @param connection Connection provided by the application. + * + * @return The created stateless session. */ - public CollectionMetadata getCollectionMetadata(String roleName) throws HibernateException; + public StatelessSession openStatelessSession(Connection connection); + /** + * Retrieve the {@link ClassMetadata} associated with the given entity class. + * + * @param entityClass The entity class + * + * @return The metadata associated with the given entity; may be null if no such + * entity was mapped. + * + * @throws HibernateException Generally null is returned instead of throwing. + */ + public ClassMetadata getClassMetadata(Class entityClass); /** - * Get all ClassMetadata as a Map from entityname String - * to metadata object + * Retrieve the {@link ClassMetadata} associated with the given entity class. * - * @see org.hibernate.metadata.ClassMetadata - * @return a map from String an entity name to ClassMetaData - * @since 3.0 changed key from Class to String + * @param entityName The entity class + * + * @return The metadata associated with the given entity; may be null if no such + * entity was mapped. + * + * @throws HibernateException Generally null is returned instead of throwing. + * @since 3.0 */ - public Map getAllClassMetadata() throws HibernateException; + public ClassMetadata getClassMetadata(String entityName); /** - * Get all CollectionMetadata as a Map from role name - * to metadata object + * Get the {@link CollectionMetadata} associated with the named collection role. * - * @see org.hibernate.metadata.CollectionMetadata + * @param roleName The collection role (in form [owning-entity-name].[collection-property-name]). + * + * @return The metadata associated with the given collection; may be null if no such + * collection was mapped. + * + * @throws HibernateException Generally null is returned instead of throwing. + */ + public CollectionMetadata getCollectionMetadata(String roleName); + + /** + * Retrieve the {@link ClassMetadata} for all mapped entities. + * + * @return A map containing all {@link ClassMetadata} keyed by the + * corresponding {@link String} entity-name. + * + * @throws HibernateException Generally empty map is returned instead of throwing. + * + * @since 3.0 changed key from {@link Class} to {@link String}. + */ + public Map getAllClassMetadata(); + + /** + * Get the {@link CollectionMetadata} for all mapped collections. + * * @return a map from String to CollectionMetadata + * + * @throws HibernateException Generally empty map is returned instead of throwing. */ - public Map getAllCollectionMetadata() throws HibernateException; + public Map getAllCollectionMetadata(); /** - * Get the statistics for this session factory + * Retrieve the statistics fopr this factory. + * + * @return The statistics. */ public Statistics getStatistics(); /** * Destroy this SessionFactory and release all resources (caches, - * connection pools, etc). It is the responsibility of the application - * to ensure that there are no open Sessions before calling - * close(). + * connection pools, etc). + *

+ * It is the responsibility of the application to ensure that there are no + * open {@link Session sessions} before calling this method as the impact + * on those {@link Session sessions} is indeterminate. + *

+ * No-ops if already {@link #isClosed closed}. + * + * @throws HibernateException Indicates an issue closing the factory. */ public void close() throws HibernateException; /** - * Was this SessionFactory already closed? + * Is this factory already closed? + * + * @return True if this factory is already closed; false otherwise. */ public boolean isClosed(); /** + * Obtain direct access to the underlying cache regions. + * + * @return The direct cache access API. + */ + public Cache getCache(); + + /** * Evict all entries from the second-level cache. This method occurs outside * of any transaction; it performs an immediate "hard" remove, so does not respect * any transaction isolation semantics of the usage strategy. Use with care. + * + * @param persistentClass The entity class for which to evict data. + * + * @throws HibernateException Generally will mean that either that + * 'persisttentClass' did not name a mapped entity or a problem + * communicating with underlying cache impl. + * + * @deprecated Use {@link Cache#evictEntityRegion(Class)} accessed through + * {@link #getCache()} instead. */ + @Deprecated public void evict(Class persistentClass) throws HibernateException; + /** * Evict an entry from the second-level cache. This method occurs outside * of any transaction; it performs an immediate "hard" remove, so does not respect * any transaction isolation semantics of the usage strategy. Use with care. + * + * @param persistentClass The entity class for which to evict data. + * @param id The entity id + * + * @throws HibernateException Generally will mean that either that + * 'persisttentClass' did not name a mapped entity or a problem + * communicating with underlying cache impl. + * + * @deprecated Use {@link Cache#containsEntity(Class, Serializable)} accessed through + * {@link #getCache()} instead. */ + @Deprecated public void evict(Class persistentClass, Serializable id) throws HibernateException; + /** * Evict all entries from the second-level cache. This method occurs outside * of any transaction; it performs an immediate "hard" remove, so does not respect * any transaction isolation semantics of the usage strategy. Use with care. + * + * @param entityName The entity name for which to evict data. + * + * @throws HibernateException Generally will mean that either that + * 'persisttentClass' did not name a mapped entity or a problem + * communicating with underlying cache impl. + * + * @deprecated Use {@link Cache#evictEntityRegion(String)} accessed through + * {@link #getCache()} instead. */ + @Deprecated public void evictEntity(String entityName) throws HibernateException; + /** * Evict an entry from the second-level cache. This method occurs outside * of any transaction; it performs an immediate "hard" remove, so does not respect * any transaction isolation semantics of the usage strategy. Use with care. + * + * @param entityName The entity name for which to evict data. + * @param id The entity id + * + * @throws HibernateException Generally will mean that either that + * 'persisttentClass' did not name a mapped entity or a problem + * communicating with underlying cache impl. + * + * @deprecated Use {@link Cache#evictEntity(String,Serializable)} accessed through + * {@link #getCache()} instead. */ + @Deprecated public void evictEntity(String entityName, Serializable id) throws HibernateException; + /** * Evict all entries from the second-level cache. This method occurs outside * of any transaction; it performs an immediate "hard" remove, so does not respect * any transaction isolation semantics of the usage strategy. Use with care. + * + * @param roleName The name of the collection role whose regions should be evicted + * + * @throws HibernateException Generally will mean that either that + * 'roleName' did not name a mapped collection or a problem + * communicating with underlying cache impl. + * + * @deprecated Use {@link Cache#evictCollectionRegion(String)} accessed through + * {@link #getCache()} instead. */ + @Deprecated public void evictCollection(String roleName) throws HibernateException; + /** * Evict an entry from the second-level cache. This method occurs outside * of any transaction; it performs an immediate "hard" remove, so does not respect * any transaction isolation semantics of the usage strategy. Use with care. + * + * @param roleName The name of the collection role + * @param id The id of the collection owner + * + * @throws HibernateException Generally will mean that either that + * 'roleName' did not name a mapped collection or a problem + * communicating with underlying cache impl. + * + * @deprecated Use {@link Cache#evictCollection(String,Serializable)} accessed through + * {@link #getCache()} instead. */ + @Deprecated public void evictCollection(String roleName, Serializable id) throws HibernateException; /** - * Evict any query result sets cached in the default query cache region. - */ - public void evictQueries() throws HibernateException; - /** * Evict any query result sets cached in the named query cache region. + * + * @param cacheRegion The named query cache region from which to evict. + * + * @throws HibernateException Since a not-found 'cacheRegion' simply no-ops, + * this should indicate a problem communicating with underlying cache impl. + * + * @deprecated Use {@link Cache#evictQueryRegion(String)} accessed through + * {@link #getCache()} instead. */ + @Deprecated public void evictQueries(String cacheRegion) throws HibernateException; + /** - * Get a new stateless session. + * Evict any query result sets cached in the default query cache region. + * + * @throws HibernateException Indicate a problem communicating with + * underlying cache impl. + * + * @deprecated Use {@link Cache#evictQueryRegions} accessed through + * {@link #getCache()} instead. */ - public StatelessSession openStatelessSession(); - /** - * Get a new stateless session for the given JDBC connection. - */ - public StatelessSession openStatelessSession(Connection connection); + @Deprecated + public void evictQueries() throws HibernateException; /** * Obtain a set of the names of all filters defined on this SessionFactory. @@ -244,4 +384,20 @@ * @throws HibernateException If no filter defined with the given name. */ public FilterDefinition getFilterDefinition(String filterName) throws HibernateException; + + /** + * Determine if this session factory contains a fetch profile definition + * registered under the given name. + * + * @param name The name to check + * @return True if there is such a fetch profile; false otherwise. + */ + public boolean containsFetchProfileDefinition(String name); + + /** + * Retrieve this factory's {@link TypeHelper}. + * + * @return The factory's {@link TypeHelper} + */ + public TypeHelper getTypeHelper(); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/SharedSessionBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/SharedSessionContract.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/SimpleNaturalIdLoadAccess.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/StaleObjectStateException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/StaleObjectStateException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/StaleObjectStateException.java 17 Aug 2012 14:36:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/StaleObjectStateException.java 30 Jul 2014 16:16:04 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; @@ -29,19 +28,24 @@ import org.hibernate.pretty.MessageHelper; /** - * A StaleStateException that carries information - * about a particular entity instance that was the source - * of the failure. + * A specialized StaleStateException that carries information about the particular entity + * instance that was the source of the failure. * * @author Gavin King */ public class StaleObjectStateException extends StaleStateException { private final String entityName; private final Serializable identifier; - public StaleObjectStateException(String persistentClass, Serializable identifier) { - super("Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)"); - this.entityName = persistentClass; + /** + * Constructs a StaleObjectStateException using the supplied information. + * + * @param entityName The name of the entity + * @param identifier The identifier of the entity + */ + public StaleObjectStateException(String entityName, Serializable identifier) { + super( "Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)" ); + this.entityName = entityName; this.identifier = identifier; } @@ -54,8 +58,7 @@ } public String getMessage() { - return super.getMessage() + ": " + - MessageHelper.infoString(entityName, identifier); + return super.getMessage() + " : " + MessageHelper.infoString( entityName, identifier ); } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/StatelessSessionBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/TypeMismatchException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/TypeMismatchException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/TypeMismatchException.java 17 Aug 2012 14:36:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/TypeMismatchException.java 30 Jul 2014 16:16:04 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,25 +20,21 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; /** - * Used when a user provided type does not match the expected one + * Used when a user provided type does not match the expected one. * * @author Emmanuel Bernard */ public class TypeMismatchException extends HibernateException { - public TypeMismatchException(Throwable root) { - super( root ); + /** + * Constructs a TypeMismatchException using the supplied message. + * + * @param message The message explaining the exception condition + */ + public TypeMismatchException(String message) { + super( message ); } - - public TypeMismatchException(String s) { - super( s ); - } - - public TypeMismatchException(String string, Throwable root) { - super( string, root ); - } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/Version.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/WrongClassException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/WrongClassException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/WrongClassException.java 17 Aug 2012 14:36:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/WrongClassException.java 30 Jul 2014 16:16:04 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,51 +20,47 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate; import java.io.Serializable; /** - * Thrown when Session.load() selects a row with - * the given primary key (identifier value) but the row's - * discriminator value specifies a subclass that is not - * assignable to the class requested by the user. + * Thrown when loading an entity (by identifier) results in a value that cannot be treated as the subclass + * type requested by the caller. * * @author Gavin King */ public class WrongClassException extends HibernateException { - private final Serializable identifier; private final String entityName; - public WrongClassException(String msg, Serializable identifier, String clazz) { - super(msg); + /** + * Constructs a WrongClassException using the supplied information. + * + * @param message A message explaining the exception condition + * @param identifier The identifier of the entity + * @param entityName The entity-type requested + */ + public WrongClassException(String message, Serializable identifier, String entityName) { + super( + String.format( + "Object [id=%s] was not of the specified subclass [%s] : %s", + identifier, + entityName, + message + ) + ); this.identifier = identifier; - this.entityName = clazz; + this.entityName = entityName; } - public Serializable getIdentifier() { - return identifier; - } - public String getMessage() { - return "Object with id: " + - identifier + - " was not of the specified subclass: " + - entityName + - " (" + super.getMessage() + ")" ; - } - public String getEntityName() { return entityName; } + public Serializable getIdentifier() { + return identifier; + } } - - - - - - Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/hibernate-configuration-3.0.dtd'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/hibernate-mapping-3.0.dtd'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/AccessType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Any.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/AnyMetaDef.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/AnyMetaDefs.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/AttributeAccessor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/BatchSize.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Cache.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/CacheConcurrencyStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/CacheModeType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Cascade.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/CascadeType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Check.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/CollectionId.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/CollectionType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/ColumnDefault.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/ColumnTransformer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/ColumnTransformers.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Columns.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/CreationTimestamp.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/DiscriminatorFormula.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/DiscriminatorOptions.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/DynamicInsert.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/DynamicUpdate.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Entity.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Fetch.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/FetchMode.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/FetchProfile.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/FetchProfiles.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Filter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/FilterDef.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/FilterDefs.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/FilterJoinTable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/FilterJoinTables.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Filters.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/FlushModeType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/ForeignKey.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Formula.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Generated.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/GenerationTime.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/GeneratorType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/GenericGenerator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/GenericGenerators.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Immutable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Index.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/IndexColumn.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/JoinColumnOrFormula.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/JoinColumnsOrFormulas.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/JoinFormula.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/LazyCollection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/LazyCollectionOption.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/LazyToOne.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/LazyToOneOption.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/ListIndexBase.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Loader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/ManyToAny.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/MapKeyType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/MetaValue.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/NamedNativeQueries.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/NamedNativeQuery.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/NamedQueries.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/NamedQuery.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Nationalized.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/NaturalId.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/NaturalIdCache.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/NotFound.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/NotFoundAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/OnDelete.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/OnDeleteAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/OptimisticLock.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/OptimisticLockType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/OptimisticLocking.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/OrderBy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/ParamDef.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Parameter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Parent.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Persister.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Polymorphism.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/PolymorphismType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Proxy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/QueryHints.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/ResultCheckStyle.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/RowId.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/SQLDelete.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/SQLDeleteAll.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/SQLInsert.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/SQLUpdate.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/SelectBeforeUpdate.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Sort.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/SortComparator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/SortNatural.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/SortType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Source.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/SourceType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/SqlFragmentAlias.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Subselect.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Synchronize.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Table.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Tables.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Target.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Tuplizer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Tuplizers.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Type.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/TypeDef.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/TypeDefs.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/UpdateTimestamp.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/ValueGenerationType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/Where.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/WhereJoinTable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/annotations/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/AbstractClassTransformerImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/BasicProxyFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/BytecodeProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/ClassTransformer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/InstrumentedClassLoader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/ProxyFactoryFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/ReflectionOptimizer.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/bytecode/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/bytecode/package.html,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/bytecode/package.html 17 Aug 2012 14:33:54 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/bytecode/package.html 30 Jul 2014 16:16:33 -0000 1.1.2.1 @@ -1,10 +1,10 @@ @@ -46,9 +45,6 @@

- Currently, both CGLIB and Javassist are supported out-of-the-box. -

-

Note that for field-level interception, simply plugging in a new {@link BytecodeProvider} is not enough for Hibernate to be able to recognize new providers. You would additionally need to make appropriate code changes to the {@link org.hibernate.intercept.Helper} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/buildtime/internal/JavassistInstrumenter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/buildtime/internal/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/buildtime/spi/AbstractInstrumenter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/buildtime/spi/BasicClassFilter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/buildtime/spi/ClassDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/buildtime/spi/ClassFilter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/buildtime/spi/ExecutionException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/buildtime/spi/FieldFilter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/buildtime/spi/Instrumenter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/buildtime/spi/Logger.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/buildtime/spi/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/cglib/AccessOptimizerAdapter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/cglib/BytecodeProviderImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/cglib/CglibClassTransformer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/cglib/InstantiationOptimizerAdapter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/cglib/ReflectionOptimizerImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/enhance/EnhancementException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/enhance/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/enhance/spi/CollectionTracker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/enhance/spi/CompositeOwnerTracker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/enhance/spi/EnhancementContext.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/enhance/spi/Enhancer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/enhance/spi/EnhancerConstants.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/enhance/spi/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/instrumentation/package.html'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/instrumentation/internal/FieldInterceptionHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/instrumentation/internal/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/instrumentation/internal/javassist/FieldInterceptorImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/instrumentation/internal/javassist/JavassistHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/instrumentation/internal/javassist/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/instrumentation/spi/AbstractFieldInterceptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/instrumentation/spi/FieldInterceptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/instrumentation/spi/LazyPropertyInitializer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/instrumentation/spi/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/AccessOptimizerAdapter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/BulkAccessor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/BulkAccessorException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/BulkAccessorFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/BytecodeProviderImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/FastClass.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/FieldFilter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/FieldHandled.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/FieldHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/FieldTransformer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/InstantiationOptimizerAdapter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/JavassistClassTransformer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/ProxyFactoryFactoryImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/ReflectionOptimizerImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/TransformingClassLoader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/internal/javassist/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/AccessOptimizerAdapter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/BulkAccessor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/BulkAccessorException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/BulkAccessorFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/BytecodeProviderImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/FastClass.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/FieldFilter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/FieldHandled.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/FieldHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/FieldTransformer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/InstantiationOptimizerAdapter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/JavassistClassTransformer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/ProxyFactoryFactoryImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/ReflectionOptimizerImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/javassist/TransformingClassLoader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/spi/AbstractClassTransformerImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/spi/BasicProxyFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/spi/ByteCodeHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/spi/BytecodeProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/spi/ClassTransformer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/spi/EntityInstrumentationMetadata.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/spi/InstrumentedClassLoader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/spi/NotInstrumentedException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/spi/ProxyFactoryFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/spi/ReflectionOptimizer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/spi/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/util/BasicClassFilter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/util/ByteCodeHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/util/ClassDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/util/ClassFilter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/bytecode/util/FieldFilter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/classic/Lifecycle.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/classic/Lifecycle.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/classic/Lifecycle.java 17 Aug 2012 14:34:03 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/classic/Lifecycle.java 30 Jul 2014 16:16:48 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.classic; - import java.io.Serializable; import org.hibernate.CallbackException; @@ -76,7 +75,7 @@ * Called when an entity is saved. * @param s the session * @return true to veto save - * @throws CallbackException + * @throws CallbackException Indicates a problem happened during callback */ public boolean onSave(Session s) throws CallbackException; @@ -86,15 +85,15 @@ * state is persisted during a flush. * @param s the session * @return true to veto update - * @throws CallbackException + * @throws CallbackException Indicates a problem happened during callback */ public boolean onUpdate(Session s) throws CallbackException; /** * Called when an entity is deleted. * @param s the session * @return true to veto delete - * @throws CallbackException + * @throws CallbackException Indicates a problem happened during callback */ public boolean onDelete(Session s) throws CallbackException; @@ -109,9 +108,3 @@ */ public void onLoad(Session s, Serializable id); } - - - - - - Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/classic/Session.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/classic/Validatable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/classic/ValidationFailure.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/AbstractPersistentCollection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/PersistentArrayHolder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/PersistentBag.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/PersistentCollection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/PersistentElementHolder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/PersistentIdentifierBag.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/PersistentIndexedElementHolder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/PersistentList.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/PersistentListElementHolder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/PersistentMap.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/PersistentMapElementHolder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/PersistentSet.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/PersistentSortedMap.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/PersistentSortedSet.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/internal/AbstractPersistentCollection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/internal/PersistentArrayHolder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/internal/PersistentBag.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/internal/PersistentElementHolder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/internal/PersistentIdentifierBag.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/internal/PersistentIndexedElementHolder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/internal/PersistentList.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/internal/PersistentListElementHolder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/internal/PersistentMap.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/internal/PersistentMapElementHolder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/internal/PersistentSet.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/internal/PersistentSortedMap.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/internal/PersistentSortedSet.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/internal/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/spi/PersistentCollection.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/collection/spi/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/criterion/MatchMode.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/criterion/MatchMode.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/criterion/MatchMode.java 17 Aug 2012 14:33:50 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/criterion/MatchMode.java 30 Jul 2014 16:17:03 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,80 +20,63 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.criterion; -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - /** * Represents an strategy for matching strings using "like". * - * @see Example#enableLike(MatchMode) * @author Gavin King + * @see Example#enableLike(MatchMode) */ -public abstract class MatchMode implements Serializable { - private final String name; - private static final Map INSTANCES = new HashMap(); +public enum MatchMode { - protected MatchMode(String name) { - this.name=name; - } - public String toString() { - return name; - } - /** * Match the entire string to the pattern */ - public static final MatchMode EXACT = new MatchMode("EXACT") { + EXACT { + @Override public String toMatchString(String pattern) { return pattern; } - }; + }, /** * Match the start of the string to the pattern */ - public static final MatchMode START = new MatchMode("START") { + START { + @Override public String toMatchString(String pattern) { return pattern + '%'; } - }; + }, /** * Match the end of the string to the pattern */ - public static final MatchMode END = new MatchMode("END") { + END { + @Override public String toMatchString(String pattern) { return '%' + pattern; } - }; + }, /** * Match the pattern anywhere in the string */ - public static final MatchMode ANYWHERE = new MatchMode("ANYWHERE") { + ANYWHERE { + @Override public String toMatchString(String pattern) { return '%' + pattern + '%'; } }; - static { - INSTANCES.put( EXACT.name, EXACT ); - INSTANCES.put( END.name, END ); - INSTANCES.put( START.name, START ); - INSTANCES.put( ANYWHERE.name, ANYWHERE ); - } - - private Object readResolve() { - return INSTANCES.get(name); - } - /** - * convert the pattern, by appending/prepending "%" + * Convert the pattern, by appending/prepending "%" + * + * @param pattern The pattern for convert according to the mode + * + * @return The converted pattern */ public abstract String toMatchString(String pattern); Index: 3rdParty_sources/hibernate-core/org/hibernate/criterion/Order.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/criterion/Order.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/criterion/Order.java 17 Aug 2012 14:33:48 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/criterion/Order.java 30 Jul 2014 16:17:03 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,87 +20,153 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.criterion; import java.io.Serializable; import java.sql.Types; import org.hibernate.Criteria; -import org.hibernate.HibernateException; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.NullPrecedence; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.type.Type; /** - * Represents an order imposed upon a Criteria result set + * Represents an ordering imposed upon the results of a Criteria + * * @author Gavin King + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) */ public class Order implements Serializable { - private boolean ascending; private boolean ignoreCase; private String propertyName; - - public String toString() { - return propertyName + ' ' + (ascending?"asc":"desc"); + private NullPrecedence nullPrecedence; + + /** + * Ascending order + * + * @param propertyName The property to order on + * + * @return The build Order instance + */ + public static Order asc(String propertyName) { + return new Order( propertyName, true ); } - - public Order ignoreCase() { - ignoreCase = true; - return this; + + /** + * Descending order. + * + * @param propertyName The property to order on + * + * @return The build Order instance + */ + public static Order desc(String propertyName) { + return new Order( propertyName, false ); } /** - * Constructor for Order. + * Constructor for Order. Order instances are generally created by factory methods. + * + * @see #asc + * @see #desc */ protected Order(String propertyName, boolean ascending) { this.propertyName = propertyName; this.ascending = ascending; } /** - * Render the SQL fragment + * Should this ordering ignore case? Has no effect on non-character properties. * + * @return {@code this}, for method chaining */ - public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) - throws HibernateException { - String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName); - Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName); - StringBuffer fragment = new StringBuffer(); - for ( int i=0; i - *
- * Compatible with Cach� 2007.1. - *
- * - * Caché and Hibernate - * - * - *

Caché and Hibernate

+ * Caché 2007.1 dialect. + * + * This class is required in order to use Hibernate with Intersystems Caché SQL. Compatible with + * Caché 2007.1. + * *

PREREQUISITES

* These setup instructions assume that both Caché and Hibernate are installed and operational. *
@@ -141,11 +140,9 @@ * * *

- *

- *
Note 1
- *
Please contact your administrator for the userid and password you should use when attempting access via JDBC. - * By default, these are chosen to be "_SYSTEM" and "SYS" respectively as noted in the SQL standard.
- *
+ * NOTE: Please contact your administrator for the userid and password you should use when + * attempting access via JDBC. By default, these are chosen to be "_SYSTEM" and "SYS" respectively + * as noted in the SQL standard. *
*

CACHÉ VERSION URL

* This is the standard URL for the JDBC driver. @@ -212,8 +209,8 @@ public class Cache71Dialect extends Dialect { /** - * Creates new Cach�71Dialect instance. Sets up the JDBC / - * Cach� type mappings. + * Creates new Cache71Dialect instance. Sets up the JDBC / + * Caché type mappings. */ public Cache71Dialect() { super(); @@ -236,283 +233,292 @@ registerColumnType( Types.DOUBLE, "double" ); registerColumnType( Types.FLOAT, "float" ); registerColumnType( Types.INTEGER, "integer" ); - registerColumnType( Types.LONGVARBINARY, "longvarbinary" ); // binary %Stream - registerColumnType( Types.LONGVARCHAR, "longvarchar" ); // character %Stream + registerColumnType( Types.LONGVARBINARY, "longvarbinary" ); + registerColumnType( Types.LONGVARCHAR, "longvarchar" ); registerColumnType( Types.NUMERIC, "numeric($p,$s)" ); registerColumnType( Types.REAL, "real" ); registerColumnType( Types.SMALLINT, "smallint" ); registerColumnType( Types.TIMESTAMP, "timestamp" ); registerColumnType( Types.TIME, "time" ); registerColumnType( Types.TINYINT, "tinyint" ); - // TBD should this be varbinary($1)? - // registerColumnType(Types.VARBINARY, "binary($1)"); registerColumnType( Types.VARBINARY, "longvarbinary" ); registerColumnType( Types.VARCHAR, "varchar($l)" ); registerColumnType( Types.BLOB, "longvarbinary" ); registerColumnType( Types.CLOB, "longvarchar" ); getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "false" ); getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE ); - //getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH); getDefaultProperties().setProperty( Environment.USE_SQL_COMMENTS, "false" ); registerFunction( "abs", new StandardSQLFunction( "abs" ) ); - registerFunction( "acos", new StandardJDBCEscapeFunction( "acos", Hibernate.DOUBLE ) ); - registerFunction( "%alphaup", new StandardSQLFunction( "%alphaup", Hibernate.STRING ) ); - registerFunction( "ascii", new StandardSQLFunction( "ascii", Hibernate.STRING ) ); - registerFunction( "asin", new StandardJDBCEscapeFunction( "asin", Hibernate.DOUBLE ) ); - registerFunction( "atan", new StandardJDBCEscapeFunction( "atan", Hibernate.DOUBLE ) ); - registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "($length(?1)*8)" ) ); - // hibernate impelemnts cast in Dialect.java - registerFunction( "ceiling", new StandardSQLFunction( "ceiling", Hibernate.INTEGER ) ); - registerFunction( "char", new StandardJDBCEscapeFunction( "char", Hibernate.CHARACTER ) ); - registerFunction( "character_length", new StandardSQLFunction( "character_length", Hibernate.INTEGER ) ); - registerFunction( "char_length", new StandardSQLFunction( "char_length", Hibernate.INTEGER ) ); - registerFunction( "cos", new StandardJDBCEscapeFunction( "cos", Hibernate.DOUBLE ) ); - registerFunction( "cot", new StandardJDBCEscapeFunction( "cot", Hibernate.DOUBLE ) ); + registerFunction( "acos", new StandardJDBCEscapeFunction( "acos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "%alphaup", new StandardSQLFunction( "%alphaup", StandardBasicTypes.STRING ) ); + registerFunction( "ascii", new StandardSQLFunction( "ascii", StandardBasicTypes.STRING ) ); + registerFunction( "asin", new StandardJDBCEscapeFunction( "asin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "atan", new StandardJDBCEscapeFunction( "atan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "bit_length", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "($length(?1)*8)" ) ); + registerFunction( "ceiling", new StandardSQLFunction( "ceiling", StandardBasicTypes.INTEGER ) ); + registerFunction( "char", new StandardJDBCEscapeFunction( "char", StandardBasicTypes.CHARACTER ) ); + registerFunction( "character_length", new StandardSQLFunction( "character_length", StandardBasicTypes.INTEGER ) ); + registerFunction( "char_length", new StandardSQLFunction( "char_length", StandardBasicTypes.INTEGER ) ); + registerFunction( "cos", new StandardJDBCEscapeFunction( "cos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cot", new StandardJDBCEscapeFunction( "cot", StandardBasicTypes.DOUBLE ) ); registerFunction( "coalesce", new VarArgsSQLFunction( "coalesce(", ",", ")" ) ); - registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "", "||", "" ) ); + registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "", "||", "" ) ); registerFunction( "convert", new ConvertFunction() ); - registerFunction( "curdate", new StandardJDBCEscapeFunction( "curdate", Hibernate.DATE ) ); - registerFunction( "current_date", new NoArgSQLFunction( "current_date", Hibernate.DATE, false ) ); - registerFunction( "current_time", new NoArgSQLFunction( "current_time", Hibernate.TIME, false ) ); + registerFunction( "curdate", new StandardJDBCEscapeFunction( "curdate", StandardBasicTypes.DATE ) ); + registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE, false ) ); + registerFunction( "current_time", new NoArgSQLFunction( "current_time", StandardBasicTypes.TIME, false ) ); registerFunction( - "current_timestamp", new ConditionalParenthesisFunction( "current_timestamp", Hibernate.TIMESTAMP ) + "current_timestamp", new ConditionalParenthesisFunction( "current_timestamp", StandardBasicTypes.TIMESTAMP ) ); - registerFunction( "curtime", new StandardJDBCEscapeFunction( "curtime", Hibernate.TIME ) ); - registerFunction( "database", new StandardJDBCEscapeFunction( "database", Hibernate.STRING ) ); - registerFunction( "dateadd", new VarArgsSQLFunction( Hibernate.TIMESTAMP, "dateadd(", ",", ")" ) ); - registerFunction( "datediff", new VarArgsSQLFunction( Hibernate.INTEGER, "datediff(", ",", ")" ) ); - registerFunction( "datename", new VarArgsSQLFunction( Hibernate.STRING, "datename(", ",", ")" ) ); - registerFunction( "datepart", new VarArgsSQLFunction( Hibernate.INTEGER, "datepart(", ",", ")" ) ); - registerFunction( "day", new StandardSQLFunction( "day", Hibernate.INTEGER ) ); - registerFunction( "dayname", new StandardJDBCEscapeFunction( "dayname", Hibernate.STRING ) ); - registerFunction( "dayofmonth", new StandardJDBCEscapeFunction( "dayofmonth", Hibernate.INTEGER ) ); - registerFunction( "dayofweek", new StandardJDBCEscapeFunction( "dayofweek", Hibernate.INTEGER ) ); - registerFunction( "dayofyear", new StandardJDBCEscapeFunction( "dayofyear", Hibernate.INTEGER ) ); + registerFunction( "curtime", new StandardJDBCEscapeFunction( "curtime", StandardBasicTypes.TIME ) ); + registerFunction( "database", new StandardJDBCEscapeFunction( "database", StandardBasicTypes.STRING ) ); + registerFunction( "dateadd", new VarArgsSQLFunction( StandardBasicTypes.TIMESTAMP, "dateadd(", ",", ")" ) ); + registerFunction( "datediff", new VarArgsSQLFunction( StandardBasicTypes.INTEGER, "datediff(", ",", ")" ) ); + registerFunction( "datename", new VarArgsSQLFunction( StandardBasicTypes.STRING, "datename(", ",", ")" ) ); + registerFunction( "datepart", new VarArgsSQLFunction( StandardBasicTypes.INTEGER, "datepart(", ",", ")" ) ); + registerFunction( "day", new StandardSQLFunction( "day", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayname", new StandardJDBCEscapeFunction( "dayname", StandardBasicTypes.STRING ) ); + registerFunction( "dayofmonth", new StandardJDBCEscapeFunction( "dayofmonth", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofweek", new StandardJDBCEscapeFunction( "dayofweek", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofyear", new StandardJDBCEscapeFunction( "dayofyear", StandardBasicTypes.INTEGER ) ); // is it necessary to register %exact since it can only appear in a where clause? - registerFunction( "%exact", new StandardSQLFunction( "%exact", Hibernate.STRING ) ); - registerFunction( "exp", new StandardJDBCEscapeFunction( "exp", Hibernate.DOUBLE ) ); - registerFunction( "%external", new StandardSQLFunction( "%external", Hibernate.STRING ) ); - registerFunction( "$extract", new VarArgsSQLFunction( Hibernate.INTEGER, "$extract(", ",", ")" ) ); - registerFunction( "$find", new VarArgsSQLFunction( Hibernate.INTEGER, "$find(", ",", ")" ) ); - registerFunction( "floor", new StandardSQLFunction( "floor", Hibernate.INTEGER ) ); - registerFunction( "getdate", new StandardSQLFunction( "getdate", Hibernate.TIMESTAMP ) ); - registerFunction( "hour", new StandardJDBCEscapeFunction( "hour", Hibernate.INTEGER ) ); + registerFunction( "%exact", new StandardSQLFunction( "%exact", StandardBasicTypes.STRING ) ); + registerFunction( "exp", new StandardJDBCEscapeFunction( "exp", StandardBasicTypes.DOUBLE ) ); + registerFunction( "%external", new StandardSQLFunction( "%external", StandardBasicTypes.STRING ) ); + registerFunction( "$extract", new VarArgsSQLFunction( StandardBasicTypes.INTEGER, "$extract(", ",", ")" ) ); + registerFunction( "$find", new VarArgsSQLFunction( StandardBasicTypes.INTEGER, "$find(", ",", ")" ) ); + registerFunction( "floor", new StandardSQLFunction( "floor", StandardBasicTypes.INTEGER ) ); + registerFunction( "getdate", new StandardSQLFunction( "getdate", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "hour", new StandardJDBCEscapeFunction( "hour", StandardBasicTypes.INTEGER ) ); registerFunction( "ifnull", new VarArgsSQLFunction( "ifnull(", ",", ")" ) ); registerFunction( "%internal", new StandardSQLFunction( "%internal" ) ); registerFunction( "isnull", new VarArgsSQLFunction( "isnull(", ",", ")" ) ); - registerFunction( "isnumeric", new StandardSQLFunction( "isnumeric", Hibernate.INTEGER ) ); - registerFunction( "lcase", new StandardJDBCEscapeFunction( "lcase", Hibernate.STRING ) ); - registerFunction( "left", new StandardJDBCEscapeFunction( "left", Hibernate.STRING ) ); - registerFunction( "len", new StandardSQLFunction( "len", Hibernate.INTEGER ) ); - registerFunction( "length", new StandardSQLFunction( "length", Hibernate.INTEGER ) ); + registerFunction( "isnumeric", new StandardSQLFunction( "isnumeric", StandardBasicTypes.INTEGER ) ); + registerFunction( "lcase", new StandardJDBCEscapeFunction( "lcase", StandardBasicTypes.STRING ) ); + registerFunction( "left", new StandardJDBCEscapeFunction( "left", StandardBasicTypes.STRING ) ); + registerFunction( "len", new StandardSQLFunction( "len", StandardBasicTypes.INTEGER ) ); registerFunction( "$length", new VarArgsSQLFunction( "$length(", ",", ")" ) ); - // aggregate functions shouldn't be registered, right? - //registerFunction( "list", new StandardSQLFunction("list",Hibernate.STRING) ); - // stopped on $list registerFunction( "$list", new VarArgsSQLFunction( "$list(", ",", ")" ) ); registerFunction( "$listdata", new VarArgsSQLFunction( "$listdata(", ",", ")" ) ); registerFunction( "$listfind", new VarArgsSQLFunction( "$listfind(", ",", ")" ) ); registerFunction( "$listget", new VarArgsSQLFunction( "$listget(", ",", ")" ) ); - registerFunction( "$listlength", new StandardSQLFunction( "$listlength", Hibernate.INTEGER ) ); - registerFunction( "locate", new StandardSQLFunction( "$FIND", Hibernate.INTEGER ) ); - registerFunction( "log", new StandardJDBCEscapeFunction( "log", Hibernate.DOUBLE ) ); - registerFunction( "log10", new StandardJDBCEscapeFunction( "log", Hibernate.DOUBLE ) ); + registerFunction( "$listlength", new StandardSQLFunction( "$listlength", StandardBasicTypes.INTEGER ) ); + registerFunction( "locate", new StandardSQLFunction( "$FIND", StandardBasicTypes.INTEGER ) ); + registerFunction( "log", new StandardJDBCEscapeFunction( "log", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log10", new StandardJDBCEscapeFunction( "log", StandardBasicTypes.DOUBLE ) ); registerFunction( "lower", new StandardSQLFunction( "lower" ) ); registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) ); - registerFunction( "minute", new StandardJDBCEscapeFunction( "minute", Hibernate.INTEGER ) ); - registerFunction( "mod", new StandardJDBCEscapeFunction( "mod", Hibernate.DOUBLE ) ); - registerFunction( "month", new StandardJDBCEscapeFunction( "month", Hibernate.INTEGER ) ); - registerFunction( "monthname", new StandardJDBCEscapeFunction( "monthname", Hibernate.STRING ) ); - registerFunction( "now", new StandardJDBCEscapeFunction( "monthname", Hibernate.TIMESTAMP ) ); + registerFunction( "minute", new StandardJDBCEscapeFunction( "minute", StandardBasicTypes.INTEGER ) ); + registerFunction( "mod", new StandardJDBCEscapeFunction( "mod", StandardBasicTypes.DOUBLE ) ); + registerFunction( "month", new StandardJDBCEscapeFunction( "month", StandardBasicTypes.INTEGER ) ); + registerFunction( "monthname", new StandardJDBCEscapeFunction( "monthname", StandardBasicTypes.STRING ) ); + registerFunction( "now", new StandardJDBCEscapeFunction( "monthname", StandardBasicTypes.TIMESTAMP ) ); registerFunction( "nullif", new VarArgsSQLFunction( "nullif(", ",", ")" ) ); registerFunction( "nvl", new NvlFunction() ); registerFunction( "%odbcin", new StandardSQLFunction( "%odbcin" ) ); registerFunction( "%odbcout", new StandardSQLFunction( "%odbcin" ) ); - registerFunction( "%pattern", new VarArgsSQLFunction( Hibernate.STRING, "", "%pattern", "" ) ); - registerFunction( "pi", new StandardJDBCEscapeFunction( "pi", Hibernate.DOUBLE ) ); - registerFunction( "$piece", new VarArgsSQLFunction( Hibernate.STRING, "$piece(", ",", ")" ) ); - registerFunction( "position", new VarArgsSQLFunction( Hibernate.INTEGER, "position(", " in ", ")" ) ); - registerFunction( "power", new VarArgsSQLFunction( Hibernate.STRING, "power(", ",", ")" ) ); - registerFunction( "quarter", new StandardJDBCEscapeFunction( "quarter", Hibernate.INTEGER ) ); - registerFunction( "repeat", new VarArgsSQLFunction( Hibernate.STRING, "repeat(", ",", ")" ) ); - registerFunction( "replicate", new VarArgsSQLFunction( Hibernate.STRING, "replicate(", ",", ")" ) ); - registerFunction( "right", new StandardJDBCEscapeFunction( "right", Hibernate.STRING ) ); - registerFunction( "round", new VarArgsSQLFunction( Hibernate.FLOAT, "round(", ",", ")" ) ); - registerFunction( "rtrim", new StandardSQLFunction( "rtrim", Hibernate.STRING ) ); - registerFunction( "second", new StandardJDBCEscapeFunction( "second", Hibernate.INTEGER ) ); - registerFunction( "sign", new StandardSQLFunction( "sign", Hibernate.INTEGER ) ); - registerFunction( "sin", new StandardJDBCEscapeFunction( "sin", Hibernate.DOUBLE ) ); - registerFunction( "space", new StandardSQLFunction( "space", Hibernate.STRING ) ); - registerFunction( "%sqlstring", new VarArgsSQLFunction( Hibernate.STRING, "%sqlstring(", ",", ")" ) ); - registerFunction( "%sqlupper", new VarArgsSQLFunction( Hibernate.STRING, "%sqlupper(", ",", ")" ) ); - registerFunction( "sqrt", new StandardJDBCEscapeFunction( "SQRT", Hibernate.DOUBLE ) ); - registerFunction( "%startswith", new VarArgsSQLFunction( Hibernate.STRING, "", "%startswith", "" ) ); + registerFunction( "%pattern", new VarArgsSQLFunction( StandardBasicTypes.STRING, "", "%pattern", "" ) ); + registerFunction( "pi", new StandardJDBCEscapeFunction( "pi", StandardBasicTypes.DOUBLE ) ); + registerFunction( "$piece", new VarArgsSQLFunction( StandardBasicTypes.STRING, "$piece(", ",", ")" ) ); + registerFunction( "position", new VarArgsSQLFunction( StandardBasicTypes.INTEGER, "position(", " in ", ")" ) ); + registerFunction( "power", new VarArgsSQLFunction( StandardBasicTypes.STRING, "power(", ",", ")" ) ); + registerFunction( "quarter", new StandardJDBCEscapeFunction( "quarter", StandardBasicTypes.INTEGER ) ); + registerFunction( "repeat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "repeat(", ",", ")" ) ); + registerFunction( "replicate", new VarArgsSQLFunction( StandardBasicTypes.STRING, "replicate(", ",", ")" ) ); + registerFunction( "right", new StandardJDBCEscapeFunction( "right", StandardBasicTypes.STRING ) ); + registerFunction( "round", new VarArgsSQLFunction( StandardBasicTypes.FLOAT, "round(", ",", ")" ) ); + registerFunction( "rtrim", new StandardSQLFunction( "rtrim", StandardBasicTypes.STRING ) ); + registerFunction( "second", new StandardJDBCEscapeFunction( "second", StandardBasicTypes.INTEGER ) ); + registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) ); + registerFunction( "sin", new StandardJDBCEscapeFunction( "sin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "space", new StandardSQLFunction( "space", StandardBasicTypes.STRING ) ); + registerFunction( "%sqlstring", new VarArgsSQLFunction( StandardBasicTypes.STRING, "%sqlstring(", ",", ")" ) ); + registerFunction( "%sqlupper", new VarArgsSQLFunction( StandardBasicTypes.STRING, "%sqlupper(", ",", ")" ) ); + registerFunction( "sqrt", new StandardJDBCEscapeFunction( "SQRT", StandardBasicTypes.DOUBLE ) ); + registerFunction( "%startswith", new VarArgsSQLFunction( StandardBasicTypes.STRING, "", "%startswith", "" ) ); // below is for Cache' that don't have str in 2007.1 there is str and we register str directly - registerFunction( "str", new SQLFunctionTemplate( Hibernate.STRING, "cast(?1 as char varying)" ) ); - registerFunction( "string", new VarArgsSQLFunction( Hibernate.STRING, "string(", ",", ")" ) ); + registerFunction( "str", new SQLFunctionTemplate( StandardBasicTypes.STRING, "cast(?1 as char varying)" ) ); + registerFunction( "string", new VarArgsSQLFunction( StandardBasicTypes.STRING, "string(", ",", ")" ) ); // note that %string is deprecated - registerFunction( "%string", new VarArgsSQLFunction( Hibernate.STRING, "%string(", ",", ")" ) ); - registerFunction( "substr", new VarArgsSQLFunction( Hibernate.STRING, "substr(", ",", ")" ) ); - registerFunction( "substring", new VarArgsSQLFunction( Hibernate.STRING, "substring(", ",", ")" ) ); - registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", Hibernate.TIMESTAMP, false ) ); - registerFunction( "tan", new StandardJDBCEscapeFunction( "tan", Hibernate.DOUBLE ) ); - registerFunction( "timestampadd", new StandardJDBCEscapeFunction( "timestampadd", Hibernate.DOUBLE ) ); - registerFunction( "timestampdiff", new StandardJDBCEscapeFunction( "timestampdiff", Hibernate.DOUBLE ) ); - registerFunction( "tochar", new VarArgsSQLFunction( Hibernate.STRING, "tochar(", ",", ")" ) ); - registerFunction( "to_char", new VarArgsSQLFunction( Hibernate.STRING, "to_char(", ",", ")" ) ); - registerFunction( "todate", new VarArgsSQLFunction( Hibernate.STRING, "todate(", ",", ")" ) ); - registerFunction( "to_date", new VarArgsSQLFunction( Hibernate.STRING, "todate(", ",", ")" ) ); + registerFunction( "%string", new VarArgsSQLFunction( StandardBasicTypes.STRING, "%string(", ",", ")" ) ); + registerFunction( "substr", new VarArgsSQLFunction( StandardBasicTypes.STRING, "substr(", ",", ")" ) ); + registerFunction( "substring", new VarArgsSQLFunction( StandardBasicTypes.STRING, "substring(", ",", ")" ) ); + registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.TIMESTAMP, false ) ); + registerFunction( "tan", new StandardJDBCEscapeFunction( "tan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "timestampadd", new StandardJDBCEscapeFunction( "timestampadd", StandardBasicTypes.DOUBLE ) ); + registerFunction( "timestampdiff", new StandardJDBCEscapeFunction( "timestampdiff", StandardBasicTypes.DOUBLE ) ); + registerFunction( "tochar", new VarArgsSQLFunction( StandardBasicTypes.STRING, "tochar(", ",", ")" ) ); + registerFunction( "to_char", new VarArgsSQLFunction( StandardBasicTypes.STRING, "to_char(", ",", ")" ) ); + registerFunction( "todate", new VarArgsSQLFunction( StandardBasicTypes.STRING, "todate(", ",", ")" ) ); + registerFunction( "to_date", new VarArgsSQLFunction( StandardBasicTypes.STRING, "todate(", ",", ")" ) ); registerFunction( "tonumber", new StandardSQLFunction( "tonumber" ) ); registerFunction( "to_number", new StandardSQLFunction( "tonumber" ) ); // TRIM(end_keyword string-expression-1 FROM string-expression-2) // use Hibernate implementation "From" is one of the parameters they pass in position ?3 - //registerFunction( "trim", new SQLFunctionTemplate(Hibernate.STRING, "trim(?1 ?2 from ?3)") ); - registerFunction( "truncate", new StandardJDBCEscapeFunction( "truncate", Hibernate.STRING ) ); - registerFunction( "ucase", new StandardJDBCEscapeFunction( "ucase", Hibernate.STRING ) ); + //registerFunction( "trim", new SQLFunctionTemplate(StandardBasicTypes.STRING, "trim(?1 ?2 from ?3)") ); + registerFunction( "truncate", new StandardJDBCEscapeFunction( "truncate", StandardBasicTypes.STRING ) ); + registerFunction( "ucase", new StandardJDBCEscapeFunction( "ucase", StandardBasicTypes.STRING ) ); registerFunction( "upper", new StandardSQLFunction( "upper" ) ); // %upper is deprecated registerFunction( "%upper", new StandardSQLFunction( "%upper" ) ); - registerFunction( "user", new StandardJDBCEscapeFunction( "user", Hibernate.STRING ) ); - registerFunction( "week", new StandardJDBCEscapeFunction( "user", Hibernate.INTEGER ) ); - registerFunction( "xmlconcat", new VarArgsSQLFunction( Hibernate.STRING, "xmlconcat(", ",", ")" ) ); - registerFunction( "xmlelement", new VarArgsSQLFunction( Hibernate.STRING, "xmlelement(", ",", ")" ) ); + registerFunction( "user", new StandardJDBCEscapeFunction( "user", StandardBasicTypes.STRING ) ); + registerFunction( "week", new StandardJDBCEscapeFunction( "user", StandardBasicTypes.INTEGER ) ); + registerFunction( "xmlconcat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "xmlconcat(", ",", ")" ) ); + registerFunction( "xmlelement", new VarArgsSQLFunction( StandardBasicTypes.STRING, "xmlelement(", ",", ")" ) ); // xmlforest requires a new kind of function constructor - registerFunction( "year", new StandardJDBCEscapeFunction( "year", Hibernate.INTEGER ) ); + registerFunction( "year", new StandardJDBCEscapeFunction( "year", StandardBasicTypes.INTEGER ) ); } protected final void register71Functions() { - this.registerFunction( "str", new VarArgsSQLFunction( Hibernate.STRING, "str(", ",", ")" ) ); + this.registerFunction( "str", new VarArgsSQLFunction( StandardBasicTypes.STRING, "str(", ",", ")" ) ); } // DDL support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public boolean hasAlterTable() { // Does this dialect support the ALTER TABLE syntax? return true; } + @Override public boolean qualifyIndexName() { // Do we need to qualify index names with the schema name? return false; } - public boolean supportsUnique() { - // Does this dialect support the UNIQUE column syntax? - return true; - } - - /** - * The syntax used to add a foreign key constraint to a table. - * - * @return String - */ + @Override + @SuppressWarnings("StringBufferReplaceableByString") public String getAddForeignKeyConstraintString( String constraintName, String[] foreignKey, String referencedTable, String[] primaryKey, boolean referencesPrimaryKey) { // The syntax used to add a foreign key constraint to a table. - return new StringBuffer( 300 ) + return new StringBuilder( 300 ) .append( " ADD CONSTRAINT " ) .append( constraintName ) .append( " FOREIGN KEY " ) .append( constraintName ) .append( " (" ) - .append( StringHelper.join( ", ", foreignKey ) ) // identifier-commalist + .append( StringHelper.join( ", ", foreignKey ) ) .append( ") REFERENCES " ) .append( referencedTable ) .append( " (" ) - .append( StringHelper.join( ", ", primaryKey ) ) // identifier-commalist + .append( StringHelper.join( ", ", primaryKey ) ) .append( ") " ) .toString(); } + /** + * Does this dialect support check constraints? + * + * @return {@code false} (Cache does not support check constraints) + */ + @SuppressWarnings("UnusedDeclaration") public boolean supportsCheck() { - // Does this dialect support check constraints? return false; } + @Override public String getAddColumnString() { // The syntax used to add a column to a table return " add column"; } + @Override public String getCascadeConstraintsString() { // Completely optional cascading drop clause. return ""; } + @Override public boolean dropConstraints() { // Do we need to drop constraints before dropping tables in this dialect? return true; } + @Override public boolean supportsCascadeDelete() { return true; } + @Override public boolean hasSelfReferentialForeignKeyBug() { return true; } + // temporary table support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public boolean supportsTemporaryTables() { return true; } + @Override public String generateTemporaryTableName(String baseTableName) { - String name = super.generateTemporaryTableName( baseTableName ); + final String name = super.generateTemporaryTableName( baseTableName ); return name.length() > 25 ? name.substring( 1, 25 ) : name; } + @Override public String getCreateTemporaryTableString() { return "create global temporary table"; } + @Override public Boolean performTemporaryTableDDLInIsolation() { return Boolean.FALSE; } + @Override public String getCreateTemporaryTablePostfix() { return ""; } + @Override public boolean dropTemporaryTableAfterUse() { return true; } // IDENTITY support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public boolean supportsIdentityColumns() { return true; } + @Override public Class getNativeIdentifierGeneratorClass() { return IdentityGenerator.class; } + @Override public boolean hasDataTypeInIdentityColumn() { // Whether this dialect has an Identity clause added to the data type or a completely seperate identity // data type return true; } + @Override public String getIdentityColumnString() throws MappingException { // The keyword used to specify an identity column, if identity column key generation is supported. return "identity"; } + @Override public String getIdentitySelectString() { return "SELECT LAST_IDENTITY() FROM %TSQL_sys.snf"; } // SEQUENCE support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public boolean supportsSequences() { return false; } @@ -542,29 +548,31 @@ // lock acquisition support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - public boolean supportsForUpdate() { - // Does this dialect support the FOR UPDATE syntax? - return false; - } - - public boolean supportsForUpdateOf() { - // Does this dialect support FOR UPDATE OF, allowing particular rows to be locked? - return false; - } - - public boolean supportsForUpdateNowait() { - // Does this dialect support the Oracle-style FOR UPDATE NOWAIT syntax? - return false; - } - + @Override public boolean supportsOuterJoinForUpdate() { return false; } + @Override public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { // InterSystems Cache' does not current support "SELECT ... FOR UPDATE" syntax... // Set your transaction mode to READ_COMMITTED before using - if ( lockMode.greaterThan( LockMode.READ ) ) { + if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) { + return new PessimisticForceIncrementLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.PESSIMISTIC_WRITE) { + return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.PESSIMISTIC_READ) { + return new PessimisticReadUpdateLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.OPTIMISTIC) { + return new OptimisticLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) { + return new OptimisticForceIncrementLockingStrategy( lockable, lockMode); + } + else if ( lockMode.greaterThan( LockMode.READ ) ) { return new UpdateLockingStrategy( lockable, lockMode ); } else { @@ -574,88 +582,110 @@ // LIMIT support (ala TOP) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override + @SuppressWarnings("deprecation") public boolean supportsLimit() { return true; } + @Override + @SuppressWarnings("deprecation") public boolean supportsLimitOffset() { return false; } + @Override + @SuppressWarnings("deprecation") public boolean supportsVariableLimit() { return true; } + @Override + @SuppressWarnings("deprecation") public boolean bindLimitParametersFirst() { // Does the LIMIT clause come at the start of the SELECT statement, rather than at the end? return true; } + @Override + @SuppressWarnings("deprecation") public boolean useMaxForLimit() { // Does the LIMIT clause take a "maximum" row number instead of a total number of returned rows? return true; } + @Override + @SuppressWarnings("deprecation") public String getLimitString(String sql, boolean hasOffset) { if ( hasOffset ) { - throw new UnsupportedOperationException( "An offset may not be specified to in Cache SQL" ); + throw new UnsupportedOperationException( "query result offset is not supported" ); } // This does not support the Cache SQL 'DISTINCT BY (comma-list)' extensions, // but this extension is not supported through Hibernate anyway. - int insertionPoint = sql.startsWith( "select distinct" ) ? 15 : 6; + final int insertionPoint = sql.startsWith( "select distinct" ) ? 15 : 6; - return new StringBuffer( sql.length() + 8 ) + return new StringBuilder( sql.length() + 8 ) .append( sql ) .insert( insertionPoint, " TOP ? " ) .toString(); } // callable statement support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException { return col; } + @Override public ResultSet getResultSet(CallableStatement ps) throws SQLException { ps.execute(); - return ( ResultSet ) ps.getObject( 1 ); + return (ResultSet) ps.getObject( 1 ); } // miscellaneous support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public String getLowercaseFunction() { // The name of the SQL function that transforms a string to lowercase return "lower"; } + @Override public String getNullColumnString() { // The keyword used to specify a nullable column. return " null"; } + @Override public JoinFragment createOuterJoinFragment() { // Create an OuterJoinGenerator for this dialect. return new CacheJoinFragment(); } + @Override public String getNoColumnsInsertString() { // The keyword used to insert a row without specifying // any column values return " default values"; } - public SQLExceptionConverter buildSQLExceptionConverter() { - return new CacheSQLStateConverter( EXTRACTER ); + @Override + public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() { + return new CacheSQLExceptionConversionDelegate( this ); } + @Override + public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() { + return EXTRACTER; + } + + /** + * The Cache ViolatedConstraintNameExtracter. + */ public static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { - /** - * Extract the name of the violated constraint from the given SQLException. - * - * @param sqle The exception that was the result of the constraint violation. - * @return The extracted constraint name. - */ + @Override public String extractConstraintName(SQLException sqle) { return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() ); } @@ -664,14 +694,17 @@ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public boolean supportsEmptyInList() { return false; } + @Override public boolean areStringComparisonsCaseInsensitive() { return true; } + @Override public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() { return false; } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/ColumnAliasExtractor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/DB2390Dialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/DB2390Dialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/DB2390Dialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/DB2390Dialect.java 30 Jul 2014 16:15:52 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,49 +20,57 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; + /** * An SQL dialect for DB2/390. This class provides support for * DB2 Universal Database for OS/390, also known as DB2/390. * * @author Kristoffer Dyrkorn */ public class DB2390Dialect extends DB2Dialect { - + @Override public boolean supportsSequences() { return false; } + @Override public String getIdentitySelectString() { return "select identity_val_local() from sysibm.sysdummy1"; } + @Override public boolean supportsLimit() { return true; } + @Override + @SuppressWarnings("deprecation") public boolean supportsLimitOffset() { return false; } - public String getLimitString(String sql, int offset, int limit) { - return new StringBuffer(sql.length() + 40) - .append(sql) - .append(" fetch first ") - .append(limit) - .append(" rows only ") - .toString(); - } - + @Override public boolean useMaxForLimit() { return true; } + @Override public boolean supportsVariableLimit() { return false; } -} \ No newline at end of file + @Override + public String getLimitString(String sql, int offset, int limit) { + if ( offset > 0 ) { + throw new UnsupportedOperationException( "query result offset is not supported" ); + } + if ( limit == 0 ) { + return sql; + } + return sql + " fetch first " + limit + " rows only "; + } + +} Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/DB2400Dialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/DB2400Dialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/DB2400Dialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/DB2400Dialect.java 30 Jul 2014 16:15:51 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,49 +20,60 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; /** -* An SQL dialect for DB2/400 -* @author Peter DeGregorio (pdegregorio) -* This class provides support for DB2 Universal Database for iSeries, -* also known as DB2/400. -*/ + * An SQL dialect for DB2/400. This class provides support for DB2 Universal Database for iSeries, + * also known as DB2/400. + * + * @author Peter DeGregorio (pdegregorio) + */ public class DB2400Dialect extends DB2Dialect { - + @Override public boolean supportsSequences() { return false; } + @Override public String getIdentitySelectString() { return "select identity_val_local() from sysibm.sysdummy1"; } + @Override public boolean supportsLimit() { return true; } + @Override + @SuppressWarnings("deprecation") public boolean supportsLimitOffset() { return false; } - public String getLimitString(String sql, int offset, int limit) { - return new StringBuffer(sql.length() + 40) - .append(sql) - .append(" fetch first ") - .append(limit) - .append(" rows only ") - .toString(); - } - + @Override public boolean useMaxForLimit() { return true; } + @Override public boolean supportsVariableLimit() { return false; } -} \ No newline at end of file + @Override + public String getLimitString(String sql, int offset, int limit) { + if ( offset > 0 ) { + throw new UnsupportedOperationException( "query result offset is not supported" ); + } + if ( limit == 0 ) { + return sql; + } + return sql + " fetch first " + limit + " rows only "; + } + + @Override + public String getForUpdateString() { + return " for update with rs"; + } +} Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/DB2Dialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/DB2Dialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/DB2Dialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/DB2Dialect.java 30 Jul 2014 16:15:52 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; @@ -29,20 +28,33 @@ import java.sql.SQLException; import java.sql.Types; -import org.hibernate.Hibernate; +import org.hibernate.JDBCException; import org.hibernate.cfg.Environment; +import org.hibernate.dialect.function.AvgWithArgumentCastFunction; import org.hibernate.dialect.function.NoArgSQLFunction; import org.hibernate.dialect.function.SQLFunctionTemplate; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.VarArgsSQLFunction; -import org.hibernate.dialect.function.AnsiTrimEmulationFunction; +import org.hibernate.dialect.unique.DB2UniqueDelegate; +import org.hibernate.dialect.unique.UniqueDelegate; +import org.hibernate.exception.LockTimeoutException; +import org.hibernate.exception.spi.SQLExceptionConversionDelegate; +import org.hibernate.internal.util.JdbcExceptionHelper; +import org.hibernate.type.StandardBasicTypes; +import org.hibernate.type.descriptor.sql.SmallIntTypeDescriptor; +import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; /** * An SQL dialect for DB2. + * * @author Gavin King */ public class DB2Dialect extends Dialect { + private final UniqueDelegate uniqueDelegate; + /** + * Constructs a DB2Dialect + */ public DB2Dialect() { super(); registerColumnType( Types.BIT, "smallint" ); @@ -61,241 +73,251 @@ registerColumnType( Types.NUMERIC, "numeric($p,$s)" ); registerColumnType( Types.BLOB, "blob($l)" ); registerColumnType( Types.CLOB, "clob($l)" ); + registerColumnType( Types.LONGVARCHAR, "long varchar" ); + registerColumnType( Types.LONGVARBINARY, "long varchar for bit data" ); + registerColumnType( Types.BINARY, "varchar($l) for bit data" ); + registerColumnType( Types.BINARY, 254, "char($l) for bit data" ); + registerColumnType( Types.BOOLEAN, "smallint" ); - registerFunction("abs", new StandardSQLFunction("abs") ); - registerFunction("absval", new StandardSQLFunction("absval") ); - registerFunction("sign", new StandardSQLFunction("sign", Hibernate.INTEGER) ); + registerFunction( "avg", new AvgWithArgumentCastFunction( "double" ) ); - registerFunction("ceiling", new StandardSQLFunction("ceiling") ); - registerFunction("ceil", new StandardSQLFunction("ceil") ); - registerFunction("floor", new StandardSQLFunction("floor") ); - registerFunction("round", new StandardSQLFunction("round") ); + registerFunction( "abs", new StandardSQLFunction( "abs" ) ); + registerFunction( "absval", new StandardSQLFunction( "absval" ) ); + registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) ); - registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) ); - registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) ); - registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) ); - registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) ); - registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) ); - registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) ); - registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) ); - registerFunction("float", new StandardSQLFunction("float", Hibernate.DOUBLE) ); - registerFunction("hex", new StandardSQLFunction("hex", Hibernate.STRING) ); - registerFunction("ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) ); - registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE) ); - registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) ); - registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) ); - registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE) ); - registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) ); - registerFunction("soundex", new StandardSQLFunction("soundex", Hibernate.STRING) ); - registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) ); - registerFunction("stddev", new StandardSQLFunction("stddev", Hibernate.DOUBLE) ); - registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) ); - registerFunction("variance", new StandardSQLFunction("variance", Hibernate.DOUBLE) ); + registerFunction( "ceiling", new StandardSQLFunction( "ceiling" ) ); + registerFunction( "ceil", new StandardSQLFunction( "ceil" ) ); + registerFunction( "floor", new StandardSQLFunction( "floor" ) ); + registerFunction( "round", new StandardSQLFunction( "round" ) ); - registerFunction("julian_day", new StandardSQLFunction("julian_day", Hibernate.INTEGER) ); - registerFunction("microsecond", new StandardSQLFunction("microsecond", Hibernate.INTEGER) ); - registerFunction("midnight_seconds", new StandardSQLFunction("midnight_seconds", Hibernate.INTEGER) ); - registerFunction("minute", new StandardSQLFunction("minute", Hibernate.INTEGER) ); - registerFunction("month", new StandardSQLFunction("month", Hibernate.INTEGER) ); - registerFunction("monthname", new StandardSQLFunction("monthname", Hibernate.STRING) ); - registerFunction("quarter", new StandardSQLFunction("quarter", Hibernate.INTEGER) ); - registerFunction("hour", new StandardSQLFunction("hour", Hibernate.INTEGER) ); - registerFunction("second", new StandardSQLFunction("second", Hibernate.INTEGER) ); - registerFunction("current_date", new NoArgSQLFunction("current date", Hibernate.DATE, false) ); - registerFunction("date", new StandardSQLFunction("date", Hibernate.DATE) ); - registerFunction("day", new StandardSQLFunction("day", Hibernate.INTEGER) ); - registerFunction("dayname", new StandardSQLFunction("dayname", Hibernate.STRING) ); - registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER) ); - registerFunction("dayofweek_iso", new StandardSQLFunction("dayofweek_iso", Hibernate.INTEGER) ); - registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER) ); - registerFunction("days", new StandardSQLFunction("days", Hibernate.LONG) ); - registerFunction("current_time", new NoArgSQLFunction("current time", Hibernate.TIME, false) ); - registerFunction("time", new StandardSQLFunction("time", Hibernate.TIME) ); - registerFunction("current_timestamp", new NoArgSQLFunction("current timestamp", Hibernate.TIMESTAMP, false) ); - registerFunction("timestamp", new StandardSQLFunction("timestamp", Hibernate.TIMESTAMP) ); - registerFunction("timestamp_iso", new StandardSQLFunction("timestamp_iso", Hibernate.TIMESTAMP) ); - registerFunction("week", new StandardSQLFunction("week", Hibernate.INTEGER) ); - registerFunction("week_iso", new StandardSQLFunction("week_iso", Hibernate.INTEGER) ); - registerFunction("year", new StandardSQLFunction("year", Hibernate.INTEGER) ); + registerFunction( "acos", new StandardSQLFunction( "acos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "asin", new StandardSQLFunction( "asin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "atan", new StandardSQLFunction( "atan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cos", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cot", new StandardSQLFunction( "cot", StandardBasicTypes.DOUBLE ) ); + registerFunction( "degrees", new StandardSQLFunction( "degrees", StandardBasicTypes.DOUBLE ) ); + registerFunction( "exp", new StandardSQLFunction( "exp", StandardBasicTypes.DOUBLE ) ); + registerFunction( "float", new StandardSQLFunction( "float", StandardBasicTypes.DOUBLE ) ); + registerFunction( "hex", new StandardSQLFunction( "hex", StandardBasicTypes.STRING ) ); + registerFunction( "ln", new StandardSQLFunction( "ln", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log", new StandardSQLFunction( "log", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log10", new StandardSQLFunction( "log10", StandardBasicTypes.DOUBLE ) ); + registerFunction( "radians", new StandardSQLFunction( "radians", StandardBasicTypes.DOUBLE ) ); + registerFunction( "rand", new NoArgSQLFunction( "rand", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sin", new StandardSQLFunction( "sin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "soundex", new StandardSQLFunction( "soundex", StandardBasicTypes.STRING ) ); + registerFunction( "sqrt", new StandardSQLFunction( "sqrt", StandardBasicTypes.DOUBLE ) ); + registerFunction( "stddev", new StandardSQLFunction( "stddev", StandardBasicTypes.DOUBLE ) ); + registerFunction( "tan", new StandardSQLFunction( "tan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "variance", new StandardSQLFunction( "variance", StandardBasicTypes.DOUBLE ) ); - registerFunction("double", new StandardSQLFunction("double", Hibernate.DOUBLE) ); - registerFunction("varchar", new StandardSQLFunction("varchar", Hibernate.STRING) ); - registerFunction("real", new StandardSQLFunction("real", Hibernate.FLOAT) ); - registerFunction("bigint", new StandardSQLFunction("bigint", Hibernate.LONG) ); - registerFunction("char", new StandardSQLFunction("char", Hibernate.CHARACTER) ); - registerFunction("integer", new StandardSQLFunction("integer", Hibernate.INTEGER) ); - registerFunction("smallint", new StandardSQLFunction("smallint", Hibernate.SHORT) ); + registerFunction( "julian_day", new StandardSQLFunction( "julian_day", StandardBasicTypes.INTEGER ) ); + registerFunction( "microsecond", new StandardSQLFunction( "microsecond", StandardBasicTypes.INTEGER ) ); + registerFunction( + "midnight_seconds", + new StandardSQLFunction( "midnight_seconds", StandardBasicTypes.INTEGER ) + ); + registerFunction( "minute", new StandardSQLFunction( "minute", StandardBasicTypes.INTEGER ) ); + registerFunction( "month", new StandardSQLFunction( "month", StandardBasicTypes.INTEGER ) ); + registerFunction( "monthname", new StandardSQLFunction( "monthname", StandardBasicTypes.STRING ) ); + registerFunction( "quarter", new StandardSQLFunction( "quarter", StandardBasicTypes.INTEGER ) ); + registerFunction( "hour", new StandardSQLFunction( "hour", StandardBasicTypes.INTEGER ) ); + registerFunction( "second", new StandardSQLFunction( "second", StandardBasicTypes.INTEGER ) ); + registerFunction( "current_date", new NoArgSQLFunction( "current date", StandardBasicTypes.DATE, false ) ); + registerFunction( "date", new StandardSQLFunction( "date", StandardBasicTypes.DATE ) ); + registerFunction( "day", new StandardSQLFunction( "day", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayname", new StandardSQLFunction( "dayname", StandardBasicTypes.STRING ) ); + registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofweek_iso", new StandardSQLFunction( "dayofweek_iso", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", StandardBasicTypes.INTEGER ) ); + registerFunction( "days", new StandardSQLFunction( "days", StandardBasicTypes.LONG ) ); + registerFunction( "current_time", new NoArgSQLFunction( "current time", StandardBasicTypes.TIME, false ) ); + registerFunction( "time", new StandardSQLFunction( "time", StandardBasicTypes.TIME ) ); + registerFunction( + "current_timestamp", + new NoArgSQLFunction( "current timestamp", StandardBasicTypes.TIMESTAMP, false ) + ); + registerFunction( "timestamp", new StandardSQLFunction( "timestamp", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "timestamp_iso", new StandardSQLFunction( "timestamp_iso", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "week", new StandardSQLFunction( "week", StandardBasicTypes.INTEGER ) ); + registerFunction( "week_iso", new StandardSQLFunction( "week_iso", StandardBasicTypes.INTEGER ) ); + registerFunction( "year", new StandardSQLFunction( "year", StandardBasicTypes.INTEGER ) ); - registerFunction("digits", new StandardSQLFunction("digits", Hibernate.STRING) ); - registerFunction("chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) ); - registerFunction("upper", new StandardSQLFunction("upper") ); - registerFunction("lower", new StandardSQLFunction("lower") ); - registerFunction("ucase", new StandardSQLFunction("ucase") ); - registerFunction("lcase", new StandardSQLFunction("lcase") ); - registerFunction("length", new StandardSQLFunction("length", Hibernate.LONG) ); - registerFunction("ltrim", new StandardSQLFunction("ltrim") ); - registerFunction("rtrim", new StandardSQLFunction("rtrim") ); - registerFunction( "substr", new StandardSQLFunction( "substr", Hibernate.STRING ) ); - registerFunction( "posstr", new StandardSQLFunction( "posstr", Hibernate.INTEGER ) ); + registerFunction( "double", new StandardSQLFunction( "double", StandardBasicTypes.DOUBLE ) ); + registerFunction( "varchar", new StandardSQLFunction( "varchar", StandardBasicTypes.STRING ) ); + registerFunction( "real", new StandardSQLFunction( "real", StandardBasicTypes.FLOAT ) ); + registerFunction( "bigint", new StandardSQLFunction( "bigint", StandardBasicTypes.LONG ) ); + registerFunction( "char", new StandardSQLFunction( "char", StandardBasicTypes.CHARACTER ) ); + registerFunction( "integer", new StandardSQLFunction( "integer", StandardBasicTypes.INTEGER ) ); + registerFunction( "smallint", new StandardSQLFunction( "smallint", StandardBasicTypes.SHORT ) ); - registerFunction( "substring", new StandardSQLFunction( "substr", Hibernate.STRING ) ); - registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "length(?1)*8" ) ); - registerFunction( "trim", new AnsiTrimEmulationFunction() ); + registerFunction( "digits", new StandardSQLFunction( "digits", StandardBasicTypes.STRING ) ); + registerFunction( "chr", new StandardSQLFunction( "chr", StandardBasicTypes.CHARACTER ) ); + registerFunction( "upper", new StandardSQLFunction( "upper" ) ); + registerFunction( "lower", new StandardSQLFunction( "lower" ) ); + registerFunction( "ucase", new StandardSQLFunction( "ucase" ) ); + registerFunction( "lcase", new StandardSQLFunction( "lcase" ) ); + registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) ); + registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) ); + registerFunction( "substr", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) ); + registerFunction( "posstr", new StandardSQLFunction( "posstr", StandardBasicTypes.INTEGER ) ); - registerFunction( "concat", new VarArgsSQLFunction(Hibernate.STRING, "", "||", "") ); + registerFunction( "substring", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) ); + registerFunction( "bit_length", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "length(?1)*8" ) ); + registerFunction( "trim", new SQLFunctionTemplate( StandardBasicTypes.STRING, "trim(?1 ?2 ?3 ?4)" ) ); - registerFunction( "str", new SQLFunctionTemplate( Hibernate.STRING, "rtrim(char(?1))" ) ); + registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "", "||", "" ) ); - registerKeyword("current"); - registerKeyword("date"); - registerKeyword("time"); - registerKeyword("timestamp"); - registerKeyword("fetch"); - registerKeyword("first"); - registerKeyword("rows"); - registerKeyword("only"); + registerFunction( "str", new SQLFunctionTemplate( StandardBasicTypes.STRING, "rtrim(char(?1))" ) ); - getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH); + registerKeyword( "current" ); + registerKeyword( "date" ); + registerKeyword( "time" ); + registerKeyword( "timestamp" ); + registerKeyword( "fetch" ); + registerKeyword( "first" ); + registerKeyword( "rows" ); + registerKeyword( "only" ); + + getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, NO_BATCH ); + + uniqueDelegate = new DB2UniqueDelegate( this ); } + @Override public String getLowercaseFunction() { return "lcase"; } + @Override public String getAddColumnString() { return "add column"; } + + @Override public boolean dropConstraints() { return false; } + + @Override public boolean supportsIdentityColumns() { return true; } + + @Override public String getIdentitySelectString() { return "values identity_val_local()"; } + + @Override public String getIdentityColumnString() { - return "generated by default as identity"; //not null ... (start with 1) is implicit + return "generated by default as identity"; } + + @Override public String getIdentityInsertString() { return "default"; } + @Override public String getSequenceNextValString(String sequenceName) { return "values nextval for " + sequenceName; } + + @Override public String getCreateSequenceString(String sequenceName) { return "create sequence " + sequenceName; } + + @Override public String getDropSequenceString(String sequenceName) { return "drop sequence " + sequenceName + " restrict"; } + @Override public boolean supportsSequences() { return true; } + @Override + public boolean supportsPooledSequences() { + return true; + } + + @Override public String getQuerySequencesString() { return "select seqname from sysibm.syssequences"; } + @Override + @SuppressWarnings("deprecation") public boolean supportsLimit() { return true; } - /*public String getLimitString(String sql, boolean hasOffset) { - StringBuffer rownumber = new StringBuffer(50) - .append(" rownumber() over("); - int orderByIndex = sql.toLowerCase().indexOf("order by"); - if (orderByIndex>0) rownumber.append( sql.substring(orderByIndex) ); - rownumber.append(") as row_,"); - StringBuffer pagingSelect = new StringBuffer( sql.length()+100 ) - .append("select * from ( ") - .append(sql) - .insert( getAfterSelectInsertPoint(sql)+16, rownumber.toString() ) - .append(" ) as temp_ where row_ "); - if (hasOffset) { - pagingSelect.append("between ?+1 and ?"); - } - else { - pagingSelect.append("<= ?"); - } - return pagingSelect.toString(); - }*/ - - /** - * Render the rownumber() over ( .... ) as rownumber_, - * bit, that goes in the select list - */ - private String getRowNumber(String sql) { - StringBuffer rownumber = new StringBuffer(50) - .append("rownumber() over("); - - int orderByIndex = sql.toLowerCase().indexOf("order by"); - - if ( orderByIndex>0 && !hasDistinct(sql) ) { - rownumber.append( sql.substring(orderByIndex) ); - } - - rownumber.append(") as rownumber_,"); - - return rownumber.toString(); + @Override + @SuppressWarnings("deprecation") + public boolean supportsVariableLimit() { + return false; } - public String getLimitString(String sql, boolean hasOffset) { - - int startOfSelect = sql.toLowerCase().indexOf("select"); - - StringBuffer pagingSelect = new StringBuffer( sql.length()+100 ) - .append( sql.substring(0, startOfSelect) ) //add the comment - .append("select * from ( select ") //nest the main query in an outer select - .append( getRowNumber(sql) ); //add the rownnumber bit into the outer query select list - - if ( hasDistinct(sql) ) { - pagingSelect.append(" row_.* from ( ") //add another (inner) nested select - .append( sql.substring(startOfSelect) ) //add the main query - .append(" ) as row_"); //close off the inner nested select + @Override + @SuppressWarnings("deprecation") + public String getLimitString(String sql, int offset, int limit) { + if ( offset == 0 ) { + return sql + " fetch first " + limit + " rows only"; } - else { - pagingSelect.append( sql.substring( startOfSelect + 6 ) ); //add the main query - } - - pagingSelect.append(" ) as temp_ where rownumber_ "); - - //add the restriction to the outer select - if (hasOffset) { - pagingSelect.append("between ?+1 and ?"); - } - else { - pagingSelect.append("<= ?"); - } - - return pagingSelect.toString(); + //nest the main query in an outer select + return "select * from ( select inner2_.*, rownumber() over(order by order of inner2_) as rownumber_ from ( " + + sql + " fetch first " + limit + " rows only ) as inner2_ ) as inner1_ where rownumber_ > " + + offset + " order by rownumber_"; } - private static boolean hasDistinct(String sql) { - return sql.toLowerCase().indexOf("select distinct")>=0; + /** + * {@inheritDoc} + *

+ * + * DB2 does have a one-based offset, however this was actually already handled in the limit string building + * (the '?+1' bit). To not mess up inheritors, I'll leave that part alone and not touch the offset here. + */ + @Override + @SuppressWarnings("deprecation") + public int convertToFirstRowValue(int zeroBasedFirstResult) { + return zeroBasedFirstResult; } + @Override + @SuppressWarnings("deprecation") public String getForUpdateString() { - return " for read only with rs"; + return " for read only with rs use and keep update locks"; } + @Override + @SuppressWarnings("deprecation") public boolean useMaxForLimit() { return true; } + @Override public boolean supportsOuterJoinForUpdate() { return false; } - public boolean supportsNotNullUnique() { + @Override + public boolean supportsExistsInSelect() { return false; } + @Override + public boolean supportsLockTimeouts() { + //as far as I know, DB2 doesn't support this + return false; + } + + @Override public String getSelectClauseNullString(int sqlType) { String literal; - switch(sqlType) { + switch ( sqlType ) { case Types.VARCHAR: case Types.CHAR: literal = "'x'"; @@ -315,78 +337,152 @@ return "nullif(" + literal + ',' + literal + ')'; } - public static void main(String[] args) { - System.out.println( new DB2Dialect().getLimitString("/*foo*/ select * from foos", true) ); - System.out.println( new DB2Dialect().getLimitString("/*foo*/ select distinct * from foos", true) ); - System.out.println( new DB2Dialect().getLimitString("/*foo*/ select * from foos foo order by foo.bar, foo.baz", true) ); - System.out.println( new DB2Dialect().getLimitString("/*foo*/ select distinct * from foos foo order by foo.bar, foo.baz", true) ); - } - + @Override public boolean supportsUnionAll() { return true; } + @Override public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException { return col; } + @Override public ResultSet getResultSet(CallableStatement ps) throws SQLException { boolean isResultSet = ps.execute(); // This assumes you will want to ignore any update counts - while (!isResultSet && ps.getUpdateCount() != -1) { - isResultSet = ps.getMoreResults(); + while ( !isResultSet && ps.getUpdateCount() != -1 ) { + isResultSet = ps.getMoreResults(); } - ResultSet rs = ps.getResultSet(); - // You may still have other ResultSets or update counts left to process here - // but you can't do it now or the ResultSet you just got will be closed - return rs; + + return ps.getResultSet(); } + @Override public boolean supportsCommentOn() { return true; } + @Override public boolean supportsTemporaryTables() { return true; } + @Override public String getCreateTemporaryTableString() { return "declare global temporary table"; } + @Override public String getCreateTemporaryTablePostfix() { return "not logged"; } + @Override public String generateTemporaryTableName(String baseTableName) { - return "session." + super.generateTemporaryTableName(baseTableName); + return "session." + super.generateTemporaryTableName( baseTableName ); } + @Override public boolean supportsCurrentTimestampSelection() { return true; } + @Override public String getCurrentTimestampSelectString() { return "values current timestamp"; } + @Override public boolean isCurrentTimestampSelectStringCallable() { return false; } + /** + * {@inheritDoc} + *

+ * NOTE : DB2 is know to support parameters in the SELECT clause, but only in casted form + * (see {@link #requiresCastingOfParametersInSelectClause()}). + */ + @Override public boolean supportsParametersInInsertSelect() { - // DB2 known to not support parameters within the select - // clause of an SQL INSERT ... SELECT ... statement + return true; + } + + /** + * {@inheritDoc} + *

+ * DB2 in fact does require that parameters appearing in the select clause be wrapped in cast() calls + * to tell the DB parser the type of the select value. + */ + @Override + public boolean requiresCastingOfParametersInSelectClause() { + return true; + } + + @Override + public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() { return false; } + @Override + public String getCrossJoinSeparator() { + //DB2 v9.1 doesn't support 'cross join' syntax + return ", "; + } + + // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public boolean supportsEmptyInList() { return false; } + @Override public boolean supportsLobValueChangePropogation() { return false; } + + @Override + public boolean doesReadCommittedCauseWritersToBlockReaders() { + return true; + } + + @Override + public boolean supportsTupleDistinctCounts() { + return false; + } + + @Override + protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) { + return sqlCode == Types.BOOLEAN ? SmallIntTypeDescriptor.INSTANCE : super.getSqlTypeDescriptorOverride( sqlCode ); + } + + @Override + public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() { + return new SQLExceptionConversionDelegate() { + @Override + public JDBCException convert(SQLException sqlException, String message, String sql) { + final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException ); + final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException ); + + if( -952 == errorCode && "57014".equals( sqlState )){ + throw new LockTimeoutException( message, sqlException, sql ); + } + return null; + } + }; + } + + @Override + public UniqueDelegate getUniqueDelegate() { + return uniqueDelegate; + } + + @Override + public String getNotExpression( String expression ) { + return "not (" + expression + ")"; + } + } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/DataDirectOracle9Dialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/DataDirectOracle9Dialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/DataDirectOracle9Dialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/DataDirectOracle9Dialect.java 30 Jul 2014 16:15:51 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,30 +20,31 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; import java.sql.CallableStatement; import java.sql.ResultSet; import java.sql.SQLException; +/** + * A Dialect for accessing Oracle through DataDirect driver + */ +@SuppressWarnings("deprecation") public class DataDirectOracle9Dialect extends Oracle9Dialect { - + @Override public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException { - return col; // sql server just returns automatically + return col; } - + + @Override public ResultSet getResultSet(CallableStatement ps) throws SQLException { - boolean isResultSet = ps.execute(); -// This assumes you will want to ignore any update counts + boolean isResultSet = ps.execute(); + // This assumes you will want to ignore any update counts while (!isResultSet && ps.getUpdateCount() != -1) { - isResultSet = ps.getMoreResults(); - } - ResultSet rs = ps.getResultSet(); -// You may still have other ResultSets or update counts left to process here -// but you can't do it now or the ResultSet you just got will be closed - return rs; - } + isResultSet = ps.getMoreResults(); + } + return ps.getResultSet(); + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/DerbyDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/DerbyDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/DerbyDialect.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/DerbyDialect.java 30 Jul 2014 16:15:54 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,202 +20,241 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; -import org.hibernate.Hibernate; -import org.hibernate.QueryException; -import org.hibernate.HibernateException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.type.Type; -import org.hibernate.dialect.function.SQLFunction; -import org.hibernate.dialect.function.SQLFunctionTemplate; +import java.lang.reflect.Method; +import java.sql.Types; + +import org.hibernate.MappingException; +import org.hibernate.dialect.function.AnsiTrimFunction; import org.hibernate.dialect.function.DerbyConcatFunction; -import org.hibernate.id.TableHiLoGenerator; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.ReflectHelper; import org.hibernate.sql.CaseFragment; import org.hibernate.sql.DerbyCaseFragment; -import java.util.List; -import java.util.ArrayList; +import org.jboss.logging.Logger; /** - * Hibernate Dialect for Cloudscape 10 - aka Derby. This implements both an + * Hibernate Dialect for Cloudscape 10 - aka Derby. This implements both an * override for the identity column generator as well as for the case statement * issue documented at: * http://www.jroller.com/comments/kenlars99/Weblog/cloudscape_soon_to_be_derby * * @author Simon Johnston + * + * @deprecated HHH-6073 */ +@Deprecated public class DerbyDialect extends DB2Dialect { + @SuppressWarnings("deprecation") + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + DerbyDialect.class.getName() + ); + private int driverVersionMajor; + private int driverVersionMinor; + + /** + * Constructs a DerbyDialect + */ + @SuppressWarnings("deprecation") public DerbyDialect() { super(); + if ( this.getClass() == DerbyDialect.class ) { + LOG.deprecatedDerbyDialect(); + } + registerFunction( "concat", new DerbyConcatFunction() ); - registerFunction( "trim", new DerbyTrimFunctionEmulation() ); + registerFunction( "trim", new AnsiTrimFunction() ); + registerColumnType( Types.BLOB, "blob" ); + determineDriverVersion(); + + if ( driverVersionMajor > 10 || ( driverVersionMajor == 10 && driverVersionMinor >= 7 ) ) { + registerColumnType( Types.BOOLEAN, "boolean" ); + } } - /** - * This is different in Cloudscape to DB2. - */ - public String getIdentityColumnString() { - return "not null generated always as identity"; //$NON-NLS-1 + private void determineDriverVersion() { + try { + // locate the derby sysinfo class and query its version info + final Class sysinfoClass = ReflectHelper.classForName( "org.apache.derby.tools.sysinfo", this.getClass() ); + final Method majorVersionGetter = sysinfoClass.getMethod( "getMajorVersion", ReflectHelper.NO_PARAM_SIGNATURE ); + final Method minorVersionGetter = sysinfoClass.getMethod( "getMinorVersion", ReflectHelper.NO_PARAM_SIGNATURE ); + driverVersionMajor = (Integer) majorVersionGetter.invoke( null, ReflectHelper.NO_PARAMS ); + driverVersionMinor = (Integer) minorVersionGetter.invoke( null, ReflectHelper.NO_PARAMS ); + } + catch ( Exception e ) { + LOG.unableToLoadDerbyDriver( e.getMessage() ); + driverVersionMajor = -1; + driverVersionMinor = -1; + } } - /** - * Return the case statement modified for Cloudscape. - */ + private boolean isTenPointFiveReleaseOrNewer() { + return driverVersionMajor > 10 || ( driverVersionMajor == 10 && driverVersionMinor >= 5 ); + } + + @Override + public String getCrossJoinSeparator() { + return ", "; + } + + @Override public CaseFragment createCaseFragment() { return new DerbyCaseFragment(); } + @Override public boolean dropConstraints() { - return true; + return true; } - public Class getNativeIdentifierGeneratorClass() { - return TableHiLoGenerator.class; + @Override + public boolean supportsSequences() { + // technically sequence support was added in 10.6.1.0... + // + // The problem though is that I am not exactly sure how to differentiate 10.6.1.0 from any other 10.6.x release. + // + // http://db.apache.org/derby/docs/10.0/publishedapi/org/apache/derby/tools/sysinfo.html seems incorrect. It + // states that derby's versioning scheme is major.minor.maintenance, but obviously 10.6.1.0 has 4 components + // to it, not 3. + // + // Let alone the fact that it states that versions with the matching major.minor are 'feature + // compatible' which is clearly not the case here (sequence support is a new feature...) + return driverVersionMajor > 10 || ( driverVersionMajor == 10 && driverVersionMinor >= 6 ); } - public boolean supportsSequences() { - return false; + @Override + public String getSequenceNextValString(String sequenceName) { + if ( supportsSequences() ) { + return "values next value for " + sequenceName; + } + else { + throw new MappingException( "Derby does not support sequence prior to release 10.6.1.0" ); + } } + @Override public boolean supportsLimit() { + return isTenPointFiveReleaseOrNewer(); + } + + @Override + public boolean supportsCommentOn() { + //HHH-4531 return false; } + @Override + @SuppressWarnings("deprecation") public boolean supportsLimitOffset() { - return false; + return isTenPointFiveReleaseOrNewer(); } - public String getQuerySequencesString() { - return null ; + @Override + public String getForUpdateString() { + return " for update with rs"; } + @Override + public String getWriteLockString(int timeout) { + return " for update with rs"; + } + + @Override + public String getReadLockString(int timeout) { + return " for read only with rs"; + } + + /** - * A specialized function template to emulate the ANSI trim function on Derby DB - * since it does not support the full trim specification. However, we cannot even - * fully emulate it because there is not standard 'replace' function either. :( + * {@inheritDoc} + *

+ * From Derby 10.5 Docs: + *

+	 * Query
+	 * [ORDER BY clause]
+	 * [result offset clause]
+	 * [fetch first clause]
+	 * [FOR UPDATE clause]
+	 * [WITH {RR|RS|CS|UR}]
+	 * 
*/ - public static class DerbyTrimFunctionEmulation implements SQLFunction { - private static final SQLFunction LEADING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( ?1 )"); - private static final SQLFunction TRAILING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "rtrim( ?1 )"); - private static final SQLFunction BOTH_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?1 ) )"); - private static final SQLFunction BOTH_SPACE_TRIM_FROM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?2 ) )"); + @Override + public String getLimitString(String query, final int offset, final int limit) { + final StringBuilder sb = new StringBuilder(query.length() + 50); + final String normalizedSelect = query.toLowerCase().trim(); + final int forUpdateIndex = normalizedSelect.lastIndexOf( "for update") ; - public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { - return Hibernate.STRING; + if ( hasForUpdateClause( forUpdateIndex ) ) { + sb.append( query.substring( 0, forUpdateIndex-1 ) ); } - - public boolean hasArguments() { - return true; + else if ( hasWithClause( normalizedSelect ) ) { + sb.append( query.substring( 0, getWithIndex( query ) - 1 ) ); } + else { + sb.append( query ); + } - public boolean hasParenthesesIfNoArguments() { - return false; + if ( offset == 0 ) { + sb.append( " fetch first " ); } + else { + sb.append( " offset " ).append( offset ).append( " rows fetch next " ); + } - public String render(List args, SessionFactoryImplementor factory) throws QueryException { - // according to both the ANSI-SQL and EJB3 specs, trim can either take - // exactly one parameter or a variable number of parameters between 1 and 4. - // from the SQL spec: - // - // ::= - // TRIM - // - // ::= - // [ [ ] [ ] FROM ] - // - // ::= - // LEADING - // | TRAILING - // | BOTH - // - // If only is omitted, BOTH is assumed; - // if is omitted, space is assumed - if ( args.size() == 1 ) { - // we have the form: trim(trimSource) - // so we trim leading and trailing spaces - return BOTH_SPACE_TRIM.render( args, factory ); - } - else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) { - // we have the form: trim(from trimSource). - // This is functionally equivalent to trim(trimSource) - return BOTH_SPACE_TRIM_FROM.render( args, factory ); - } - else { - // otherwise, a trim-specification and/or a trim-character - // have been specified; we need to decide which options - // are present and "do the right thing" - boolean leading = true; // should leading trim-characters be trimmed? - boolean trailing = true; // should trailing trim-characters be trimmed? - String trimCharacter; // the trim-character - String trimSource; // the trim-source + sb.append( limit ).append( " rows only" ); - // potentialTrimCharacterArgIndex = 1 assumes that a - // trim-specification has been specified. we handle the - // exception to that explicitly - int potentialTrimCharacterArgIndex = 1; - String firstArg = ( String ) args.get( 0 ); - if ( "leading".equalsIgnoreCase( firstArg ) ) { - trailing = false; - } - else if ( "trailing".equalsIgnoreCase( firstArg ) ) { - leading = false; - } - else if ( "both".equalsIgnoreCase( firstArg ) ) { - } - else { - potentialTrimCharacterArgIndex = 0; - } + if ( hasForUpdateClause( forUpdateIndex ) ) { + sb.append( ' ' ); + sb.append( query.substring( forUpdateIndex ) ); + } + else if ( hasWithClause( normalizedSelect ) ) { + sb.append( ' ' ).append( query.substring( getWithIndex( query ) ) ); + } + return sb.toString(); + } - String potentialTrimCharacter = ( String ) args.get( potentialTrimCharacterArgIndex ); - if ( "from".equalsIgnoreCase( potentialTrimCharacter ) ) { - trimCharacter = "' '"; - trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 ); - } - else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) { - trimCharacter = "' '"; - trimSource = potentialTrimCharacter; - } - else { - trimCharacter = potentialTrimCharacter; - if ( "from".equalsIgnoreCase( ( String ) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) { - trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 2 ); - } - else { - trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 ); - } - } + @Override + public boolean supportsVariableLimit() { + // we bind the limit and offset values directly into the sql... + return false; + } - List argsToUse = new ArrayList(); - argsToUse.add( trimSource ); - argsToUse.add( trimCharacter ); + private boolean hasForUpdateClause(int forUpdateIndex) { + return forUpdateIndex >= 0; + } - if ( trimCharacter.equals( "' '" ) ) { - if ( leading && trailing ) { - return BOTH_SPACE_TRIM.render( argsToUse, factory ); - } - else if ( leading ) { - return LEADING_SPACE_TRIM.render( argsToUse, factory ); - } - else { - return TRAILING_SPACE_TRIM.render( argsToUse, factory ); - } - } - else { - throw new HibernateException( "cannot specify trim character when using Derby as Derby does not support the ANSI trim function, not does it support a replace function to properly emmulate it" ); - } - } + private boolean hasWithClause(String normalizedSelect){ + return normalizedSelect.startsWith( "with ", normalizedSelect.length()-7 ); + } + + private int getWithIndex(String querySelect) { + int i = querySelect.lastIndexOf( "with " ); + if ( i < 0 ) { + i = querySelect.lastIndexOf( "WITH " ); } + return i; } + @Override + public String getQuerySequencesString() { + return null ; + } + // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public boolean supportsLobValueChangePropogation() { return false; } + + @Override + public boolean supportsUnboundedLobLocatorMaterialization() { + return false; + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/DerbyTenFiveDialect.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/DerbyTenSevenDialect.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/DerbyTenSixDialect.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/Dialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/Dialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/Dialect.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/Dialect.java 30 Jul 2014 16:15:54 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,207 +20,213 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; +import java.io.InputStream; +import java.io.OutputStream; +import java.sql.Blob; import java.sql.CallableStatement; +import java.sql.Clob; +import java.sql.NClob; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.hibernate.Hibernate; import org.hibernate.HibernateException; import org.hibernate.LockMode; +import org.hibernate.LockOptions; import org.hibernate.MappingException; -import org.hibernate.QueryException; +import org.hibernate.NullPrecedence; +import org.hibernate.ScrollMode; import org.hibernate.cfg.Environment; import org.hibernate.dialect.function.CastFunction; import org.hibernate.dialect.function.SQLFunction; import org.hibernate.dialect.function.SQLFunctionTemplate; +import org.hibernate.dialect.function.StandardAnsiSqlAggregationFunctions; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.lock.LockingStrategy; +import org.hibernate.dialect.lock.OptimisticForceIncrementLockingStrategy; +import org.hibernate.dialect.lock.OptimisticLockingStrategy; +import org.hibernate.dialect.lock.PessimisticForceIncrementLockingStrategy; +import org.hibernate.dialect.lock.PessimisticReadSelectLockingStrategy; +import org.hibernate.dialect.lock.PessimisticWriteSelectLockingStrategy; import org.hibernate.dialect.lock.SelectLockingStrategy; -import org.hibernate.engine.Mapping; -import org.hibernate.exception.SQLExceptionConverter; -import org.hibernate.exception.SQLStateConverter; -import org.hibernate.exception.ViolatedConstraintNameExtracter; +import org.hibernate.dialect.pagination.LegacyLimitHandler; +import org.hibernate.dialect.pagination.LimitHandler; +import org.hibernate.dialect.unique.DefaultUniqueDelegate; +import org.hibernate.dialect.unique.UniqueDelegate; +import org.hibernate.engine.jdbc.LobCreator; +import org.hibernate.engine.spi.RowSelection; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.exception.spi.ConversionContext; +import org.hibernate.exception.spi.SQLExceptionConversionDelegate; +import org.hibernate.exception.spi.SQLExceptionConverter; +import org.hibernate.exception.spi.ViolatedConstraintNameExtracter; import org.hibernate.id.IdentityGenerator; import org.hibernate.id.SequenceGenerator; import org.hibernate.id.TableHiLoGenerator; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.internal.util.io.StreamCopier; import org.hibernate.mapping.Column; +import org.hibernate.metamodel.spi.TypeContributions; import org.hibernate.persister.entity.Lockable; +import org.hibernate.procedure.internal.StandardCallableStatementSupport; +import org.hibernate.procedure.spi.CallableStatementSupport; +import org.hibernate.service.ServiceRegistry; import org.hibernate.sql.ANSICaseFragment; import org.hibernate.sql.ANSIJoinFragment; import org.hibernate.sql.CaseFragment; -import org.hibernate.sql.JoinFragment; import org.hibernate.sql.ForUpdateFragment; -import org.hibernate.type.Type; -import org.hibernate.util.ReflectHelper; -import org.hibernate.util.StringHelper; +import org.hibernate.sql.JoinFragment; +import org.hibernate.type.StandardBasicTypes; +import org.hibernate.type.descriptor.sql.ClobTypeDescriptor; +import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; +import org.jboss.logging.Logger; + /** - * Represents a dialect of SQL implemented by a particular RDBMS. - * Subclasses implement Hibernate compatibility with different systems.
- *
- * Subclasses should provide a public default constructor that register() - * a set of type mappings and default Hibernate properties.
- *
- * Subclasses should be immutable. + * Represents a dialect of SQL implemented by a particular RDBMS. Subclasses implement Hibernate compatibility + * with different systems. Subclasses should provide a public default constructor that register a set of type + * mappings and default Hibernate properties. Subclasses should be immutable. * * @author Gavin King, David Channon */ -public abstract class Dialect { +@SuppressWarnings("deprecation") +public abstract class Dialect implements ConversionContext { + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + Dialect.class.getName() + ); - private static final Logger log = LoggerFactory.getLogger( Dialect.class ); - + /** + * Defines a default batch size constant + */ public static final String DEFAULT_BATCH_SIZE = "15"; + + /** + * Defines a "no batching" batch size constant + */ public static final String NO_BATCH = "0"; /** - * Characters used for quoting SQL identifiers + * Characters used as opening for quoting SQL identifiers */ public static final String QUOTE = "`\"["; + + /** + * Characters used as closing for quoting SQL identifiers + */ public static final String CLOSED_QUOTE = "`\"]"; - - // build the map of standard ANSI SQL aggregation functions ~~~~~~~~~~~~~~~ - - private static final Map STANDARD_AGGREGATE_FUNCTIONS = new HashMap(); - static { - STANDARD_AGGREGATE_FUNCTIONS.put( "count", new StandardSQLFunction("count") { - public Type getReturnType(Type columnType, Mapping mapping) { - return Hibernate.LONG; - } - } ); - - STANDARD_AGGREGATE_FUNCTIONS.put( "avg", 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()" ); - return Hibernate.DOUBLE; - } - } ); - - STANDARD_AGGREGATE_FUNCTIONS.put( "max", new StandardSQLFunction("max") ); - STANDARD_AGGREGATE_FUNCTIONS.put( "min", new StandardSQLFunction("min") ); - STANDARD_AGGREGATE_FUNCTIONS.put( "sum", new StandardSQLFunction("sum") { - public Type getReturnType(Type columnType, Mapping mapping) { - //pre H3.2 behavior: super.getReturnType(ct, m); - 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 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; - } - else if ( columnType == Hibernate.BIG_DECIMAL ) { - return Hibernate.BIG_DECIMAL; - } - else if ( columnType == Hibernate.LONG || columnType == Hibernate.SHORT || columnType == Hibernate.INTEGER) { - return Hibernate.LONG; - } - else if ( columnType == Hibernate.FLOAT || columnType == Hibernate.DOUBLE) { - return Hibernate.DOUBLE; - } - - // finally use the sqltype if == on Hibernate types did not find a match. - if ( sqlType == Types.NUMERIC ) { - return columnType; //because numeric can be anything - } - else if ( sqlType == Types.FLOAT || sqlType == Types.DOUBLE || sqlType == Types.DECIMAL || sqlType == Types.REAL) { - return Hibernate.DOUBLE; - } - else if ( sqlType == Types.BIGINT || sqlType == Types.INTEGER || sqlType == Types.SMALLINT || sqlType == Types.TINYINT ) { - return Hibernate.LONG; - } - else { - return columnType; - } - } - }); - } - private final TypeNames typeNames = new TypeNames(); private final TypeNames hibernateTypeNames = new TypeNames(); private final Properties properties = new Properties(); - private final Map sqlFunctions = new HashMap(); - private final Set sqlKeywords = new HashSet(); + private final Map sqlFunctions = new HashMap(); + private final Set sqlKeywords = new HashSet(); + private final UniqueDelegate uniqueDelegate; + // constructors and factory methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ protected Dialect() { - log.info( "Using dialect: " + this ); - sqlFunctions.putAll( STANDARD_AGGREGATE_FUNCTIONS ); + LOG.usingDialect( this ); + StandardAnsiSqlAggregationFunctions.primeFunctionMap( sqlFunctions ); // standard sql92 functions (can be overridden by subclasses) - registerFunction( "substring", new SQLFunctionTemplate( Hibernate.STRING, "substring(?1, ?2, ?3)" ) ); - registerFunction( "locate", new SQLFunctionTemplate( Hibernate.INTEGER, "locate(?1, ?2, ?3)" ) ); - registerFunction( "trim", new SQLFunctionTemplate( Hibernate.STRING, "trim(?1 ?2 ?3 ?4)" ) ); - registerFunction( "length", new StandardSQLFunction( "length", Hibernate.INTEGER ) ); - registerFunction( "bit_length", new StandardSQLFunction( "bit_length", Hibernate.INTEGER ) ); + registerFunction( "substring", new SQLFunctionTemplate( StandardBasicTypes.STRING, "substring(?1, ?2, ?3)" ) ); + registerFunction( "locate", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "locate(?1, ?2, ?3)" ) ); + registerFunction( "trim", new SQLFunctionTemplate( StandardBasicTypes.STRING, "trim(?1 ?2 ?3 ?4)" ) ); + registerFunction( "length", new StandardSQLFunction( "length", StandardBasicTypes.INTEGER ) ); + registerFunction( "bit_length", new StandardSQLFunction( "bit_length", StandardBasicTypes.INTEGER ) ); registerFunction( "coalesce", new StandardSQLFunction( "coalesce" ) ); registerFunction( "nullif", new StandardSQLFunction( "nullif" ) ); registerFunction( "abs", new StandardSQLFunction( "abs" ) ); - registerFunction( "mod", new StandardSQLFunction( "mod", Hibernate.INTEGER) ); - registerFunction( "sqrt", new StandardSQLFunction( "sqrt", Hibernate.DOUBLE) ); + registerFunction( "mod", new StandardSQLFunction( "mod", StandardBasicTypes.INTEGER) ); + registerFunction( "sqrt", new StandardSQLFunction( "sqrt", StandardBasicTypes.DOUBLE) ); registerFunction( "upper", new StandardSQLFunction("upper") ); registerFunction( "lower", new StandardSQLFunction("lower") ); registerFunction( "cast", new CastFunction() ); - registerFunction( "extract", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(?1 ?2 ?3)") ); + registerFunction( "extract", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "extract(?1 ?2 ?3)") ); //map second/minute/hour/day/month/year to ANSI extract(), override on subclasses - registerFunction( "second", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(second from ?1)") ); - registerFunction( "minute", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(minute from ?1)") ); - registerFunction( "hour", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(hour from ?1)") ); - registerFunction( "day", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(day from ?1)") ); - registerFunction( "month", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(month from ?1)") ); - registerFunction( "year", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(year from ?1)") ); + registerFunction( "second", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "extract(second from ?1)") ); + registerFunction( "minute", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "extract(minute from ?1)") ); + registerFunction( "hour", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "extract(hour from ?1)") ); + registerFunction( "day", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "extract(day from ?1)") ); + registerFunction( "month", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "extract(month from ?1)") ); + registerFunction( "year", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "extract(year from ?1)") ); - registerFunction( "str", new SQLFunctionTemplate(Hibernate.STRING, "cast(?1 as char)") ); + registerFunction( "str", new SQLFunctionTemplate(StandardBasicTypes.STRING, "cast(?1 as char)") ); - // register hibernate types for default use in scalar sqlquery type auto detection - registerHibernateType( Types.BIGINT, Hibernate.BIG_INTEGER.getName() ); - registerHibernateType( Types.BINARY, Hibernate.BINARY.getName() ); - registerHibernateType( Types.BIT, Hibernate.BOOLEAN.getName() ); - registerHibernateType( Types.CHAR, Hibernate.CHARACTER.getName() ); - registerHibernateType( Types.DATE, Hibernate.DATE.getName() ); - registerHibernateType( Types.DOUBLE, Hibernate.DOUBLE.getName() ); - registerHibernateType( Types.FLOAT, Hibernate.FLOAT.getName() ); - registerHibernateType( Types.INTEGER, Hibernate.INTEGER.getName() ); - registerHibernateType( Types.SMALLINT, Hibernate.SHORT.getName() ); - registerHibernateType( Types.TINYINT, Hibernate.BYTE.getName() ); - registerHibernateType( Types.TIME, Hibernate.TIME.getName() ); - registerHibernateType( Types.TIMESTAMP, Hibernate.TIMESTAMP.getName() ); - registerHibernateType( Types.VARCHAR, Hibernate.STRING.getName() ); - registerHibernateType( Types.VARBINARY, Hibernate.BINARY.getName() ); - registerHibernateType( Types.NUMERIC, Hibernate.BIG_DECIMAL.getName() ); - registerHibernateType( Types.DECIMAL, Hibernate.BIG_DECIMAL.getName() ); - registerHibernateType( Types.BLOB, Hibernate.BLOB.getName() ); - registerHibernateType( Types.CLOB, Hibernate.CLOB.getName() ); - registerHibernateType( Types.REAL, Hibernate.FLOAT.getName() ); + registerColumnType( Types.BIT, "bit" ); + registerColumnType( Types.BOOLEAN, "boolean" ); + registerColumnType( Types.TINYINT, "tinyint" ); + registerColumnType( Types.SMALLINT, "smallint" ); + registerColumnType( Types.INTEGER, "integer" ); + registerColumnType( Types.BIGINT, "bigint" ); + registerColumnType( Types.FLOAT, "float($p)" ); + registerColumnType( Types.DOUBLE, "double precision" ); + registerColumnType( Types.NUMERIC, "numeric($p,$s)" ); + registerColumnType( Types.REAL, "real" ); + + registerColumnType( Types.DATE, "date" ); + registerColumnType( Types.TIME, "time" ); + registerColumnType( Types.TIMESTAMP, "timestamp" ); + + registerColumnType( Types.VARBINARY, "bit varying($l)" ); + registerColumnType( Types.LONGVARBINARY, "bit varying($l)" ); + registerColumnType( Types.BLOB, "blob" ); + + registerColumnType( Types.CHAR, "char($l)" ); + registerColumnType( Types.VARCHAR, "varchar($l)" ); + registerColumnType( Types.LONGVARCHAR, "varchar($l)" ); + registerColumnType( Types.CLOB, "clob" ); + + registerColumnType( Types.NCHAR, "nchar($l)" ); + registerColumnType( Types.NVARCHAR, "nvarchar($l)" ); + registerColumnType( Types.LONGNVARCHAR, "nvarchar($l)" ); + registerColumnType( Types.NCLOB, "nclob" ); + + // register hibernate types for default use in scalar sqlquery type auto detection + registerHibernateType( Types.BIGINT, StandardBasicTypes.BIG_INTEGER.getName() ); + registerHibernateType( Types.BINARY, StandardBasicTypes.BINARY.getName() ); + registerHibernateType( Types.BIT, StandardBasicTypes.BOOLEAN.getName() ); + registerHibernateType( Types.BOOLEAN, StandardBasicTypes.BOOLEAN.getName() ); + registerHibernateType( Types.CHAR, StandardBasicTypes.CHARACTER.getName() ); + registerHibernateType( Types.CHAR, 1, StandardBasicTypes.CHARACTER.getName() ); + registerHibernateType( Types.CHAR, 255, StandardBasicTypes.STRING.getName() ); + registerHibernateType( Types.DATE, StandardBasicTypes.DATE.getName() ); + registerHibernateType( Types.DOUBLE, StandardBasicTypes.DOUBLE.getName() ); + registerHibernateType( Types.FLOAT, StandardBasicTypes.FLOAT.getName() ); + registerHibernateType( Types.INTEGER, StandardBasicTypes.INTEGER.getName() ); + registerHibernateType( Types.SMALLINT, StandardBasicTypes.SHORT.getName() ); + registerHibernateType( Types.TINYINT, StandardBasicTypes.BYTE.getName() ); + registerHibernateType( Types.TIME, StandardBasicTypes.TIME.getName() ); + registerHibernateType( Types.TIMESTAMP, StandardBasicTypes.TIMESTAMP.getName() ); + registerHibernateType( Types.VARCHAR, StandardBasicTypes.STRING.getName() ); + registerHibernateType( Types.VARBINARY, StandardBasicTypes.BINARY.getName() ); + registerHibernateType( Types.LONGVARCHAR, StandardBasicTypes.TEXT.getName() ); + registerHibernateType( Types.LONGVARBINARY, StandardBasicTypes.IMAGE.getName() ); + registerHibernateType( Types.NUMERIC, StandardBasicTypes.BIG_DECIMAL.getName() ); + registerHibernateType( Types.DECIMAL, StandardBasicTypes.BIG_DECIMAL.getName() ); + registerHibernateType( Types.BLOB, StandardBasicTypes.BLOB.getName() ); + registerHibernateType( Types.CLOB, StandardBasicTypes.CLOB.getName() ); + registerHibernateType( Types.REAL, StandardBasicTypes.FLOAT.getName() ); + + uniqueDelegate = new DefaultUniqueDelegate( this ); } /** @@ -230,8 +236,7 @@ * @throws HibernateException If no dialect was specified, or if it could not be instantiated. */ public static Dialect getDialect() throws HibernateException { - String dialectName = Environment.getProperties().getProperty( Environment.DIALECT ); - return instantiateDialect( dialectName ); + return instantiateDialect( Environment.getProperties().getProperty( Environment.DIALECT ) ); } @@ -244,7 +249,7 @@ * @throws HibernateException If no dialect was specified, or if it could not be instantiated. */ public static Dialect getDialect(Properties props) throws HibernateException { - String dialectName = props.getProperty( Environment.DIALECT ); + final String dialectName = props.getProperty( Environment.DIALECT ); if ( dialectName == null ) { return getDialect(); } @@ -256,13 +261,13 @@ throw new HibernateException( "The dialect was not set. Set the property hibernate.dialect." ); } try { - return ( Dialect ) ReflectHelper.classForName( dialectName ).newInstance(); + return (Dialect) ReflectHelper.classForName( dialectName ).newInstance(); } catch ( ClassNotFoundException cnfe ) { throw new HibernateException( "Dialect class not found: " + dialectName ); } catch ( Exception e ) { - throw new HibernateException( "Could not instantiate dialect class", e ); + throw new HibernateException( "Could not instantiate given dialect class: " + dialectName, e ); } } @@ -275,6 +280,7 @@ return properties; } + @Override public String toString() { return getClass().getName(); } @@ -283,6 +289,16 @@ // database type mapping support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** + * Allows the Dialect to contribute additional types + * + * @param typeContributions Callback to contribute the types + * @param serviceRegistry The service registry + */ + public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) { + // by default, nothing to do + } + + /** * Get the name of the database type associated with the given * {@link java.sql.Types} typecode. * @@ -291,7 +307,7 @@ * @throws HibernateException If no mapping was specified for that type. */ public String getTypeName(int code) throws HibernateException { - String result = typeNames.get( code ); + final String result = typeNames.get( code ); if ( result == null ) { throw new HibernateException( "No default type mapping for (java.sql.Types) " + code ); } @@ -310,14 +326,11 @@ * @return the database type name * @throws HibernateException If no mapping was specified for that type. */ - public String getTypeName(int code, int length, int precision, int scale) throws HibernateException { - String result = typeNames.get( code, length, precision, scale ); + public String getTypeName(int code, long length, int precision, int scale) throws HibernateException { + final String result = typeNames.get( code, length, precision, scale ); if ( result == null ) { throw new HibernateException( - "No type mapping for java.sql.Types code: " + - code + - ", length: " + - length + String.format( "No type mapping for java.sql.Types code: %s, length: %s", code, length ) ); } return result; @@ -335,6 +348,56 @@ } /** + * Return an expression casting the value to the specified type + * + * @param value The value to cast + * @param jdbcTypeCode The JDBC type code to cast to + * @param length The type length + * @param precision The type precision + * @param scale The type scale + * + * @return The cast expression + */ + public String cast(String value, int jdbcTypeCode, int length, int precision, int scale) { + if ( jdbcTypeCode == Types.CHAR ) { + return "cast(" + value + " as char(" + length + "))"; + } + else { + return "cast(" + value + "as " + getTypeName( jdbcTypeCode, length, precision, scale ) + ")"; + } + } + + /** + * Return an expression casting the value to the specified type. Simply calls + * {@link #cast(String, int, int, int, int)} passing {@link Column#DEFAULT_PRECISION} and + * {@link Column#DEFAULT_SCALE} as the precision/scale. + * + * @param value The value to cast + * @param jdbcTypeCode The JDBC type code to cast to + * @param length The type length + * + * @return The cast expression + */ + public String cast(String value, int jdbcTypeCode, int length) { + return cast( value, jdbcTypeCode, length, Column.DEFAULT_PRECISION, Column.DEFAULT_SCALE ); + } + + /** + * Return an expression casting the value to the specified type. Simply calls + * {@link #cast(String, int, int, int, int)} passing {@link Column#DEFAULT_LENGTH} as the length + * + * @param value The value to cast + * @param jdbcTypeCode The JDBC type code to cast to + * @param precision The type precision + * @param scale The type scale + * + * @return The cast expression + */ + public String cast(String value, int jdbcTypeCode, int precision, int scale) { + return cast( value, jdbcTypeCode, Column.DEFAULT_LENGTH, precision, scale ); + } + + /** * Subclasses register a type name for the given type code and maximum * column length. $l in the type name with be replaced by the * column length (if appropriate). @@ -343,7 +406,7 @@ * @param capacity The maximum length of database type * @param name The database type name */ - protected void registerColumnType(int code, int capacity, String name) { + protected void registerColumnType(int code, long capacity, String name) { typeNames.put( code, capacity, name ); } @@ -358,19 +421,216 @@ typeNames.put( code, name ); } + /** + * Allows the dialect to override a {@link SqlTypeDescriptor}. + *

+ * If the passed {@code sqlTypeDescriptor} allows itself to be remapped (per + * {@link org.hibernate.type.descriptor.sql.SqlTypeDescriptor#canBeRemapped()}), then this method uses + * {@link #getSqlTypeDescriptorOverride} to get an optional override based on the SQL code returned by + * {@link SqlTypeDescriptor#getSqlType()}. + *

+ * If this dialect does not provide an override or if the {@code sqlTypeDescriptor} doe not allow itself to be + * remapped, then this method simply returns the original passed {@code sqlTypeDescriptor} + * + * @param sqlTypeDescriptor The {@link SqlTypeDescriptor} to override + * @return The {@link SqlTypeDescriptor} that should be used for this dialect; + * if there is no override, then original {@code sqlTypeDescriptor} is returned. + * @throws IllegalArgumentException if {@code sqlTypeDescriptor} is null. + * + * @see #getSqlTypeDescriptorOverride + */ + public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) { + if ( sqlTypeDescriptor == null ) { + throw new IllegalArgumentException( "sqlTypeDescriptor is null" ); + } + if ( ! sqlTypeDescriptor.canBeRemapped() ) { + return sqlTypeDescriptor; + } + final SqlTypeDescriptor overridden = getSqlTypeDescriptorOverride( sqlTypeDescriptor.getSqlType() ); + return overridden == null ? sqlTypeDescriptor : overridden; + } + + /** + * Returns the {@link SqlTypeDescriptor} that should be used to handle the given JDBC type code. Returns + * {@code null} if there is no override. + * + * @param sqlCode A {@link Types} constant indicating the SQL column type + * @return The {@link SqlTypeDescriptor} to use as an override, or {@code null} if there is no override. + */ + protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) { + SqlTypeDescriptor descriptor; + switch ( sqlCode ) { + case Types.CLOB: { + descriptor = useInputStreamToInsertBlob() ? ClobTypeDescriptor.STREAM_BINDING : null; + break; + } + default: { + descriptor = null; + break; + } + } + return descriptor; + } + + /** + * The legacy behavior of Hibernate. LOBs are not processed by merge + */ + @SuppressWarnings( {"UnusedDeclaration"}) + protected static final LobMergeStrategy LEGACY_LOB_MERGE_STRATEGY = new LobMergeStrategy() { + @Override + public Blob mergeBlob(Blob original, Blob target, SessionImplementor session) { + return target; + } + + @Override + public Clob mergeClob(Clob original, Clob target, SessionImplementor session) { + return target; + } + + @Override + public NClob mergeNClob(NClob original, NClob target, SessionImplementor session) { + return target; + } + }; + + /** + * Merge strategy based on transferring contents based on streams. + */ + @SuppressWarnings( {"UnusedDeclaration"}) + protected static final LobMergeStrategy STREAM_XFER_LOB_MERGE_STRATEGY = new LobMergeStrategy() { + @Override + public Blob mergeBlob(Blob original, Blob target, SessionImplementor session) { + if ( original != target ) { + try { + // the BLOB just read during the load phase of merge + final OutputStream connectedStream = target.setBinaryStream( 1L ); + // the BLOB from the detached state + final InputStream detachedStream = original.getBinaryStream(); + StreamCopier.copy( detachedStream, connectedStream ); + return target; + } + catch (SQLException e ) { + throw session.getFactory().getSQLExceptionHelper().convert( e, "unable to merge BLOB data" ); + } + } + else { + return NEW_LOCATOR_LOB_MERGE_STRATEGY.mergeBlob( original, target, session ); + } + } + + @Override + public Clob mergeClob(Clob original, Clob target, SessionImplementor session) { + if ( original != target ) { + try { + // the CLOB just read during the load phase of merge + final OutputStream connectedStream = target.setAsciiStream( 1L ); + // the CLOB from the detached state + final InputStream detachedStream = original.getAsciiStream(); + StreamCopier.copy( detachedStream, connectedStream ); + return target; + } + catch (SQLException e ) { + throw session.getFactory().getSQLExceptionHelper().convert( e, "unable to merge CLOB data" ); + } + } + else { + return NEW_LOCATOR_LOB_MERGE_STRATEGY.mergeClob( original, target, session ); + } + } + + @Override + public NClob mergeNClob(NClob original, NClob target, SessionImplementor session) { + if ( original != target ) { + try { + // the NCLOB just read during the load phase of merge + final OutputStream connectedStream = target.setAsciiStream( 1L ); + // the NCLOB from the detached state + final InputStream detachedStream = original.getAsciiStream(); + StreamCopier.copy( detachedStream, connectedStream ); + return target; + } + catch (SQLException e ) { + throw session.getFactory().getSQLExceptionHelper().convert( e, "unable to merge NCLOB data" ); + } + } + else { + return NEW_LOCATOR_LOB_MERGE_STRATEGY.mergeNClob( original, target, session ); + } + } + }; + + /** + * Merge strategy based on creating a new LOB locator. + */ + protected static final LobMergeStrategy NEW_LOCATOR_LOB_MERGE_STRATEGY = new LobMergeStrategy() { + @Override + public Blob mergeBlob(Blob original, Blob target, SessionImplementor session) { + if ( original == null && target == null ) { + return null; + } + try { + final LobCreator lobCreator = session.getFactory().getJdbcServices().getLobCreator( session ); + return original == null + ? lobCreator.createBlob( ArrayHelper.EMPTY_BYTE_ARRAY ) + : lobCreator.createBlob( original.getBinaryStream(), original.length() ); + } + catch (SQLException e) { + throw session.getFactory().getSQLExceptionHelper().convert( e, "unable to merge BLOB data" ); + } + } + + @Override + public Clob mergeClob(Clob original, Clob target, SessionImplementor session) { + if ( original == null && target == null ) { + return null; + } + try { + final LobCreator lobCreator = session.getFactory().getJdbcServices().getLobCreator( session ); + return original == null + ? lobCreator.createClob( "" ) + : lobCreator.createClob( original.getCharacterStream(), original.length() ); + } + catch (SQLException e) { + throw session.getFactory().getSQLExceptionHelper().convert( e, "unable to merge CLOB data" ); + } + } + + @Override + public NClob mergeNClob(NClob original, NClob target, SessionImplementor session) { + if ( original == null && target == null ) { + return null; + } + try { + final LobCreator lobCreator = session.getFactory().getJdbcServices().getLobCreator( session ); + return original == null + ? lobCreator.createNClob( "" ) + : lobCreator.createNClob( original.getCharacterStream(), original.length() ); + } + catch (SQLException e) { + throw session.getFactory().getSQLExceptionHelper().convert( e, "unable to merge NCLOB data" ); + } + } + }; + + public LobMergeStrategy getLobMergeStrategy() { + return NEW_LOCATOR_LOB_MERGE_STRATEGY; + } + + // hibernate type mapping support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** - * Get the name of the Hibernate {@link org.hibernate.type.Type} associated with th given - * {@link java.sql.Types} typecode. + * Get the name of the Hibernate {@link org.hibernate.type.Type} associated with the given + * {@link java.sql.Types} type code. * - * @param code The {@link java.sql.Types} typecode + * @param code The {@link java.sql.Types} type code * @return The Hibernate {@link org.hibernate.type.Type} name. * @throws HibernateException If no mapping was specified for that type. */ + @SuppressWarnings( {"UnusedDeclaration"}) public String getHibernateTypeName(int code) throws HibernateException { - String result = hibernateTypeNames.get( code ); + final String result = hibernateTypeNames.get( code ); if ( result == null ) { throw new HibernateException( "No Hibernate type mapping for java.sql.Types code: " + code ); } @@ -390,13 +650,14 @@ * @throws HibernateException If no mapping was specified for that type. */ public String getHibernateTypeName(int code, int length, int precision, int scale) throws HibernateException { - String result = hibernateTypeNames.get( code, length, precision, scale ); + final String result = hibernateTypeNames.get( code, length, precision, scale ); if ( result == null ) { throw new HibernateException( - "No Hibernate type mapping for java.sql.Types code: " + - code + - ", length: " + - length + String.format( + "No Hibernate type mapping for type [code=%s, length=%s]", + code, + length + ) ); } return result; @@ -410,7 +671,7 @@ * @param capacity The maximum length of database type * @param name The Hibernate {@link org.hibernate.type.Type} name */ - protected void registerHibernateType(int code, int capacity, String name) { + protected void registerHibernateType(int code, long capacity, String name) { hibernateTypeNames.put( code, capacity, name); } @@ -429,32 +690,34 @@ // function support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ protected void registerFunction(String name, SQLFunction function) { - sqlFunctions.put( name, function ); + // HHH-7721: SQLFunctionRegistry expects all lowercase. Enforce, + // just in case a user's customer dialect uses mixed cases. + sqlFunctions.put( name.toLowerCase(), function ); } /** - * Retrieves a map of the dialect's registered fucntions + * Retrieves a map of the dialect's registered functions * (functionName => {@link org.hibernate.dialect.function.SQLFunction}). * * @return The map of registered functions. */ - public final Map getFunctions() { + public final Map getFunctions() { return sqlFunctions; } // keyword support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ protected void registerKeyword(String word) { - sqlKeywords.add(word); + sqlKeywords.add( word ); } - public Set getKeywords() { + public Set getKeywords() { return sqlKeywords; } - // native identifier generatiion ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // native identifier generation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** * The class (which implements {@link org.hibernate.id.IdentifierGenerator}) @@ -501,7 +764,7 @@ /** * Whether this dialect have an Identity clause added to the data type or a - * completely seperate identity data type + * completely separate identity data type * * @return boolean */ @@ -510,7 +773,7 @@ } /** - * Provided we {@link #supportsInsertSelectIdentity}, then attch the + * Provided we {@link #supportsInsertSelectIdentity}, then attach the * "select identity" clause to the insert statement. *

* Note, if {@link #supportsInsertSelectIdentity} == false then @@ -526,7 +789,7 @@ /** * Get the select command to use to retrieve the last generated IDENTITY - * value for a particuar table + * value for a particular table * * @param table The table into which the insert was done * @param column The PK column. @@ -546,7 +809,7 @@ * @throws MappingException If IDENTITY generation is not supported. */ protected String getIdentitySelectString() throws MappingException { - throw new MappingException( "Dialect does not support identity key generation" ); + throw new MappingException( getClass().getName() + " does not support identity key generation" ); } /** @@ -568,7 +831,7 @@ * @throws MappingException If IDENTITY generation is not supported. */ protected String getIdentityColumnString() throws MappingException { - throw new MappingException( "Dialect does not support identity key generation" ); + throw new MappingException( getClass().getName() + " does not support identity key generation" ); } /** @@ -606,7 +869,7 @@ } /** - * Generate the appropriate select statement to to retreive the next value + * Generate the appropriate select statement to to retrieve the next value * of a sequence. *

* This should be a "stand alone" select statement. @@ -616,11 +879,11 @@ * @throws MappingException If sequences are not supported. */ public String getSequenceNextValString(String sequenceName) throws MappingException { - throw new MappingException( "Dialect does not support sequences" ); + throw new MappingException( getClass().getName() + " does not support sequences" ); } /** - * Generate the select expression fragment that will retreive the next + * Generate the select expression fragment that will retrieve the next * value of a sequence as part of another (typically DML) statement. *

* This differs from {@link #getSequenceNextValString(String)} in that this @@ -631,7 +894,7 @@ * @throws MappingException If sequences are not supported. */ public String getSelectSequenceNextValString(String sequenceName) throws MappingException { - throw new MappingException( "Dialect does not support sequences" ); + throw new MappingException( getClass().getName() + " does not support sequences" ); } /** @@ -642,6 +905,7 @@ * @throws MappingException If sequences are not supported. * @deprecated Use {@link #getCreateSequenceString(String, int, int)} instead */ + @Deprecated public String[] getCreateSequenceStrings(String sequenceName) throws MappingException { return new String[] { getCreateSequenceString( sequenceName ) }; } @@ -674,7 +938,7 @@ * @throws MappingException If sequences are not supported. */ protected String getCreateSequenceString(String sequenceName) throws MappingException { - throw new MappingException( "Dialect does not support sequences" ); + throw new MappingException( getClass().getName() + " does not support sequences" ); } /** @@ -698,7 +962,7 @@ if ( supportsPooledSequences() ) { return getCreateSequenceString( sequenceName ) + " start with " + initialValue + " increment by " + incrementSize; } - throw new MappingException( "Dialect does not support pooled sequences" ); + throw new MappingException( getClass().getName() + " does not support pooled sequences" ); } /** @@ -727,7 +991,7 @@ * @throws MappingException If sequences are not supported. */ protected String getDropSequenceString(String sequenceName) throws MappingException { - throw new MappingException( "Dialect does not support sequences" ); + throw new MappingException( getClass().getName() + " does not support sequences" ); } /** @@ -751,7 +1015,7 @@ * @return The appropriate command. */ public String getSelectGUIDString() { - throw new UnsupportedOperationException( "dialect does not support GUIDs" ); + throw new UnsupportedOperationException( getClass().getName() + " does not support GUIDs" ); } @@ -762,7 +1026,9 @@ * via a SQL clause? * * @return True if this dialect supports some form of LIMIT. + * @deprecated {@link #buildLimitHandler(String, RowSelection)} should be overridden instead. */ + @Deprecated public boolean supportsLimit() { return false; } @@ -772,17 +1038,21 @@ * support specifying an offset? * * @return True if the dialect supports an offset within the limit support. + * @deprecated {@link #buildLimitHandler(String, RowSelection)} should be overridden instead. */ + @Deprecated public boolean supportsLimitOffset() { return supportsLimit(); } /** - * Does this dialect support bind variables (i.e., prepared statememnt + * Does this dialect support bind variables (i.e., prepared statement * parameters) for its limit/offset? * * @return True if bind variables can be used; false otherwise. + * @deprecated {@link #buildLimitHandler(String, RowSelection)} should be overridden instead. */ + @Deprecated public boolean supportsVariableLimit() { return supportsLimit(); } @@ -792,7 +1062,9 @@ * Does this dialect require us to bind the parameters in reverse order? * * @return true if the correct order is limit, offset + * @deprecated {@link #buildLimitHandler(String, RowSelection)} should be overridden instead. */ + @Deprecated public boolean bindLimitParametersInReverseOrder() { return false; } @@ -802,7 +1074,9 @@ * SELECT statement, rather than at the end? * * @return true if limit parameters should come before other parameters + * @deprecated {@link #buildLimitHandler(String, RowSelection)} should be overridden instead. */ + @Deprecated public boolean bindLimitParametersFirst() { return false; } @@ -822,28 +1096,44 @@ * So essentially, is limit relative from offset? Or is limit absolute? * * @return True if limit is relative from offset; false otherwise. + * @deprecated {@link #buildLimitHandler(String, RowSelection)} should be overridden instead. */ + @Deprecated public boolean useMaxForLimit() { return false; } /** + * Generally, if there is no limit applied to a Hibernate query we do not apply any limits + * to the SQL query. This option forces that the limit be written to the SQL query. + * + * @return True to force limit into SQL query even if none specified in Hibernate query; false otherwise. + * @deprecated {@link #buildLimitHandler(String, RowSelection)} should be overridden instead. + */ + @Deprecated + public boolean forceLimitUsage() { + return false; + } + + /** * Given a limit and an offset, apply the limit clause to the query. * * @param query The query to which to apply the limit. * @param offset The offset of the limit * @param limit The limit of the limit ;) * @return The modified query statement with the limit applied. + * @deprecated {@link #buildLimitHandler(String, RowSelection)} should be overridden instead. */ + @Deprecated public String getLimitString(String query, int offset, int limit) { - return getLimitString( query, offset > 0 ); + return getLimitString( query, ( offset > 0 || forceLimitUsage() ) ); } /** * Apply s limit clause to the query. *

* Typically dialects utilize {@link #supportsVariableLimit() variable} - * limit caluses when they support limits. Thus, when building the + * limit clauses when they support limits. Thus, when building the * select command we do not actually need to know the limit or the offest * since we will just be using placeholders. *

@@ -855,15 +1145,75 @@ * @param query The query to which to apply the limit. * @param hasOffset Is the query requesting an offset? * @return the modified SQL + * @deprecated {@link #buildLimitHandler(String, RowSelection)} should be overridden instead. */ + @Deprecated protected String getLimitString(String query, boolean hasOffset) { - throw new UnsupportedOperationException( "paged queries not supported" ); + throw new UnsupportedOperationException( "Paged queries not supported by " + getClass().getName()); } + /** + * Hibernate APIs explicitly state that setFirstResult() should be a zero-based offset. Here we allow the + * Dialect a chance to convert that value based on what the underlying db or driver will expect. + *

+ * NOTE: what gets passed into {@link #getLimitString(String,int,int)} is the zero-based offset. Dialects which + * do not {@link #supportsVariableLimit} should take care to perform any needed first-row-conversion calls prior + * to injecting the limit values into the SQL string. + * + * @param zeroBasedFirstResult The user-supplied, zero-based first row offset. + * @return The corresponding db/dialect specific offset. + * @see org.hibernate.Query#setFirstResult + * @see org.hibernate.Criteria#setFirstResult + * @deprecated {@link #buildLimitHandler(String, RowSelection)} should be overridden instead. + */ + @Deprecated + public int convertToFirstRowValue(int zeroBasedFirstResult) { + return zeroBasedFirstResult; + } + /** + * Build delegate managing LIMIT clause. + * + * @param sql SQL query. + * @param selection Selection criteria. {@code null} in case of unlimited number of rows. + * @return LIMIT clause delegate. + */ + public LimitHandler buildLimitHandler(String sql, RowSelection selection) { + return new LegacyLimitHandler( this, sql, selection ); + } + + // lock acquisition support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** + * Informational metadata about whether this dialect is known to support + * specifying timeouts for requested lock acquisitions. + * + * @return True is this dialect supports specifying lock timeouts. + */ + public boolean supportsLockTimeouts() { + return true; + + } + + /** + * If this dialect supports specifying lock timeouts, are those timeouts + * rendered into the SQL string as parameters. The implication + * is that Hibernate will need to bind the timeout value as a parameter + * in the {@link java.sql.PreparedStatement}. If true, the param position + * is always handled as the last parameter; if the dialect specifies the + * lock timeout elsewhere in the SQL statement then the timeout + * value should be directly rendered into the statement and this method + * should return false. + * + * @return True if the lock timeout is rendered into the SQL + * string as a parameter; false otherwise. + */ + public boolean isLockTimeoutParameterized() { + return false; + } + + /** * Get a strategy instance which knows how to acquire a database-level lock * of the specified mode for this dialect. * @@ -873,28 +1223,61 @@ * @since 3.2 */ public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { - return new SelectLockingStrategy( lockable, lockMode ); + switch ( lockMode ) { + case PESSIMISTIC_FORCE_INCREMENT: + return new PessimisticForceIncrementLockingStrategy( lockable, lockMode ); + case PESSIMISTIC_WRITE: + return new PessimisticWriteSelectLockingStrategy( lockable, lockMode ); + case PESSIMISTIC_READ: + return new PessimisticReadSelectLockingStrategy( lockable, lockMode ); + case OPTIMISTIC: + return new OptimisticLockingStrategy( lockable, lockMode ); + case OPTIMISTIC_FORCE_INCREMENT: + return new OptimisticForceIncrementLockingStrategy( lockable, lockMode ); + default: + return new SelectLockingStrategy( lockable, lockMode ); + } } /** + * Given LockOptions (lockMode, timeout), determine the appropriate for update fragment to use. + * + * @param lockOptions contains the lock mode to apply. + * @return The appropriate for update fragment. + */ + public String getForUpdateString(LockOptions lockOptions) { + final LockMode lockMode = lockOptions.getLockMode(); + return getForUpdateString( lockMode, lockOptions.getTimeOut() ); + } + + @SuppressWarnings( {"deprecation"}) + private String getForUpdateString(LockMode lockMode, int timeout){ + switch ( lockMode ) { + case UPGRADE: + return getForUpdateString(); + case PESSIMISTIC_READ: + return getReadLockString( timeout ); + case PESSIMISTIC_WRITE: + return getWriteLockString( timeout ); + case UPGRADE_NOWAIT: + case FORCE: + case PESSIMISTIC_FORCE_INCREMENT: + return getForUpdateNowaitString(); + case UPGRADE_SKIPLOCKED: + return getForUpdateSkipLockedString(); + default: + return ""; + } + } + + /** * Given a lock mode, determine the appropriate for update fragment to use. * * @param lockMode The lock mode to apply. * @return The appropriate for update fragment. */ public String getForUpdateString(LockMode lockMode) { - if ( lockMode==LockMode.UPGRADE ) { - return getForUpdateString(); - } - else if ( lockMode==LockMode.UPGRADE_NOWAIT ) { - return getForUpdateNowaitString(); - } - else if ( lockMode==LockMode.FORCE ) { - return getForUpdateNowaitString(); - } - else { - return ""; - } + return getForUpdateString( lockMode, LockOptions.WAIT_FOREVER ); } /** @@ -908,6 +1291,31 @@ } /** + * Get the string to append to SELECT statements to acquire WRITE locks + * for this dialect. Location of the of the returned string is treated + * the same as getForUpdateString. + * + * @param timeout in milliseconds, -1 for indefinite wait and 0 for no wait. + * @return The appropriate LOCK clause string. + */ + public String getWriteLockString(int timeout) { + return getForUpdateString(); + } + + /** + * Get the string to append to SELECT statements to acquire WRITE locks + * for this dialect. Location of the of the returned string is treated + * the same as getForUpdateString. + * + * @param timeout in milliseconds, -1 for indefinite wait and 0 for no wait. + * @return The appropriate LOCK clause string. + */ + public String getReadLockString(int timeout) { + return getForUpdateString(); + } + + + /** * Is FOR UPDATE OF syntax supported? * * @return True if the database supports FOR UPDATE OF syntax; @@ -942,6 +1350,30 @@ } /** + * Get the FOR UPDATE OF column_list fragment appropriate for this + * dialect given the aliases of the columns to be write locked. + * + * @param aliases The columns to be write locked. + * @param lockOptions the lock options to apply + * @return The appropriate FOR UPDATE OF column_list clause string. + */ + @SuppressWarnings({"unchecked", "UnusedParameters"}) + public String getForUpdateString(String aliases, LockOptions lockOptions) { + LockMode lockMode = lockOptions.getLockMode(); + final Iterator> itr = lockOptions.getAliasLockIterator(); + while ( itr.hasNext() ) { + // seek the highest lock mode + final Map.Entryentry = itr.next(); + final LockMode lm = entry.getValue(); + if ( lm.greaterThan( lockMode ) ) { + lockMode = lm; + } + } + lockOptions.setLockMode( lockMode ); + return getForUpdateString( lockOptions ); + } + + /** * Retrieves the FOR UPDATE NOWAIT syntax specific to this dialect. * * @return The appropriate FOR UPDATE NOWAIT clause string. @@ -952,17 +1384,38 @@ } /** + * Retrieves the FOR UPDATE SKIP LOCKED syntax specific to this dialect. + * + * @return The appropriate FOR UPDATE SKIP LOCKED clause string. + */ + public String getForUpdateSkipLockedString() { + // by default we report no support for SKIP_LOCKED lock semantics + return getForUpdateString(); + } + + /** * Get the FOR UPDATE OF column_list NOWAIT fragment appropriate * for this dialect given the aliases of the columns to be write locked. * * @param aliases The columns to be write locked. - * @return The appropriate FOR UPDATE colunm_list NOWAIT clause string. + * @return The appropriate FOR UPDATE OF colunm_list NOWAIT clause string. */ public String getForUpdateNowaitString(String aliases) { return getForUpdateString( aliases ); } /** + * Get the FOR UPDATE OF column_list SKIP LOCKED fragment appropriate + * for this dialect given the aliases of the columns to be write locked. + * + * @param aliases The columns to be write locked. + * @return The appropriate FOR UPDATE colunm_list SKIP LOCKED clause string. + */ + public String getForUpdateSkipLockedString(String aliases) { + return getForUpdateString( aliases ); + } + + /** * Some dialects support an alternative means to SELECT FOR UPDATE, * whereby a "lock hint" is appends to the table name in the from clause. *

@@ -971,8 +1424,23 @@ * @param mode The lock mode to apply * @param tableName The name of the table to which to apply the lock hint. * @return The table with any required lock hints. + * @deprecated use {@code appendLockHint(LockOptions,String)} instead */ + @Deprecated public String appendLockHint(LockMode mode, String tableName) { + return appendLockHint( new LockOptions( mode ), tableName ); + } + /** + * Some dialects support an alternative means to SELECT FOR UPDATE, + * whereby a "lock hint" is appends to the table name in the from clause. + *

+ * contributed by Helge Schulz + * + * @param lockOptions The lock options to apply + * @param tableName The name of the table to which to apply the lock hint. + * @return The table with any required lock hints. + */ + public String appendLockHint(LockOptions lockOptions, String tableName){ return tableName; } @@ -985,12 +1453,12 @@ * SELECT FOR UPDATE to achieve this in their own fashion. * * @param sql the SQL string to modify - * @param aliasedLockModes a map of lock modes indexed by aliased table names. + * @param aliasedLockOptions lock options indexed by aliased table names. * @param keyColumnNames a map of key columns indexed by aliased table names. * @return the modified SQL string. */ - public String applyLocksToSql(String sql, Map aliasedLockModes, Map keyColumnNames) { - return sql + new ForUpdateFragment( this, aliasedLockModes, keyColumnNames ).toFragmentString(); + public String applyLocksToSql(String sql, LockOptions aliasedLockOptions, Map keyColumnNames) { + return sql + new ForUpdateFragment( this, aliasedLockOptions, keyColumnNames ).toFragmentString(); } @@ -1032,7 +1500,7 @@ } /** - * Generate a temporary table name given the bas table. + * Generate a temporary table name given the base table. * * @param baseTableName The table name from which to base the temp table name. * @return The generated temp table name. @@ -1061,6 +1529,15 @@ } /** + * Command used to drop a temporary table. + * + * @return The command used to drop a temporary table. + */ + public String getDropTemporaryTableString() { + return "drop table"; + } + + /** * Does the dialect require that temporary table DDL statements occur in * isolation from other statements? This would be the case if the creation * would cause any current transaction to get committed implicitly. @@ -1080,7 +1557,7 @@ *

  • null - defer to the JDBC driver response in regards to * {@link java.sql.DatabaseMetaData#dataDefinitionCausesTransactionCommit()}
  • * - * + * * @return see the result matrix above. */ public Boolean performTemporaryTableDDLInIsolation() { @@ -1100,23 +1577,45 @@ // callable statement support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** - * Registers an OUT parameter which will be returing a - * {@link java.sql.ResultSet}. How this is accomplished varies greatly - * from DB to DB, hence its inclusion (along with {@link #getResultSet}) here. + * Registers a parameter (either OUT, or the new REF_CURSOR param type available in Java 8) capable of + * returning {@link java.sql.ResultSet} *by position*. Pre-Java 8, registering such ResultSet-returning + * parameters varied greatly across database and drivers; hence its inclusion as part of the Dialect contract. * * @param statement The callable statement. - * @param position The bind position at which to register the OUT param. + * @param position The bind position at which to register the output param. + * * @return The number of (contiguous) bind positions used. - * @throws SQLException Indicates problems registering the OUT param. + * + * @throws SQLException Indicates problems registering the param. */ public int registerResultSetOutParameter(CallableStatement statement, int position) throws SQLException { throw new UnsupportedOperationException( getClass().getName() + - " does not support resultsets via stored procedures" - ); + " does not support resultsets via stored procedures" + ); } /** + * Registers a parameter (either OUT, or the new REF_CURSOR param type available in Java 8) capable of + * returning {@link java.sql.ResultSet} *by name*. Pre-Java 8, registering such ResultSet-returning + * parameters varied greatly across database and drivers; hence its inclusion as part of the Dialect contract. + * + * @param statement The callable statement. + * @param name The parameter name (for drivers which support named parameters). + * + * @return The number of (contiguous) bind positions used. + * + * @throws SQLException Indicates problems registering the param. + */ + @SuppressWarnings("UnusedParameters") + public int registerResultSetOutParameter(CallableStatement statement, String name) throws SQLException { + throw new UnsupportedOperationException( + getClass().getName() + + " does not support resultsets via stored procedures" + ); + } + + /** * Given a callable statement previously processed by {@link #registerResultSetOutParameter}, * extract the {@link java.sql.ResultSet} from the OUT parameter. * @@ -1126,11 +1625,46 @@ */ public ResultSet getResultSet(CallableStatement statement) throws SQLException { throw new UnsupportedOperationException( - getClass().getName() + - " does not support resultsets via stored procedures" - ); + getClass().getName() + " does not support resultsets via stored procedures" + ); } + /** + * Given a callable statement previously processed by {@link #registerResultSetOutParameter}, + * extract the {@link java.sql.ResultSet}. + * + * @param statement The callable statement. + * @param position The bind position at which to register the output param. + * + * @return The extracted result set. + * + * @throws SQLException Indicates problems extracting the result set. + */ + @SuppressWarnings("UnusedParameters") + public ResultSet getResultSet(CallableStatement statement, int position) throws SQLException { + throw new UnsupportedOperationException( + getClass().getName() + " does not support resultsets via stored procedures" + ); + } + + /** + * Given a callable statement previously processed by {@link #registerResultSetOutParameter}, + * extract the {@link java.sql.ResultSet} from the OUT parameter. + * + * @param statement The callable statement. + * @param name The parameter name (for drivers which support named parameters). + * + * @return The extracted result set. + * + * @throws SQLException Indicates problems extracting the result set. + */ + @SuppressWarnings("UnusedParameters") + public ResultSet getResultSet(CallableStatement statement, String name) throws SQLException { + throw new UnsupportedOperationException( + getClass().getName() + " does not support resultsets via stored procedures" + ); + } + // current timestamp support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** @@ -1146,7 +1680,7 @@ /** * Should the value returned by {@link #getCurrentTimestampSelectString} * be treated as callable. Typically this indicates that JDBC escape - * sytnax is being used... + * syntax is being used... * * @return True if the {@link #getCurrentTimestampSelectString} return * is callable; false otherwise. @@ -1156,7 +1690,7 @@ } /** - * Retrieve the command used to retrieve the current timestammp from the + * Retrieve the command used to retrieve the current timestamp from the * database. * * @return The command. @@ -1181,21 +1715,66 @@ /** * Build an instance of the SQLExceptionConverter preferred by this dialect for - * converting SQLExceptions into Hibernate's JDBCException hierarchy. The default - * Dialect implementation simply returns a converter based on X/Open SQLState codes. + * converting SQLExceptions into Hibernate's JDBCException hierarchy. *

    + * The preferred method is to not override this method; if possible, + * {@link #buildSQLExceptionConversionDelegate()} should be overridden + * instead. + * + * If this method is not overridden, the default SQLExceptionConverter + * implementation executes 3 SQLException converter delegates: + *

      + *
    1. a "static" delegate based on the JDBC 4 defined SQLException hierarchy;
    2. + *
    3. the vendor-specific delegate returned by {@link #buildSQLExceptionConversionDelegate()}; + * (it is strongly recommended that specific Dialect implementations + * override {@link #buildSQLExceptionConversionDelegate()})
    4. + *
    5. a delegate that interprets SQLState codes for either X/Open or SQL-2003 codes, + * depending on java.sql.DatabaseMetaData#getSQLStateType
    6. + *
    + *

    + * If this method is overridden, it is strongly recommended that the + * returned {@link SQLExceptionConverter} interpret SQL errors based on + * vendor-specific error codes rather than the SQLState since the + * interpretation is more accurate when using vendor-specific ErrorCodes. + * + * @return The Dialect's preferred SQLExceptionConverter, or null to + * indicate that the default {@link SQLExceptionConverter} should be used. + * + * @see {@link #buildSQLExceptionConversionDelegate()} + * @deprecated {@link #buildSQLExceptionConversionDelegate()} should be + * overridden instead. + */ + @Deprecated + public SQLExceptionConverter buildSQLExceptionConverter() { + return null; + } + + /** + * Build an instance of a {@link SQLExceptionConversionDelegate} for + * interpreting dialect-specific error or SQLState codes. + *

    + * When {@link #buildSQLExceptionConverter} returns null, the default + * {@link SQLExceptionConverter} is used to interpret SQLState and + * error codes. If this method is overridden to return a non-null value, + * the default {@link SQLExceptionConverter} will use the returned + * {@link SQLExceptionConversionDelegate} in addition to the following + * standard delegates: + *

      + *
    1. a "static" delegate based on the JDBC 4 defined SQLException hierarchy;
    2. + *
    3. a delegate that interprets SQLState codes for either X/Open or SQL-2003 codes, + * depending on java.sql.DatabaseMetaData#getSQLStateType
    4. + *
    + *

    * It is strongly recommended that specific Dialect implementations override this * method, since interpretation of a SQL error is much more accurate when based on - * the ErrorCode rather than the SQLState. Unfortunately, the ErrorCode is a vendor- - * specific approach. + * the a vendor-specific ErrorCode rather than the SQLState. + *

    + * Specific Dialects may override to return whatever is most appropriate for that vendor. * - * @return The Dialect's preferred SQLExceptionConverter. + * @return The SQLExceptionConversionDelegate for this dialect */ - public SQLExceptionConverter buildSQLExceptionConverter() { - // The default SQLExceptionConverter for all dialects is based on SQLState - // since SQLErrorCode is extremely vendor-specific. Specific Dialects - // may override to return whatever is most appropriate for that vendor. - return new SQLStateConverter( getViolatedConstraintNameExtracter() ); + public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() { + return null; } private static final ViolatedConstraintNameExtracter EXTRACTER = new ViolatedConstraintNameExtracter() { @@ -1282,6 +1861,25 @@ } /** + * The name of the SQL function that can do case insensitive like comparison. + * + * @return The dialect-specific "case insensitive" like function. + */ + public String getCaseInsensitiveLike(){ + return "like"; + } + + /** + * Does this dialect support case insensitive LIKE restrictions? + * + * @return {@code true} if the underlying database supports case insensitive like comparison, + * {@code false} otherwise. The default is {@code false}. + */ + public boolean supportsCaseInsensitiveLike(){ + return false; + } + + /** * Meant as a means for end users to affect the select strings being sent * to the database and perhaps manipulate them in some fashion. *

    @@ -1297,6 +1895,11 @@ /** * What is the maximum length Hibernate can use for generated aliases? + *

    + * The maximum here should account for the fact that Hibernate often needs to append "uniqueing" information + * to the end of generated aliases. That "uniqueing" information will be added to the end of a identifier + * generated to the length specified here; so be sure to leave some room (generally speaking 5 positions will + * suffice). * * @return The maximum length. */ @@ -1341,24 +1944,50 @@ * By default, the incoming value is checked to see if its first character * is the back-tick (`). If so, the dialect specific quoting is applied. * - * @param column The value to be quoted. + * @param name The value to be quoted. * @return The quoted (or unmodified, if not starting with back-tick) value. * @see #openQuote() * @see #closeQuote() */ - public final String quote(String column) { - if ( column.charAt( 0 ) == '`' ) { - return openQuote() + column.substring( 1, column.length() - 1 ) + closeQuote(); + public final String quote(String name) { + if ( name == null ) { + return null; } + + if ( name.charAt( 0 ) == '`' ) { + return openQuote() + name.substring( 1, name.length() - 1 ) + closeQuote(); + } else { - return column; + return name; } } // DDL support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** + * Get the SQL command used to create the named schema + * + * @param schemaName The name of the schema to be created. + * + * @return The creation command + */ + public String getCreateSchemaCommand(String schemaName) { + return "create schema " + schemaName; + } + + /** + * Get the SQL command used to drop the named schema + * + * @param schemaName The name of the schema to be dropped. + * + * @return The drop command + */ + public String getDropSchemaCommand(String schemaName) { + return "drop schema " + schemaName; + } + + /** * Does this dialect support the ALTER TABLE syntax? * * @return True if we support altering of tables; false otherwise. @@ -1387,29 +2016,21 @@ } /** - * Does this dialect support the UNIQUE column syntax? + * The syntax used to add a column to a table (optional). * - * @return boolean + * @return The "add column" fragment. */ - public boolean supportsUnique() { - return true; + public String getAddColumnString() { + throw new UnsupportedOperationException( "No add column syntax supported by " + getClass().getName() ); } - /** - * Does this dialect support adding Unique constraints via create and alter table ? - * @return boolean - */ - public boolean supportsUniqueConstraintInCreateAlterTable() { - return true; - } - /** - * The syntax used to add a column to a table (optional). + * The syntax for the suffix used to add a column to a table (optional). * - * @return The "add column" fragment. + * @return The suffix "add column" fragment. */ - public String getAddColumnString() { - throw new UnsupportedOperationException( "No add column syntax supported by Dialect" ); + public String getAddColumnSuffixString() { + return ""; } public String getDropForeignKeyString() { @@ -1440,10 +2061,10 @@ String referencedTable, String[] primaryKey, boolean referencesPrimaryKey) { - StringBuffer res = new StringBuffer( 30 ); + final StringBuilder res = new StringBuilder( 30 ); res.append( " add constraint " ) - .append( constraintName ) + .append( quote( constraintName ) ) .append( " foreign key (" ) .append( StringHelper.join( ", ", foreignKey ) ) .append( ") references " ) @@ -1468,6 +2089,11 @@ return " add constraint " + constraintName + " primary key "; } + /** + * Does the database/driver have bug in deleting rows that refer to other rows being deleted in the same query? + * + * @return {@code true} if the database/driver has this bug + */ public boolean hasSelfReferentialForeignKeyBug() { return false; } @@ -1481,27 +2107,101 @@ return ""; } + /** + * Does this dialect/database support commenting on tables, columns, etc? + * + * @return {@code true} if commenting is supported + */ public boolean supportsCommentOn() { return false; } + /** + * Get the comment into a form supported for table definition. + * + * @param comment The comment to apply + * + * @return The comment fragment + */ public String getTableComment(String comment) { return ""; } + /** + * Get the comment into a form supported for column definition. + * + * @param comment The comment to apply + * + * @return The comment fragment + */ public String getColumnComment(String comment) { return ""; } + /** + * For dropping a table, can the phrase "if exists" be applied before the table name? + *

    + * NOTE : Only one or the other (or neither) of this and {@link #supportsIfExistsAfterTableName} should return true + * + * @return {@code true} if the "if exists" can be applied before the table name + */ public boolean supportsIfExistsBeforeTableName() { return false; } + /** + * For dropping a table, can the phrase "if exists" be applied after the table name? + *

    + * NOTE : Only one or the other (or neither) of this and {@link #supportsIfExistsBeforeTableName} should return true + * + * @return {@code true} if the "if exists" can be applied after the table name + */ public boolean supportsIfExistsAfterTableName() { return false; } /** + * For dropping a constraint with an "alter table", can the phrase "if exists" be applied before the constraint name? + *

    + * NOTE : Only one or the other (or neither) of this and {@link #supportsIfExistsAfterConstraintName} should return true + * + * @return {@code true} if the "if exists" can be applied before the constraint name + */ + public boolean supportsIfExistsBeforeConstraintName() { + return false; + } + + /** + * For dropping a constraint with an "alter table", can the phrase "if exists" be applied after the constraint name? + *

    + * NOTE : Only one or the other (or neither) of this and {@link #supportsIfExistsBeforeConstraintName} should return true + * + * @return {@code true} if the "if exists" can be applied after the constraint name + */ + public boolean supportsIfExistsAfterConstraintName() { + return false; + } + + /** + * Generate a DROP TABLE statement + * + * @param tableName The name of the table to drop + * + * @return The DROP TABLE command + */ + public String getDropTableString(String tableName) { + final StringBuilder buf = new StringBuilder( "drop table " ); + if ( supportsIfExistsBeforeTableName() ) { + buf.append( "if exists " ); + } + buf.append( tableName ).append( getCascadeConstraintsString() ); + if ( supportsIfExistsAfterTableName() ) { + buf.append( " if exists" ); + } + return buf.toString(); + } + + /** * Does this dialect support column-level check constraints? * * @return True if column-level CHECK constraints are supported; false @@ -1521,14 +2221,15 @@ return true; } + /** + * Does this dialect support cascaded delete on foreign key definitions? + * + * @return {@code true} indicates that the dialect does support cascaded delete on foreign keys. + */ public boolean supportsCascadeDelete() { return true; } - public boolean supportsNotNullUnique() { - return true; - } - /** * Completely optional cascading drop clause * @@ -1538,7 +2239,24 @@ return ""; } + /** + * Returns the separator to use for defining cross joins when translating HQL queries. + *

    + * Typically this will be either [ cross join ] or [, ] + *

    + * Note that the spaces are important! + * + * @return The cross join separator + */ + public String getCrossJoinSeparator() { + return " cross join "; + } + public ColumnAliasExtractor getColumnAliasExtractor() { + return ColumnAliasExtractor.COLUMN_LABEL_EXTRACTOR; + } + + // Informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /** @@ -1607,8 +2325,8 @@ } /** - * Does this dialect support parameters within the select clause of - * INSERT ... SELECT ... statements? + * Does this dialect support parameters within the SELECT clause of + * INSERT ... SELECT ... statements? * * @return True if this is supported; false otherwise. * @since 3.2 @@ -1618,6 +2336,57 @@ } /** + * Does this dialect require that references to result variables + * (i.e, select expresssion aliases) in an ORDER BY clause be + * replaced by column positions (1-origin) as defined + * by the select clause? + + * @return true if result variable references in the ORDER BY + * clause should be replaced by column positions; + * false otherwise. + */ + public boolean replaceResultVariableInOrderByClauseWithPosition() { + return false; + } + + /** + * Renders an ordering fragment + * + * @param expression The SQL order expression. In case of {@code @OrderBy} annotation user receives property placeholder + * (e.g. attribute name enclosed in '{' and '}' signs). + * @param collation Collation string in format {@code collate IDENTIFIER}, or {@code null} + * if expression has not been explicitly specified. + * @param order Order direction. Possible values: {@code asc}, {@code desc}, or {@code null} + * if expression has not been explicitly specified. + * @param nulls Nulls precedence. Default value: {@link NullPrecedence#NONE}. + * @return Renders single element of {@code ORDER BY} clause. + */ + public String renderOrderByElement(String expression, String collation, String order, NullPrecedence nulls) { + final StringBuilder orderByElement = new StringBuilder( expression ); + if ( collation != null ) { + orderByElement.append( " " ).append( collation ); + } + if ( order != null ) { + orderByElement.append( " " ).append( order ); + } + if ( nulls != NullPrecedence.NONE ) { + orderByElement.append( " nulls " ).append( nulls.name().toLowerCase() ); + } + return orderByElement.toString(); + } + + /** + * Does this dialect require that parameters appearing in the SELECT clause be wrapped in cast() + * calls to tell the db parser the expected type. + * + * @return True if select clause parameter must be cast()ed + * @since 3.2 + */ + public boolean requiresCastingOfParametersInSelectClause() { + return false; + } + + /** * Does this dialect support asking the result set its positioning * information on forward only cursors. Specifically, in the case of * scrolling fetches, Hibernate needs to use @@ -1681,7 +2450,7 @@ } /** - * Does the dialect support propogating changes to LOB + * Does the dialect support propagating changes to LOB * values back to the database? Talking about mutating the * internal value of the locator as opposed to supplying a new * locator instance... @@ -1703,11 +2472,12 @@ * databases which (1) are not part of the cruise control process * or (2) do not {@link #supportsExpectedLobUsagePattern}. * - * @return True if the changes are propogated back to the + * @return True if the changes are propagated back to the * database; false otherwise. * @since 3.2 */ public boolean supportsLobValueChangePropogation() { + // todo : pretty sure this is the same as the java.sql.DatabaseMetaData.locatorsUpdateCopy method added in JDBC 4, see HHH-6046 return true; } @@ -1779,9 +2549,178 @@ * Does this dialect support using a JDBC bind parameter as an argument * to a function or procedure call? * - * @return True if the database supports accepting bind params as args; false otherwise. + * @return Returns {@code true} if the database supports accepting bind params as args, {@code false} otherwise. The + * default is {@code true}. */ + @SuppressWarnings( {"UnusedDeclaration"}) public boolean supportsBindAsCallableArgument() { return true; } + + /** + * Does this dialect support `count(a,b)`? + * + * @return True if the database supports counting tuples; false otherwise. + */ + public boolean supportsTupleCounts() { + return false; + } + + /** + * Does this dialect support `count(distinct a,b)`? + * + * @return True if the database supports counting distinct tuples; false otherwise. + */ + public boolean supportsTupleDistinctCounts() { + // oddly most database in fact seem to, so true is the default. + return true; + } + + /** + * If {@link #supportsTupleDistinctCounts()} is true, does the Dialect require the tuple to be wrapped with parens? + * + * @return boolean + */ + public boolean requiresParensForTupleDistinctCounts() { + return false; + } + + /** + * Return the limit that the underlying database places on the number elements in an {@code IN} predicate. + * If the database defines no such limits, simply return zero or less-than-zero. + * + * @return int The limit, or zero-or-less to indicate no limit. + */ + public int getInExpressionCountLimit() { + return 0; + } + + /** + * HHH-4635 + * Oracle expects all Lob values to be last in inserts and updates. + * + * @return boolean True of Lob values should be last, false if it + * does not matter. + */ + public boolean forceLobAsLastValue() { + return false; + } + + /** + * Some dialects have trouble applying pessimistic locking depending upon what other query options are + * specified (paging, ordering, etc). This method allows these dialects to request that locking be applied + * by subsequent selects. + * + * @return {@code true} indicates that the dialect requests that locking be applied by subsequent select; + * {@code false} (the default) indicates that locking should be applied to the main SQL statement.. + */ + public boolean useFollowOnLocking() { + return false; + } + + /** + * Negate an expression + * + * @param expression The expression to negate + * + * @return The negated expression + */ + public String getNotExpression(String expression) { + return "not " + expression; + } + + /** + * Get the UniqueDelegate supported by this dialect + * + * @return The UniqueDelegate + */ + public UniqueDelegate getUniqueDelegate() { + return uniqueDelegate; + } + + /** + * Does this dialect support the UNIQUE column syntax? + * + * @return boolean + * + * @deprecated {@link #getUniqueDelegate()} should be overridden instead. + */ + @Deprecated + public boolean supportsUnique() { + return true; + } + + /** + * Does this dialect support adding Unique constraints via create and alter table ? + * + * @return boolean + * + * @deprecated {@link #getUniqueDelegate()} should be overridden instead. + */ + @Deprecated + public boolean supportsUniqueConstraintInCreateAlterTable() { + return true; + } + + /** + * The syntax used to add a unique constraint to a table. + * + * @param constraintName The name of the unique constraint. + * @return The "add unique" fragment + * + * @deprecated {@link #getUniqueDelegate()} should be overridden instead. + */ + @Deprecated + public String getAddUniqueConstraintString(String constraintName) { + return " add constraint " + constraintName + " unique "; + } + + /** + * Is the combination of not-null and unique supported? + * + * @return deprecated + * + * @deprecated {@link #getUniqueDelegate()} should be overridden instead. + */ + @Deprecated + public boolean supportsNotNullUnique() { + return true; + } + + /** + * Apply a hint to the query. The entire query is provided, allowing the Dialect full control over the placement + * and syntax of the hint. By default, ignore the hint and simply return the query. + * + * @param query The query to which to apply the hint. + * @param hints The hints to apply + * @return The modified SQL + */ + public String getQueryHintString(String query, List hints) { + return query; + } + + /** + * Certain dialects support a subset of ScrollModes. Provide a default to be used by Criteria and Query. + * + * @return ScrollMode + */ + public ScrollMode defaultScrollMode() { + return ScrollMode.SCROLL_INSENSITIVE; + } + + /** + * Does this dialect support tuples in subqueries? Ex: + * delete from Table1 where (col1, col2) in (select col1, col2 from Table2) + * + * @return boolean + */ + public boolean supportsTuplesInSubqueries() { + return true; + } + + public CallableStatementSupport getCallableStatementSupport() { + // most databases do not support returning cursors (ref_cursor)... + return StandardCallableStatementSupport.NO_REF_CURSOR_INSTANCE; + } + } Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/DialectFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/FirebirdDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/FirebirdDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/FirebirdDialect.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/FirebirdDialect.java 30 Jul 2014 16:15:55 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,33 +20,35 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; /** * An SQL dialect for Firebird. + * * @author Reha CENANI */ public class FirebirdDialect extends InterbaseDialect { - + @Override public String getDropSequenceString(String sequenceName) { return "drop generator " + sequenceName; } + @Override public String getLimitString(String sql, boolean hasOffset) { - return new StringBuffer( sql.length()+20 ) - .append(sql) - .insert(6, hasOffset ? " first ? skip ?" : " first ?") - .toString(); + return new StringBuilder( sql.length() + 20 ) + .append( sql ) + .insert( 6, hasOffset ? " first ? skip ?" : " first ?" ) + .toString(); } + @Override public boolean bindLimitParametersFirst() { return true; } + @Override public boolean bindLimitParametersInReverseOrder() { return true; } - -} \ No newline at end of file +} Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/FrontBaseDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/FrontBaseDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/FrontBaseDialect.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/FrontBaseDialect.java 30 Jul 2014 16:15:51 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,18 +20,21 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; +import java.sql.Types; +import org.hibernate.LockMode; import org.hibernate.dialect.lock.LockingStrategy; -import org.hibernate.dialect.lock.UpdateLockingStrategy; +import org.hibernate.dialect.lock.OptimisticForceIncrementLockingStrategy; +import org.hibernate.dialect.lock.OptimisticLockingStrategy; +import org.hibernate.dialect.lock.PessimisticForceIncrementLockingStrategy; +import org.hibernate.dialect.lock.PessimisticReadUpdateLockingStrategy; +import org.hibernate.dialect.lock.PessimisticWriteUpdateLockingStrategy; import org.hibernate.dialect.lock.SelectLockingStrategy; +import org.hibernate.dialect.lock.UpdateLockingStrategy; import org.hibernate.persister.entity.Lockable; -import org.hibernate.LockMode; -import java.sql.Types; - /** * An SQL Dialect for Frontbase. Assumes you're using the latest version * of the FrontBase JDBC driver, available from http://frontbase.com/ @@ -50,6 +53,9 @@ */ public class FrontBaseDialect extends Dialect { + /** + * Constructs a FrontBaseDialect + */ public FrontBaseDialect() { super(); @@ -71,40 +77,61 @@ registerColumnType( Types.CLOB, "clob" ); } + @Override public String getAddColumnString() { return "add column"; } + @Override public String getCascadeConstraintsString() { return " cascade"; } + @Override public boolean dropConstraints() { return false; } /** - * Does this dialect support the FOR UPDATE syntax. No! - * - * @return false always. FrontBase doesn't support this syntax, - * which was dropped with SQL92 + * FrontBase doesn't support this syntax, which was dropped with SQL92. + *

    + * {@inheritDoc} */ + @Override public String getForUpdateString() { return ""; } - public String getCurrentTimestampCallString() { + @Override + public String getCurrentTimestampSelectString() { // TODO : not sure this is correct, could not find docs on how to do this. return "{?= call current_timestamp}"; } + @Override public boolean isCurrentTimestampSelectStringCallable() { return true; } + @Override public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { // Frontbase has no known variation of a "SELECT ... FOR UPDATE" syntax... - if ( lockMode.greaterThan( LockMode.READ ) ) { + if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) { + return new PessimisticForceIncrementLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.PESSIMISTIC_WRITE) { + return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.PESSIMISTIC_READ) { + return new PessimisticReadUpdateLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.OPTIMISTIC) { + return new OptimisticLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) { + return new OptimisticForceIncrementLockingStrategy( lockable, lockMode); + } + else if ( lockMode.greaterThan( LockMode.READ ) ) { return new UpdateLockingStrategy( lockable, lockMode ); } else { Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/H2Dialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/H2Dialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/H2Dialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/H2Dialect.java 30 Jul 2014 16:15:54 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,303 +20,411 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; import java.sql.SQLException; import java.sql.Types; -import org.hibernate.Hibernate; -import org.hibernate.cfg.Environment; +import org.hibernate.JDBCException; +import org.hibernate.PessimisticLockException; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.dialect.function.AvgWithArgumentCastFunction; import org.hibernate.dialect.function.NoArgSQLFunction; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.VarArgsSQLFunction; -import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter; -import org.hibernate.exception.ViolatedConstraintNameExtracter; -import org.hibernate.util.ReflectHelper; +import org.hibernate.exception.ConstraintViolationException; +import org.hibernate.exception.LockAcquisitionException; +import org.hibernate.exception.spi.SQLExceptionConversionDelegate; +import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter; +import org.hibernate.exception.spi.ViolatedConstraintNameExtracter; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.JdbcExceptionHelper; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.type.StandardBasicTypes; +import org.jboss.logging.Logger; + /** * A dialect compatible with the H2 database. - * - * @author Thomas Mueller * + * @author Thomas Mueller */ public class H2Dialect extends Dialect { + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + H2Dialect.class.getName() + ); - private String querySequenceString; - public H2Dialect() { - super(); - - querySequenceString = "select sequence_name from information_schema.sequences"; - try { - // HHH-2300 - Class constants = ReflectHelper.classForName( "org.h2.engine.Constants" ); - Integer build = (Integer)constants.getDeclaredField("BUILD_ID" ).get(null); - int buildid = build.intValue(); - if(buildid < 32) { - querySequenceString = "select name from information_schema.sequences"; - } - } catch(Throwable e) { - // ignore (probably H2 not in the classpath) - } - registerColumnType(Types.BOOLEAN, "boolean"); - registerColumnType(Types.BIGINT, "bigint"); - registerColumnType(Types.BINARY, "binary"); - registerColumnType(Types.BIT, "bit"); - registerColumnType(Types.CHAR, "char($l)"); - registerColumnType(Types.DATE, "date"); - registerColumnType(Types.DECIMAL, "decimal($p,$s)"); - registerColumnType(Types.DOUBLE, "double"); - registerColumnType(Types.FLOAT, "float"); - registerColumnType(Types.INTEGER, "integer"); - registerColumnType(Types.LONGVARBINARY, "longvarbinary"); - registerColumnType(Types.LONGVARCHAR, "longvarchar"); - registerColumnType(Types.REAL, "real"); - registerColumnType(Types.SMALLINT, "smallint"); - registerColumnType(Types.TINYINT, "tinyint"); - registerColumnType(Types.TIME, "time"); - registerColumnType(Types.TIMESTAMP, "timestamp"); - registerColumnType(Types.VARCHAR, "varchar($l)"); - registerColumnType(Types.VARBINARY, "binary($l)"); - registerColumnType(Types.NUMERIC, "numeric"); - registerColumnType(Types.BLOB, "blob"); - registerColumnType(Types.CLOB, "clob"); - - // select topic, syntax from information_schema.help - // where section like 'Function%' order by section, topic + private final String querySequenceString; -// registerFunction("abs", new StandardSQLFunction("abs")); - registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE)); - registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE)); - registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE)); - registerFunction("atan2", new StandardSQLFunction("atan2", Hibernate.DOUBLE)); - registerFunction("bitand", new StandardSQLFunction("bitand", Hibernate.INTEGER)); - registerFunction("bitor", new StandardSQLFunction("bitor", Hibernate.INTEGER)); - registerFunction("bitxor", new StandardSQLFunction("bitxor", Hibernate.INTEGER)); - registerFunction("ceiling", new StandardSQLFunction("ceiling", Hibernate.DOUBLE)); - registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE)); - registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE)); - registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE)); - registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE)); - registerFunction("floor", new StandardSQLFunction("floor", Hibernate.DOUBLE)); - registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE)); - registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE)); -// registerFunction("mod", new StandardSQLFunction("mod", Hibernate.INTEGER)); - registerFunction("pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE)); - registerFunction("power", new StandardSQLFunction("power", Hibernate.DOUBLE)); - registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE)); - registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE)); - registerFunction("round", new StandardSQLFunction("round", Hibernate.DOUBLE)); - registerFunction("roundmagic", new StandardSQLFunction("roundmagic", Hibernate.DOUBLE)); - registerFunction("sign", new StandardSQLFunction("sign", Hibernate.INTEGER)); - registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE)); -// registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE)); - registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE)); - registerFunction("truncate", new StandardSQLFunction("truncate", Hibernate.DOUBLE)); + /** + * Constructs a H2Dialect + */ + public H2Dialect() { + super(); - registerFunction("compress", new StandardSQLFunction("compress", Hibernate.BINARY)); - registerFunction("expand", new StandardSQLFunction("compress", Hibernate.BINARY)); - registerFunction("decrypt", new StandardSQLFunction("decrypt", Hibernate.BINARY)); - registerFunction("encrypt", new StandardSQLFunction("encrypt", Hibernate.BINARY)); - registerFunction("hash", new StandardSQLFunction("hash", Hibernate.BINARY)); + String querySequenceString = "select sequence_name from information_schema.sequences"; + try { + // HHH-2300 + final Class h2ConstantsClass = ReflectHelper.classForName( "org.h2.engine.Constants" ); + final int majorVersion = (Integer) h2ConstantsClass.getDeclaredField( "VERSION_MAJOR" ).get( null ); + final int minorVersion = (Integer) h2ConstantsClass.getDeclaredField( "VERSION_MINOR" ).get( null ); + final int buildId = (Integer) h2ConstantsClass.getDeclaredField( "BUILD_ID" ).get( null ); + if ( buildId < 32 ) { + querySequenceString = "select name from information_schema.sequences"; + } + if ( ! ( majorVersion > 1 || minorVersion > 2 || buildId >= 139 ) ) { + LOG.unsupportedMultiTableBulkHqlJpaql( majorVersion, minorVersion, buildId ); + } + } + catch ( Exception e ) { + // probably H2 not in the classpath, though in certain app server environments it might just mean we are + // not using the correct classloader + LOG.undeterminedH2Version(); + } - registerFunction("ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER)); -// registerFunction("bit_length", new StandardSQLFunction("bit_length", Hibernate.INTEGER)); - registerFunction("char", new StandardSQLFunction("char", Hibernate.CHARACTER)); - registerFunction("concat", new VarArgsSQLFunction(Hibernate.STRING, "(", "||", ")")); - registerFunction("difference", new StandardSQLFunction("difference", Hibernate.INTEGER)); - registerFunction("hextoraw", new StandardSQLFunction("hextoraw", Hibernate.STRING)); - registerFunction("lower", new StandardSQLFunction("lower", Hibernate.STRING)); - registerFunction("insert", new StandardSQLFunction("lower", Hibernate.STRING)); - registerFunction("left", new StandardSQLFunction("left", Hibernate.STRING)); -// registerFunction("length", new StandardSQLFunction("length", Hibernate.INTEGER)); -// registerFunction("locate", new StandardSQLFunction("locate", Hibernate.INTEGER)); -// registerFunction("lower", new StandardSQLFunction("lower", Hibernate.STRING)); - registerFunction("lcase", new StandardSQLFunction("lcase", Hibernate.STRING)); - registerFunction("ltrim", new StandardSQLFunction("ltrim", Hibernate.STRING)); - registerFunction("octet_length", new StandardSQLFunction("octet_length", Hibernate.INTEGER)); - registerFunction("position", new StandardSQLFunction("position", Hibernate.INTEGER)); - registerFunction("rawtohex", new StandardSQLFunction("rawtohex", Hibernate.STRING)); - registerFunction("repeat", new StandardSQLFunction("repeat", Hibernate.STRING)); - registerFunction("replace", new StandardSQLFunction("replace", Hibernate.STRING)); - registerFunction("right", new StandardSQLFunction("right", Hibernate.STRING)); - registerFunction("rtrim", new StandardSQLFunction("rtrim", Hibernate.STRING)); - registerFunction("soundex", new StandardSQLFunction("soundex", Hibernate.STRING)); - registerFunction("space", new StandardSQLFunction("space", Hibernate.STRING)); - registerFunction("stringencode", new StandardSQLFunction("stringencode", Hibernate.STRING)); - registerFunction("stringdecode", new StandardSQLFunction("stringdecode", Hibernate.STRING)); -// registerFunction("substring", new StandardSQLFunction("substring", Hibernate.STRING)); -// registerFunction("upper", new StandardSQLFunction("upper", Hibernate.STRING)); - registerFunction("ucase", new StandardSQLFunction("ucase", Hibernate.STRING)); + this.querySequenceString = querySequenceString; - registerFunction("stringtoutf8", new StandardSQLFunction("stringtoutf8", Hibernate.BINARY)); - registerFunction("utf8tostring", new StandardSQLFunction("utf8tostring", Hibernate.STRING)); + registerColumnType( Types.BOOLEAN, "boolean" ); + registerColumnType( Types.BIGINT, "bigint" ); + registerColumnType( Types.BINARY, "binary" ); + registerColumnType( Types.BIT, "boolean" ); + registerColumnType( Types.CHAR, "char($l)" ); + registerColumnType( Types.DATE, "date" ); + registerColumnType( Types.DECIMAL, "decimal($p,$s)" ); + registerColumnType( Types.NUMERIC, "decimal($p,$s)" ); + registerColumnType( Types.DOUBLE, "double" ); + registerColumnType( Types.FLOAT, "float" ); + registerColumnType( Types.INTEGER, "integer" ); + registerColumnType( Types.LONGVARBINARY, "longvarbinary" ); + registerColumnType( Types.LONGVARCHAR, "longvarchar" ); + registerColumnType( Types.REAL, "real" ); + registerColumnType( Types.SMALLINT, "smallint" ); + registerColumnType( Types.TINYINT, "tinyint" ); + registerColumnType( Types.TIME, "time" ); + registerColumnType( Types.TIMESTAMP, "timestamp" ); + registerColumnType( Types.VARCHAR, "varchar($l)" ); + registerColumnType( Types.VARBINARY, "binary($l)" ); + registerColumnType( Types.BLOB, "blob" ); + registerColumnType( Types.CLOB, "clob" ); - registerFunction("current_date", new NoArgSQLFunction("current_date", Hibernate.DATE)); - registerFunction("current_time", new NoArgSQLFunction("current_time", Hibernate.TIME)); - registerFunction("current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP)); - registerFunction("datediff", new StandardSQLFunction("datediff", Hibernate.INTEGER)); - registerFunction("dayname", new StandardSQLFunction("dayname", Hibernate.STRING)); - registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth", Hibernate.INTEGER)); - registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER)); - registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER)); -// registerFunction("hour", new StandardSQLFunction("hour", Hibernate.INTEGER)); -// registerFunction("minute", new StandardSQLFunction("minute", Hibernate.INTEGER)); -// registerFunction("month", new StandardSQLFunction("month", Hibernate.INTEGER)); - registerFunction("monthname", new StandardSQLFunction("monthname", Hibernate.STRING)); - registerFunction("quater", new StandardSQLFunction("quater", Hibernate.INTEGER)); -// registerFunction("second", new StandardSQLFunction("second", Hibernate.INTEGER)); - registerFunction("week", new StandardSQLFunction("week", Hibernate.INTEGER)); -// registerFunction("year", new StandardSQLFunction("year", Hibernate.INTEGER)); + // Aggregations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + registerFunction( "avg", new AvgWithArgumentCastFunction( "double" ) ); - registerFunction("curdate", new NoArgSQLFunction("curdate", Hibernate.DATE)); - registerFunction("curtime", new NoArgSQLFunction("curtime", Hibernate.TIME)); - registerFunction("curtimestamp", new NoArgSQLFunction("curtimestamp", Hibernate.TIME)); - registerFunction("now", new NoArgSQLFunction("now", Hibernate.TIMESTAMP)); + // select topic, syntax from information_schema.help + // where section like 'Function%' order by section, topic + // + // see also -> http://www.h2database.com/html/functions.html - registerFunction("database", new NoArgSQLFunction("database", Hibernate.STRING)); - registerFunction("user", new NoArgSQLFunction("user", Hibernate.STRING)); + // Numeric Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + registerFunction( "acos", new StandardSQLFunction( "acos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "asin", new StandardSQLFunction( "asin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "atan", new StandardSQLFunction( "atan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "atan2", new StandardSQLFunction( "atan2", StandardBasicTypes.DOUBLE ) ); + registerFunction( "bitand", new StandardSQLFunction( "bitand", StandardBasicTypes.INTEGER ) ); + registerFunction( "bitor", new StandardSQLFunction( "bitor", StandardBasicTypes.INTEGER ) ); + registerFunction( "bitxor", new StandardSQLFunction( "bitxor", StandardBasicTypes.INTEGER ) ); + registerFunction( "ceiling", new StandardSQLFunction( "ceiling", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cos", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "compress", new StandardSQLFunction( "compress", StandardBasicTypes.BINARY ) ); + registerFunction( "cot", new StandardSQLFunction( "cot", StandardBasicTypes.DOUBLE ) ); + registerFunction( "decrypt", new StandardSQLFunction( "decrypt", StandardBasicTypes.BINARY ) ); + registerFunction( "degrees", new StandardSQLFunction( "degrees", StandardBasicTypes.DOUBLE ) ); + registerFunction( "encrypt", new StandardSQLFunction( "encrypt", StandardBasicTypes.BINARY ) ); + registerFunction( "exp", new StandardSQLFunction( "exp", StandardBasicTypes.DOUBLE ) ); + registerFunction( "expand", new StandardSQLFunction( "compress", StandardBasicTypes.BINARY ) ); + registerFunction( "floor", new StandardSQLFunction( "floor", StandardBasicTypes.DOUBLE ) ); + registerFunction( "hash", new StandardSQLFunction( "hash", StandardBasicTypes.BINARY ) ); + registerFunction( "log", new StandardSQLFunction( "log", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log10", new StandardSQLFunction( "log10", StandardBasicTypes.DOUBLE ) ); + registerFunction( "pi", new NoArgSQLFunction( "pi", StandardBasicTypes.DOUBLE ) ); + registerFunction( "power", new StandardSQLFunction( "power", StandardBasicTypes.DOUBLE ) ); + registerFunction( "radians", new StandardSQLFunction( "radians", StandardBasicTypes.DOUBLE ) ); + registerFunction( "rand", new NoArgSQLFunction( "rand", StandardBasicTypes.DOUBLE ) ); + registerFunction( "round", new StandardSQLFunction( "round", StandardBasicTypes.DOUBLE ) ); + registerFunction( "roundmagic", new StandardSQLFunction( "roundmagic", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) ); + registerFunction( "sin", new StandardSQLFunction( "sin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "tan", new StandardSQLFunction( "tan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "truncate", new StandardSQLFunction( "truncate", StandardBasicTypes.DOUBLE ) ); - getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE); + // String Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + registerFunction( "ascii", new StandardSQLFunction( "ascii", StandardBasicTypes.INTEGER ) ); + registerFunction( "char", new StandardSQLFunction( "char", StandardBasicTypes.CHARACTER ) ); + registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(", "||", ")" ) ); + registerFunction( "difference", new StandardSQLFunction( "difference", StandardBasicTypes.INTEGER ) ); + registerFunction( "hextoraw", new StandardSQLFunction( "hextoraw", StandardBasicTypes.STRING ) ); + registerFunction( "insert", new StandardSQLFunction( "lower", StandardBasicTypes.STRING ) ); + registerFunction( "left", new StandardSQLFunction( "left", StandardBasicTypes.STRING ) ); + registerFunction( "lcase", new StandardSQLFunction( "lcase", StandardBasicTypes.STRING ) ); + registerFunction( "ltrim", new StandardSQLFunction( "ltrim", StandardBasicTypes.STRING ) ); + registerFunction( "octet_length", new StandardSQLFunction( "octet_length", StandardBasicTypes.INTEGER ) ); + registerFunction( "position", new StandardSQLFunction( "position", StandardBasicTypes.INTEGER ) ); + registerFunction( "rawtohex", new StandardSQLFunction( "rawtohex", StandardBasicTypes.STRING ) ); + registerFunction( "repeat", new StandardSQLFunction( "repeat", StandardBasicTypes.STRING ) ); + registerFunction( "replace", new StandardSQLFunction( "replace", StandardBasicTypes.STRING ) ); + registerFunction( "right", new StandardSQLFunction( "right", StandardBasicTypes.STRING ) ); + registerFunction( "rtrim", new StandardSQLFunction( "rtrim", StandardBasicTypes.STRING ) ); + registerFunction( "soundex", new StandardSQLFunction( "soundex", StandardBasicTypes.STRING ) ); + registerFunction( "space", new StandardSQLFunction( "space", StandardBasicTypes.STRING ) ); + registerFunction( "stringencode", new StandardSQLFunction( "stringencode", StandardBasicTypes.STRING ) ); + registerFunction( "stringdecode", new StandardSQLFunction( "stringdecode", StandardBasicTypes.STRING ) ); + registerFunction( "stringtoutf8", new StandardSQLFunction( "stringtoutf8", StandardBasicTypes.BINARY ) ); + registerFunction( "ucase", new StandardSQLFunction( "ucase", StandardBasicTypes.STRING ) ); + registerFunction( "utf8tostring", new StandardSQLFunction( "utf8tostring", StandardBasicTypes.STRING ) ); - } + // Time and Date Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + registerFunction( "curdate", new NoArgSQLFunction( "curdate", StandardBasicTypes.DATE ) ); + registerFunction( "curtime", new NoArgSQLFunction( "curtime", StandardBasicTypes.TIME ) ); + registerFunction( "curtimestamp", new NoArgSQLFunction( "curtimestamp", StandardBasicTypes.TIME ) ); + registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE ) ); + registerFunction( "current_time", new NoArgSQLFunction( "current_time", StandardBasicTypes.TIME ) ); + registerFunction( "current_timestamp", new NoArgSQLFunction( "current_timestamp", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "datediff", new StandardSQLFunction( "datediff", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayname", new StandardSQLFunction( "dayname", StandardBasicTypes.STRING ) ); + registerFunction( "dayofmonth", new StandardSQLFunction( "dayofmonth", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", StandardBasicTypes.INTEGER ) ); + registerFunction( "monthname", new StandardSQLFunction( "monthname", StandardBasicTypes.STRING ) ); + registerFunction( "now", new NoArgSQLFunction( "now", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "quarter", new StandardSQLFunction( "quarter", StandardBasicTypes.INTEGER ) ); + registerFunction( "week", new StandardSQLFunction( "week", StandardBasicTypes.INTEGER ) ); - public String getAddColumnString() { - return "add column"; - } + // System Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + registerFunction( "database", new NoArgSQLFunction( "database", StandardBasicTypes.STRING ) ); + registerFunction( "user", new NoArgSQLFunction( "user", StandardBasicTypes.STRING ) ); - public boolean supportsIdentityColumns() { - return true; - } + getDefaultProperties().setProperty( AvailableSettings.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE ); + // http://code.google.com/p/h2database/issues/detail?id=235 + getDefaultProperties().setProperty( AvailableSettings.NON_CONTEXTUAL_LOB_CREATION, "true" ); + } - public String getIdentityColumnString() { - return "generated by default as identity"; // not null is implicit - } + @Override + public String getAddColumnString() { + return "add column"; + } - public String getIdentitySelectString() { - return "call identity()"; - } + @Override + public boolean supportsIdentityColumns() { + return true; + } - public String getIdentityInsertString() { - return "null"; - } + @Override + public String getIdentityColumnString() { + // not null is implicit + return "generated by default as identity"; + } - public String getForUpdateString() { - return " for update"; - } + @Override + public String getIdentitySelectString() { + return "call identity()"; + } - public boolean supportsUnique() { - return true; - } + @Override + public String getIdentityInsertString() { + return "null"; + } - public boolean supportsLimit() { - return true; - } + @Override + public String getForUpdateString() { + return " for update"; + } - public String getLimitString(String sql, boolean hasOffset) { - return new StringBuffer(sql.length() + 20). - append(sql). - append(hasOffset ? " limit ? offset ?" : " limit ?"). - toString(); - } - - public boolean bindLimitParametersInReverseOrder() { - return true; - } + @Override + public boolean supportsLimit() { + return true; + } - public boolean bindLimitParametersFirst() { - return false; - } + @Override + public String getLimitString(String sql, boolean hasOffset) { + return sql + (hasOffset ? " limit ? offset ?" : " limit ?"); + } - public boolean supportsIfExistsAfterTableName() { - return true; - } + @Override + public boolean bindLimitParametersInReverseOrder() { + return true; + } - public boolean supportsSequences() { - return true; - } + @Override + public boolean bindLimitParametersFirst() { + return false; + } + @Override + public boolean supportsIfExistsAfterTableName() { + return true; + } + + @Override + public boolean supportsIfExistsAfterConstraintName() { + return true; + } + + @Override + public boolean supportsSequences() { + return true; + } + + @Override public boolean supportsPooledSequences() { return true; } - public String getCreateSequenceString(String sequenceName) { - return "create sequence " + sequenceName; - } + @Override + public String getCreateSequenceString(String sequenceName) { + return "create sequence " + sequenceName; + } - public String getDropSequenceString(String sequenceName) { - return "drop sequence " + sequenceName; - } + @Override + public String getDropSequenceString(String sequenceName) { + return "drop sequence " + sequenceName; + } - public String getSelectSequenceNextValString(String sequenceName) { - return "next value for " + sequenceName; - } + @Override + public String getSelectSequenceNextValString(String sequenceName) { + return "next value for " + sequenceName; + } - public String getSequenceNextValString(String sequenceName) { - return "call next value for " + sequenceName; - } + @Override + public String getSequenceNextValString(String sequenceName) { + return "call next value for " + sequenceName; + } - public String getQuerySequencesString() { - return querySequenceString; - } + @Override + public String getQuerySequencesString() { + return querySequenceString; + } + @Override public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() { - return EXTRACTER; - } + return EXTRACTER; + } - private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { + private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { + /** + * Extract the name of the violated constraint from the given SQLException. + * + * @param sqle The exception that was the result of the constraint violation. + * @return The extracted constraint name. + */ + public String extractConstraintName(SQLException sqle) { + String constraintName = null; + // 23000: Check constraint violation: {0} + // 23001: Unique index or primary key violation: {0} + if ( sqle.getSQLState().startsWith( "23" ) ) { + final String message = sqle.getMessage(); + final int idx = message.indexOf( "violation: " ); + if ( idx > 0 ) { + constraintName = message.substring( idx + "violation: ".length() ); + } + } + return constraintName; + } + }; - /** - * Extract the name of the violated constraint from the given SQLException. - * - * @param sqle The exception that was the result of the constraint violation. - * @return The extracted constraint name. - */ - public String extractConstraintName(SQLException sqle) { - String constraintName = null; - // 23000: Check constraint violation: {0} - // 23001: Unique index or primary key violation: {0} - if(sqle.getSQLState().startsWith("23")) { - String message = sqle.getMessage(); - int idx = message.indexOf("violation: "); - if(idx > 0) { - constraintName = message.substring(idx + "violation: ".length()); - } - } - return constraintName; - } + @Override + public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() { + SQLExceptionConversionDelegate delegate = super.buildSQLExceptionConversionDelegate(); + if (delegate == null) { + delegate = new SQLExceptionConversionDelegate() { + @Override + public JDBCException convert(SQLException sqlException, String message, String sql) { + final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException ); - }; + if (40001 == errorCode) { + // DEADLOCK DETECTED + return new LockAcquisitionException(message, sqlException, sql); + } - public boolean supportsTemporaryTables() { - return true; - } - - public String getCreateTemporaryTableString() { - return "create temporary table if not exists"; - } + if (50200 == errorCode) { + // LOCK NOT AVAILABLE + return new PessimisticLockException(message, sqlException, sql); + } - public boolean supportsCurrentTimestampSelection() { - return true; - } - - public boolean isCurrentTimestampSelectStringCallable() { - return false; - } - - public String getCurrentTimestampSelectString() { - return "call current_timestamp()"; - } - - public boolean supportsUnionAll() { - return true; - } + if ( 90006 == errorCode ) { + // NULL not allowed for column [90006-145] + final String constraintName = getViolatedConstraintNameExtracter().extractConstraintName( sqlException ); + return new ConstraintViolationException( message, sqlException, sql, constraintName ); + } + return null; + } + }; + } + return delegate; + } + @Override + public boolean supportsTemporaryTables() { + return true; + } + + @Override + public String getCreateTemporaryTableString() { + return "create cached local temporary table if not exists"; + } + + @Override + public String getCreateTemporaryTablePostfix() { + // actually 2 different options are specified here: + // 1) [on commit drop] - says to drop the table on transaction commit + // 2) [transactional] - says to not perform an implicit commit of any current transaction + return "on commit drop transactional"; + } + + @Override + public Boolean performTemporaryTableDDLInIsolation() { + // explicitly create the table using the same connection and transaction + return Boolean.FALSE; + } + + @Override + public boolean dropTemporaryTableAfterUse() { + return false; + } + + @Override + public boolean supportsCurrentTimestampSelection() { + return true; + } + + @Override + public boolean isCurrentTimestampSelectStringCallable() { + return false; + } + + @Override + public String getCurrentTimestampSelectString() { + return "call current_timestamp()"; + } + + @Override + public boolean supportsUnionAll() { + return true; + } + + // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public boolean supportsLobValueChangePropogation() { return false; } -} \ No newline at end of file + + @Override + public boolean requiresParensForTupleDistinctCounts() { + return true; + } + + @Override + public boolean doesReadCommittedCauseWritersToBlockReaders() { + // see http://groups.google.com/group/h2-database/browse_thread/thread/562d8a49e2dabe99?hl=en + return true; + } + + @Override + public boolean supportsTuplesInSubqueries() { + return false; + } +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/HANAColumnStoreDialect.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/HANARowStoreDialect.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/HSQLDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/HSQLDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/HSQLDialect.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/HSQLDialect.java 30 Jul 2014 16:15:52 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,52 +20,91 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; +import java.io.Serializable; import java.sql.SQLException; import java.sql.Types; -import java.io.Serializable; -import org.hibernate.Hibernate; +import org.hibernate.JDBCException; import org.hibernate.LockMode; +import org.hibernate.MappingException; import org.hibernate.StaleObjectStateException; -import org.hibernate.JDBCException; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.persister.entity.Lockable; import org.hibernate.cfg.Environment; +import org.hibernate.dialect.function.AvgWithArgumentCastFunction; import org.hibernate.dialect.function.NoArgSQLFunction; +import org.hibernate.dialect.function.SQLFunctionTemplate; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.VarArgsSQLFunction; import org.hibernate.dialect.lock.LockingStrategy; +import org.hibernate.dialect.lock.OptimisticForceIncrementLockingStrategy; +import org.hibernate.dialect.lock.OptimisticLockingStrategy; +import org.hibernate.dialect.lock.PessimisticForceIncrementLockingStrategy; +import org.hibernate.dialect.lock.PessimisticReadSelectLockingStrategy; +import org.hibernate.dialect.lock.PessimisticWriteSelectLockingStrategy; import org.hibernate.dialect.lock.SelectLockingStrategy; -import org.hibernate.exception.JDBCExceptionHelper; -import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter; -import org.hibernate.exception.ViolatedConstraintNameExtracter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter; +import org.hibernate.exception.spi.ViolatedConstraintNameExtracter; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.JdbcExceptionHelper; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.persister.entity.Lockable; +import org.hibernate.type.StandardBasicTypes; +import org.jboss.logging.Logger; + /** - * An SQL dialect compatible with HSQLDB (Hypersonic SQL). + * An SQL dialect compatible with HSQLDB (HyperSQL). *

    * Note this version supports HSQLDB version 1.8 and higher, only. + *

    + * Enhancements to version 3.5.0 GA to provide basic support for both HSQLDB 1.8.x and 2.x + * Does not works with Hibernate 3.2 - 3.4 without alteration. * * @author Christoph Sturm * @author Phillip Baird + * @author Fred Toussi */ +@SuppressWarnings("deprecation") public class HSQLDialect extends Dialect { + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + HSQLDialect.class.getName() + ); - private static final Logger log = LoggerFactory.getLogger( HSQLDialect.class ); + /** + * version is 18 for 1.8 or 20 for 2.0 + */ + private int hsqldbVersion = 18; + + /** + * Constructs a HSQLDialect + */ public HSQLDialect() { super(); + + try { + final Class props = ReflectHelper.classForName( "org.hsqldb.persist.HsqlDatabaseProperties" ); + final String versionString = (String) props.getDeclaredField( "THIS_VERSION" ).get( null ); + + hsqldbVersion = Integer.parseInt( versionString.substring( 0, 1 ) ) * 10; + hsqldbVersion += Integer.parseInt( versionString.substring( 2, 3 ) ); + } + catch ( Throwable e ) { + // must be a very old version + } + registerColumnType( Types.BIGINT, "bigint" ); - registerColumnType( Types.BINARY, "binary" ); + registerColumnType( Types.BINARY, "binary($l)" ); registerColumnType( Types.BIT, "bit" ); - registerColumnType( Types.CHAR, "char(1)" ); + registerColumnType( Types.BOOLEAN, "boolean" ); + registerColumnType( Types.CHAR, "char($l)" ); registerColumnType( Types.DATE, "date" ); - registerColumnType( Types.DECIMAL, "decimal" ); + + registerColumnType( Types.DECIMAL, "decimal($p,$s)" ); registerColumnType( Types.DOUBLE, "double" ); registerColumnType( Types.FLOAT, "float" ); registerColumnType( Types.INTEGER, "integer" ); @@ -77,178 +116,256 @@ registerColumnType( Types.TIMESTAMP, "timestamp" ); registerColumnType( Types.VARCHAR, "varchar($l)" ); registerColumnType( Types.VARBINARY, "varbinary($l)" ); - registerColumnType( Types.NUMERIC, "numeric" ); + + if ( hsqldbVersion < 20 ) { + registerColumnType( Types.NUMERIC, "numeric" ); + } + else { + registerColumnType( Types.NUMERIC, "numeric($p,$s)" ); + } + //HSQL has no Blob/Clob support .... but just put these here for now! - registerColumnType( Types.BLOB, "longvarbinary" ); - registerColumnType( Types.CLOB, "longvarchar" ); + if ( hsqldbVersion < 20 ) { + registerColumnType( Types.BLOB, "longvarbinary" ); + registerColumnType( Types.CLOB, "longvarchar" ); + } + else { + registerColumnType( Types.BLOB, "blob($l)" ); + registerColumnType( Types.CLOB, "clob($l)" ); + } - registerFunction( "ascii", new StandardSQLFunction( "ascii", Hibernate.INTEGER ) ); - registerFunction( "char", new StandardSQLFunction( "char", Hibernate.CHARACTER ) ); - registerFunction( "length", new StandardSQLFunction( "length", Hibernate.LONG ) ); + // aggregate functions + registerFunction( "avg", new AvgWithArgumentCastFunction( "double" ) ); + + // string functions + registerFunction( "ascii", new StandardSQLFunction( "ascii", StandardBasicTypes.INTEGER ) ); + registerFunction( "char", new StandardSQLFunction( "char", StandardBasicTypes.CHARACTER ) ); registerFunction( "lower", new StandardSQLFunction( "lower" ) ); registerFunction( "upper", new StandardSQLFunction( "upper" ) ); registerFunction( "lcase", new StandardSQLFunction( "lcase" ) ); registerFunction( "ucase", new StandardSQLFunction( "ucase" ) ); - registerFunction( "soundex", new StandardSQLFunction( "soundex", Hibernate.STRING ) ); + registerFunction( "soundex", new StandardSQLFunction( "soundex", StandardBasicTypes.STRING ) ); registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) ); registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) ); registerFunction( "reverse", new StandardSQLFunction( "reverse" ) ); - registerFunction( "space", new StandardSQLFunction( "space", Hibernate.STRING ) ); + registerFunction( "space", new StandardSQLFunction( "space", StandardBasicTypes.STRING ) ); + registerFunction( "str", new SQLFunctionTemplate( StandardBasicTypes.STRING, "cast(?1 as varchar(256))" ) ); + registerFunction( "to_char", new StandardSQLFunction( "to_char", StandardBasicTypes.STRING ) ); registerFunction( "rawtohex", new StandardSQLFunction( "rawtohex" ) ); registerFunction( "hextoraw", new StandardSQLFunction( "hextoraw" ) ); - registerFunction( "user", new NoArgSQLFunction( "user", Hibernate.STRING ) ); - registerFunction( "database", new NoArgSQLFunction( "database", Hibernate.STRING ) ); + // system functions + registerFunction( "user", new NoArgSQLFunction( "user", StandardBasicTypes.STRING ) ); + registerFunction( "database", new NoArgSQLFunction( "database", StandardBasicTypes.STRING ) ); - registerFunction( "current_date", new NoArgSQLFunction( "current_date", Hibernate.DATE, false ) ); - registerFunction( "curdate", new NoArgSQLFunction( "curdate", Hibernate.DATE ) ); - registerFunction( "current_timestamp", new NoArgSQLFunction( "current_timestamp", Hibernate.TIMESTAMP, false ) ); - registerFunction( "now", new NoArgSQLFunction( "now", Hibernate.TIMESTAMP ) ); - registerFunction( "current_time", new NoArgSQLFunction( "current_time", Hibernate.TIME, false ) ); - registerFunction( "curtime", new NoArgSQLFunction( "curtime", Hibernate.TIME ) ); - registerFunction( "day", new StandardSQLFunction( "day", Hibernate.INTEGER ) ); - registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", Hibernate.INTEGER ) ); - registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", Hibernate.INTEGER ) ); - registerFunction( "dayofmonth", new StandardSQLFunction( "dayofmonth", Hibernate.INTEGER ) ); - registerFunction( "month", new StandardSQLFunction( "month", Hibernate.INTEGER ) ); - registerFunction( "year", new StandardSQLFunction( "year", Hibernate.INTEGER ) ); - registerFunction( "week", new StandardSQLFunction( "week", Hibernate.INTEGER ) ); - registerFunction( "quater", new StandardSQLFunction( "quater", Hibernate.INTEGER ) ); - registerFunction( "hour", new StandardSQLFunction( "hour", Hibernate.INTEGER ) ); - registerFunction( "minute", new StandardSQLFunction( "minute", Hibernate.INTEGER ) ); - registerFunction( "second", new StandardSQLFunction( "second", Hibernate.INTEGER ) ); - registerFunction( "dayname", new StandardSQLFunction( "dayname", Hibernate.STRING ) ); - registerFunction( "monthname", new StandardSQLFunction( "monthname", Hibernate.STRING ) ); + // datetime functions + if ( hsqldbVersion < 20 ) { + registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.DATE, false ) ); + } + else { + registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.TIMESTAMP, false ) ); + } + registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE, false ) ); + registerFunction( "curdate", new NoArgSQLFunction( "curdate", StandardBasicTypes.DATE ) ); + registerFunction( + "current_timestamp", new NoArgSQLFunction( "current_timestamp", StandardBasicTypes.TIMESTAMP, false ) + ); + registerFunction( "now", new NoArgSQLFunction( "now", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "current_time", new NoArgSQLFunction( "current_time", StandardBasicTypes.TIME, false ) ); + registerFunction( "curtime", new NoArgSQLFunction( "curtime", StandardBasicTypes.TIME ) ); + registerFunction( "day", new StandardSQLFunction( "day", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofmonth", new StandardSQLFunction( "dayofmonth", StandardBasicTypes.INTEGER ) ); + registerFunction( "month", new StandardSQLFunction( "month", StandardBasicTypes.INTEGER ) ); + registerFunction( "year", new StandardSQLFunction( "year", StandardBasicTypes.INTEGER ) ); + registerFunction( "week", new StandardSQLFunction( "week", StandardBasicTypes.INTEGER ) ); + registerFunction( "quarter", new StandardSQLFunction( "quarter", StandardBasicTypes.INTEGER ) ); + registerFunction( "hour", new StandardSQLFunction( "hour", StandardBasicTypes.INTEGER ) ); + registerFunction( "minute", new StandardSQLFunction( "minute", StandardBasicTypes.INTEGER ) ); + registerFunction( "second", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "cast(second(?1) as int)" ) ); + registerFunction( "dayname", new StandardSQLFunction( "dayname", StandardBasicTypes.STRING ) ); + registerFunction( "monthname", new StandardSQLFunction( "monthname", StandardBasicTypes.STRING ) ); + // numeric functions registerFunction( "abs", new StandardSQLFunction( "abs" ) ); - registerFunction( "sign", new StandardSQLFunction( "sign", Hibernate.INTEGER ) ); + registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) ); - registerFunction( "acos", new StandardSQLFunction( "acos", Hibernate.DOUBLE ) ); - registerFunction( "asin", new StandardSQLFunction( "asin", Hibernate.DOUBLE ) ); - registerFunction( "atan", new StandardSQLFunction( "atan", Hibernate.DOUBLE ) ); - registerFunction( "cos", new StandardSQLFunction( "cos", Hibernate.DOUBLE ) ); - registerFunction( "cot", new StandardSQLFunction( "cot", Hibernate.DOUBLE ) ); - registerFunction( "exp", new StandardSQLFunction( "exp", Hibernate.DOUBLE ) ); - registerFunction( "log", new StandardSQLFunction( "log", Hibernate.DOUBLE ) ); - registerFunction( "log10", new StandardSQLFunction( "log10", Hibernate.DOUBLE ) ); - registerFunction( "sin", new StandardSQLFunction( "sin", Hibernate.DOUBLE ) ); - registerFunction( "sqrt", new StandardSQLFunction( "sqrt", Hibernate.DOUBLE ) ); - registerFunction( "tan", new StandardSQLFunction( "tan", Hibernate.DOUBLE ) ); - registerFunction( "pi", new NoArgSQLFunction( "pi", Hibernate.DOUBLE ) ); - registerFunction( "rand", new StandardSQLFunction( "rand", Hibernate.FLOAT ) ); + registerFunction( "acos", new StandardSQLFunction( "acos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "asin", new StandardSQLFunction( "asin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "atan", new StandardSQLFunction( "atan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cos", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cot", new StandardSQLFunction( "cot", StandardBasicTypes.DOUBLE ) ); + registerFunction( "exp", new StandardSQLFunction( "exp", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log", new StandardSQLFunction( "log", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log10", new StandardSQLFunction( "log10", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sin", new StandardSQLFunction( "sin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sqrt", new StandardSQLFunction( "sqrt", StandardBasicTypes.DOUBLE ) ); + registerFunction( "tan", new StandardSQLFunction( "tan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "pi", new NoArgSQLFunction( "pi", StandardBasicTypes.DOUBLE ) ); + registerFunction( "rand", new StandardSQLFunction( "rand", StandardBasicTypes.FLOAT ) ); - registerFunction( "radians", new StandardSQLFunction( "radians", Hibernate.DOUBLE ) ); - registerFunction( "degrees", new StandardSQLFunction( "degrees", Hibernate.DOUBLE ) ); + registerFunction( "radians", new StandardSQLFunction( "radians", StandardBasicTypes.DOUBLE ) ); + registerFunction( "degrees", new StandardSQLFunction( "degrees", StandardBasicTypes.DOUBLE ) ); + registerFunction( "round", new StandardSQLFunction( "round" ) ); registerFunction( "roundmagic", new StandardSQLFunction( "roundmagic" ) ); + registerFunction( "truncate", new StandardSQLFunction( "truncate" ) ); registerFunction( "ceiling", new StandardSQLFunction( "ceiling" ) ); registerFunction( "floor", new StandardSQLFunction( "floor" ) ); - // Multi-param dialect functions... - registerFunction( "mod", new StandardSQLFunction( "mod", Hibernate.INTEGER ) ); + // special functions + // from v. 2.2.0 ROWNUM() is supported in all modes as the equivalent of Oracle ROWNUM + if ( hsqldbVersion > 21 ) { + registerFunction( "rownum", new NoArgSQLFunction( "rownum", StandardBasicTypes.INTEGER ) ); + } // function templates - registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) ); + registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(", "||", ")" ) ); getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE ); } + @Override public String getAddColumnString() { return "add column"; } + @Override public boolean supportsIdentityColumns() { return true; } + @Override public String getIdentityColumnString() { - return "generated by default as identity (start with 1)"; //not null is implicit + //not null is implicit + return "generated by default as identity (start with 1)"; } + @Override public String getIdentitySelectString() { return "call identity()"; } + @Override public String getIdentityInsertString() { - return "null"; + return hsqldbVersion < 20 ? "null" : "default"; } - public String getForUpdateString() { - return ""; + @Override + public boolean supportsLockTimeouts() { + return false; } - public boolean supportsUnique() { - return false; + @Override + public String getForUpdateString() { + if ( hsqldbVersion >= 20 ) { + return " for update"; + } + else { + return ""; + } } + @Override public boolean supportsLimit() { return true; } + @Override public String getLimitString(String sql, boolean hasOffset) { - return new StringBuffer( sql.length() + 10 ) - .append( sql ) - .insert( sql.toLowerCase().indexOf( "select" ) + 6, hasOffset ? " limit ? ?" : " top ?" ) - .toString(); + if ( hsqldbVersion < 20 ) { + return new StringBuilder( sql.length() + 10 ) + .append( sql ) + .insert( + sql.toLowerCase().indexOf( "select" ) + 6, + hasOffset ? " limit ? ?" : " top ?" + ) + .toString(); + } + else { + return sql + (hasOffset ? " offset ? limit ?" : " limit ?"); + } } + @Override public boolean bindLimitParametersFirst() { - return true; + return hsqldbVersion < 20; } + @Override public boolean supportsIfExistsAfterTableName() { return true; } + @Override public boolean supportsColumnCheck() { - return false; + return hsqldbVersion >= 20; } + @Override public boolean supportsSequences() { return true; } + @Override public boolean supportsPooledSequences() { return true; } + /** + * HSQL will start with 0, by default. In order for Hibernate to know that this not transient, + * manually start with 1. + */ + @Override protected String getCreateSequenceString(String sequenceName) { - return "create sequence " + sequenceName; + return "create sequence " + sequenceName + " start with 1"; } + + /** + * Because of the overridden {@link #getCreateSequenceString(String)}, we must also override + * {@link #getCreateSequenceString(String, int, int)} to prevent 2 instances of "start with". + */ + @Override + protected String getCreateSequenceString(String sequenceName, int initialValue, int incrementSize) throws MappingException { + if ( supportsPooledSequences() ) { + return "create sequence " + sequenceName + " start with " + initialValue + " increment by " + incrementSize; + } + throw new MappingException( getClass().getName() + " does not support pooled sequences" ); + } + @Override protected String getDropSequenceString(String sequenceName) { return "drop sequence " + sequenceName; } + @Override public String getSelectSequenceNextValString(String sequenceName) { return "next value for " + sequenceName; } + @Override public String getSequenceNextValString(String sequenceName) { return "call next value for " + sequenceName; } + @Override public String getQuerySequencesString() { // this assumes schema support, which is present in 1.8.0 and later... return "select sequence_name from information_schema.system_sequences"; } + @Override public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() { - return EXTRACTER; + return hsqldbVersion < 20 ? EXTRACTER_18 : EXTRACTER_20; } - private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { - - /** - * Extract the name of the violated constraint from the given SQLException. - * - * @param sqle The exception that was the result of the constraint violation. - * @return The extracted constraint name. - */ + private static final ViolatedConstraintNameExtracter EXTRACTER_18 = new TemplatedViolatedConstraintNameExtracter() { + @Override public String extractConstraintName(SQLException sqle) { String constraintName = null; - int errorCode = JDBCExceptionHelper.extractErrorCode( sqle ); + final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle ); if ( errorCode == -8 ) { constraintName = extractUsingTemplate( @@ -267,54 +384,281 @@ } else if ( errorCode == -177 ) { constraintName = extractUsingTemplate( - "Integrity constraint violation - no parent ", " table:", sqle.getMessage() + "Integrity constraint violation - no parent ", " table:", + sqle.getMessage() ); } - return constraintName; } }; /** - * HSQL does not really support temp tables; just take advantage of the - * fact that it is a single user db... + * HSQLDB 2.0 messages have changed + * messages may be localized - therefore use the common, non-locale element " table: " */ + private static final ViolatedConstraintNameExtracter EXTRACTER_20 = new TemplatedViolatedConstraintNameExtracter() { + @Override + public String extractConstraintName(SQLException sqle) { + String constraintName = null; + + final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle ); + + if ( errorCode == -8 ) { + constraintName = extractUsingTemplate( + "; ", " table: ", sqle.getMessage() + ); + } + else if ( errorCode == -9 ) { + constraintName = extractUsingTemplate( + "; ", " table: ", sqle.getMessage() + ); + } + else if ( errorCode == -104 ) { + constraintName = extractUsingTemplate( + "; ", " table: ", sqle.getMessage() + ); + } + else if ( errorCode == -177 ) { + constraintName = extractUsingTemplate( + "; ", " table: ", sqle.getMessage() + ); + } + return constraintName; + } + }; + + @Override + public String getSelectClauseNullString(int sqlType) { + String literal; + switch ( sqlType ) { + case Types.LONGVARCHAR: + case Types.VARCHAR: + case Types.CHAR: + literal = "cast(null as varchar(100))"; + break; + case Types.LONGVARBINARY: + case Types.VARBINARY: + case Types.BINARY: + literal = "cast(null as varbinary(100))"; + break; + case Types.CLOB: + literal = "cast(null as clob)"; + break; + case Types.BLOB: + literal = "cast(null as blob)"; + break; + case Types.DATE: + literal = "cast(null as date)"; + break; + case Types.TIMESTAMP: + literal = "cast(null as timestamp)"; + break; + case Types.BOOLEAN: + literal = "cast(null as boolean)"; + break; + case Types.BIT: + literal = "cast(null as bit)"; + break; + case Types.TIME: + literal = "cast(null as time)"; + break; + default: + literal = "cast(null as int)"; + } + return literal; + } + + @Override + public boolean supportsUnionAll() { + return true; + } + + // temporary table support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // Hibernate uses this information for temporary tables that it uses for its own operations + // therefore the appropriate strategy is taken with different versions of HSQLDB + + // All versions of HSQLDB support GLOBAL TEMPORARY tables where the table + // definition is shared by all users but data is private to the session + // HSQLDB 2.0 also supports session-based LOCAL TEMPORARY tables where + // the definition and data is private to the session and table declaration + // can happen in the middle of a transaction + + @Override public boolean supportsTemporaryTables() { return true; } + @Override + public String generateTemporaryTableName(String baseTableName) { + if ( hsqldbVersion < 20 ) { + return "HT_" + baseTableName; + } + else { + // With HSQLDB 2.0, the table name is qualified with MODULE to assist the drop + // statement (in-case there is a global name beginning with HT_) + return "MODULE.HT_" + baseTableName; + } + } + + @Override + public String getCreateTemporaryTableString() { + if ( hsqldbVersion < 20 ) { + return "create global temporary table"; + } + else { + return "declare local temporary table"; + } + } + + @Override + public String getCreateTemporaryTablePostfix() { + return ""; + } + + @Override + public String getDropTemporaryTableString() { + return "drop table"; + } + + @Override + public Boolean performTemporaryTableDDLInIsolation() { + // Different behavior for GLOBAL TEMPORARY (1.8) and LOCAL TEMPORARY (2.0) + if ( hsqldbVersion < 20 ) { + return Boolean.TRUE; + } + else { + return Boolean.FALSE; + } + } + + @Override + public boolean dropTemporaryTableAfterUse() { + // Version 1.8 GLOBAL TEMPORARY table definitions persist beyond the end + // of the session (by default, data is cleared at commit).

    + // + // Version 2.x LOCAL TEMPORARY table definitions do not persist beyond + // the end of the session (by default, data is cleared at commit). + return true; + } + + // current timestamp support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * HSQLDB 1.8.x requires CALL CURRENT_TIMESTAMP but this should not + * be treated as a callable statement. It is equivalent to + * "select current_timestamp from dual" in some databases. + * HSQLDB 2.0 also supports VALUES CURRENT_TIMESTAMP + *

    + * {@inheritDoc} + */ + @Override public boolean supportsCurrentTimestampSelection() { + return true; + } + + @Override + public boolean isCurrentTimestampSelectStringCallable() { return false; } + @Override + public String getCurrentTimestampSelectString() { + return "call current_timestamp"; + } + + @Override + public String getCurrentTimestampSQLFunctionName() { + // the standard SQL function name is current_timestamp... + return "current_timestamp"; + } + + /** + * For HSQLDB 2.0, this is a copy of the base class implementation. + * For HSQLDB 1.8, only READ_UNCOMMITTED is supported. + *

    + * {@inheritDoc} + */ + @Override public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { - // HSQLDB only supports READ_UNCOMMITTED transaction isolation - return new ReadUncommittedLockingStrategy( lockable, lockMode ); + if ( lockMode == LockMode.PESSIMISTIC_FORCE_INCREMENT ) { + return new PessimisticForceIncrementLockingStrategy( lockable, lockMode ); + } + else if ( lockMode == LockMode.PESSIMISTIC_WRITE ) { + return new PessimisticWriteSelectLockingStrategy( lockable, lockMode ); + } + else if ( lockMode == LockMode.PESSIMISTIC_READ ) { + return new PessimisticReadSelectLockingStrategy( lockable, lockMode ); + } + else if ( lockMode == LockMode.OPTIMISTIC ) { + return new OptimisticLockingStrategy( lockable, lockMode ); + } + else if ( lockMode == LockMode.OPTIMISTIC_FORCE_INCREMENT ) { + return new OptimisticForceIncrementLockingStrategy( lockable, lockMode ); + } + + if ( hsqldbVersion < 20 ) { + return new ReadUncommittedLockingStrategy( lockable, lockMode ); + } + else { + return new SelectLockingStrategy( lockable, lockMode ); + } } - public static class ReadUncommittedLockingStrategy extends SelectLockingStrategy { + private static class ReadUncommittedLockingStrategy extends SelectLockingStrategy { public ReadUncommittedLockingStrategy(Lockable lockable, LockMode lockMode) { super( lockable, lockMode ); } - public void lock(Serializable id, Object version, Object object, SessionImplementor session) + public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session) throws StaleObjectStateException, JDBCException { if ( getLockMode().greaterThan( LockMode.READ ) ) { - log.warn( "HSQLDB supports only READ_UNCOMMITTED isolation" ); + LOG.hsqldbSupportsOnlyReadCommittedIsolation(); } - super.lock( id, version, object, session ); + super.lock( id, version, object, timeout, session ); } } + @Override + public boolean supportsCommentOn() { + return hsqldbVersion >= 20; + } // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public boolean supportsEmptyInList() { return false; } + @Override + public boolean requiresCastingOfParametersInSelectClause() { + return true; + } + + @Override + public boolean doesReadCommittedCauseWritersToBlockReaders() { + return hsqldbVersion >= 20; + } + + @Override + public boolean doesRepeatableReadCauseReadersToBlockWriters() { + return hsqldbVersion >= 20; + } + + @Override public boolean supportsLobValueChangePropogation() { return false; } + + @Override + public String toBooleanValueString(boolean bool) { + return String.valueOf( bool ); + } + + @Override + public boolean supportsTupleDistinctCounts() { + return false; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/InformixDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/InformixDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/InformixDialect.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/InformixDialect.java 30 Jul 2014 16:15:54 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,29 +20,32 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; import java.sql.SQLException; import java.sql.Types; import org.hibernate.MappingException; -import org.hibernate.Hibernate; import org.hibernate.dialect.function.VarArgsSQLFunction; -import org.hibernate.exception.JDBCExceptionHelper; -import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter; -import org.hibernate.exception.ViolatedConstraintNameExtracter; -import org.hibernate.util.StringHelper; +import org.hibernate.dialect.unique.InformixUniqueDelegate; +import org.hibernate.dialect.unique.UniqueDelegate; +import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter; +import org.hibernate.exception.spi.ViolatedConstraintNameExtracter; +import org.hibernate.internal.util.JdbcExceptionHelper; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.type.StandardBasicTypes; /** * Informix dialect.
    *
    - * Seems to work with Informix Dynamic Server Version 7.31.UD3, - * Informix JDBC driver version 2.21JC3. + * Seems to work with Informix Dynamic Server Version 7.31.UD3, Informix JDBC driver version 2.21JC3. + * * @author Steve Molitor */ public class InformixDialect extends Dialect { + + private final UniqueDelegate uniqueDelegate; /** * Creates new InformixDialect instance. Sets up the JDBC / @@ -51,169 +54,207 @@ public InformixDialect() { super(); - registerColumnType(Types.BIGINT, "int8"); - registerColumnType(Types.BINARY, "byte"); - registerColumnType(Types.BIT, "smallint"); // Informix doesn't have a bit type - registerColumnType(Types.CHAR, "char($l)"); - registerColumnType(Types.DATE, "date"); - registerColumnType(Types.DECIMAL, "decimal"); - registerColumnType(Types.DOUBLE, "float"); - registerColumnType(Types.FLOAT, "smallfloat"); - registerColumnType(Types.INTEGER, "integer"); - registerColumnType(Types.LONGVARBINARY, "blob"); // or BYTE - registerColumnType(Types.LONGVARCHAR, "clob"); // or TEXT? - registerColumnType(Types.NUMERIC, "decimal"); // or MONEY - registerColumnType(Types.REAL, "smallfloat"); - registerColumnType(Types.SMALLINT, "smallint"); - registerColumnType(Types.TIMESTAMP, "datetime year to fraction(5)"); - registerColumnType(Types.TIME, "datetime hour to second"); - registerColumnType(Types.TINYINT, "smallint"); - registerColumnType(Types.VARBINARY, "byte"); - registerColumnType(Types.VARCHAR, "varchar($l)"); - registerColumnType(Types.VARCHAR, 255, "varchar($l)"); - registerColumnType(Types.VARCHAR, 32739, "lvarchar($l)"); + registerColumnType( Types.BIGINT, "int8" ); + registerColumnType( Types.BINARY, "byte" ); + // Informix doesn't have a bit type + registerColumnType( Types.BIT, "smallint" ); + registerColumnType( Types.CHAR, "char($l)" ); + registerColumnType( Types.DATE, "date" ); + registerColumnType( Types.DECIMAL, "decimal" ); + registerColumnType( Types.DOUBLE, "float" ); + registerColumnType( Types.FLOAT, "smallfloat" ); + registerColumnType( Types.INTEGER, "integer" ); + // or BYTE + registerColumnType( Types.LONGVARBINARY, "blob" ); + // or TEXT? + registerColumnType( Types.LONGVARCHAR, "clob" ); + // or MONEY + registerColumnType( Types.NUMERIC, "decimal" ); + registerColumnType( Types.REAL, "smallfloat" ); + registerColumnType( Types.SMALLINT, "smallint" ); + registerColumnType( Types.TIMESTAMP, "datetime year to fraction(5)" ); + registerColumnType( Types.TIME, "datetime hour to second" ); + registerColumnType( Types.TINYINT, "smallint" ); + registerColumnType( Types.VARBINARY, "byte" ); + registerColumnType( Types.VARCHAR, "varchar($l)" ); + registerColumnType( Types.VARCHAR, 255, "varchar($l)" ); + registerColumnType( Types.VARCHAR, 32739, "lvarchar($l)" ); - registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) ); + registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(", "||", ")" ) ); + + uniqueDelegate = new InformixUniqueDelegate( this ); } + @Override public String getAddColumnString() { return "add"; } + @Override public boolean supportsIdentityColumns() { return true; } - public String getIdentitySelectString(String table, String column, int type) - throws MappingException { - return type==Types.BIGINT ? - "select dbinfo('serial8') from systables where tabid=1" : - "select dbinfo('sqlca.sqlerrd1') from systables where tabid=1"; + @Override + public String getIdentitySelectString(String table, String column, int type) + throws MappingException { + return type == Types.BIGINT + ? "select dbinfo('serial8') from informix.systables where tabid=1" + : "select dbinfo('sqlca.sqlerrd1') from informix.systables where tabid=1"; } + @Override public String getIdentityColumnString(int type) throws MappingException { - return type==Types.BIGINT ? - "serial8 not null" : - "serial not null"; + return type == Types.BIGINT ? + "serial8 not null" : + "serial not null"; } + @Override public boolean hasDataTypeInIdentityColumn() { return false; } /** - * The syntax used to add a foreign key constraint to a table. * Informix constraint name must be at the end. - * @return String + *

    + * {@inheritDoc} */ + @Override public String getAddForeignKeyConstraintString( - String constraintName, - String[] foreignKey, - String referencedTable, - String[] primaryKey, boolean referencesPrimaryKey - ) { - StringBuffer result = new StringBuffer(30); - - result.append(" add constraint ") - .append(" foreign key (") - .append( StringHelper.join(", ", foreignKey) ) - .append(") references ") - .append(referencedTable); - - if(!referencesPrimaryKey) { - result.append(" (") - .append( StringHelper.join(", ", primaryKey) ) - .append(')'); + String constraintName, + String[] foreignKey, + String referencedTable, + String[] primaryKey, + boolean referencesPrimaryKey) { + final StringBuilder result = new StringBuilder( 30 ) + .append( " add constraint " ) + .append( " foreign key (" ) + .append( StringHelper.join( ", ", foreignKey ) ) + .append( ") references " ) + .append( referencedTable ); + + if ( !referencesPrimaryKey ) { + result.append( " (" ) + .append( StringHelper.join( ", ", primaryKey ) ) + .append( ')' ); } - result.append(" constraint ").append(constraintName); - - return result.toString(); + result.append( " constraint " ).append( constraintName ); + + return result.toString(); } /** - * The syntax used to add a primary key constraint to a table. * Informix constraint name must be at the end. - * @return String + *

    + * {@inheritDoc} */ + @Override public String getAddPrimaryKeyConstraintString(String constraintName) { return " add constraint primary key constraint " + constraintName + " "; } + @Override public String getCreateSequenceString(String sequenceName) { return "create sequence " + sequenceName; } + + @Override public String getDropSequenceString(String sequenceName) { return "drop sequence " + sequenceName + " restrict"; } + @Override public String getSequenceNextValString(String sequenceName) { - return "select " + getSelectSequenceNextValString( sequenceName ) + " from systables where tabid=1"; + return "select " + getSelectSequenceNextValString( sequenceName ) + " from informix.systables where tabid=1"; } + @Override public String getSelectSequenceNextValString(String sequenceName) { return sequenceName + ".nextval"; } + @Override public boolean supportsSequences() { return true; } + @Override + public boolean supportsPooledSequences() { + return true; + } + + @Override + public String getQuerySequencesString() { + return "select tabname from informix.systables where tabtype='Q'"; + } + + @Override public boolean supportsLimit() { return true; } + @Override public boolean useMaxForLimit() { return true; } + @Override public boolean supportsLimitOffset() { return false; } + @Override public String getLimitString(String querySelect, int offset, int limit) { - if (offset>0) throw new UnsupportedOperationException("informix has no offset"); - return new StringBuffer( querySelect.length()+8 ) - .append(querySelect) - .insert( querySelect.toLowerCase().indexOf( "select" ) + 6, " first " + limit ) - .toString(); + if ( offset > 0 ) { + throw new UnsupportedOperationException( "query result offset is not supported" ); + } + return new StringBuilder( querySelect.length() + 8 ) + .append( querySelect ) + .insert( querySelect.toLowerCase().indexOf( "select" ) + 6, " first " + limit ) + .toString(); } + @Override public boolean supportsVariableLimit() { return false; } + @Override public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() { - return EXTRACTER; + return EXTRACTER; } - private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { - - /** - * Extract the name of the violated constraint from the given SQLException. - * - * @param sqle The exception that was the result of the constraint violation. - * @return The extracted constraint name. - */ + private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { + @Override public String extractConstraintName(SQLException sqle) { String constraintName = null; - - int errorCode = JDBCExceptionHelper.extractErrorCode(sqle); + final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle ); + if ( errorCode == -268 ) { constraintName = extractUsingTemplate( "Unique constraint (", ") violated.", sqle.getMessage() ); } else if ( errorCode == -691 ) { - constraintName = extractUsingTemplate( "Missing key in referenced table for referential constraint (", ").", sqle.getMessage() ); + constraintName = extractUsingTemplate( + "Missing key in referenced table for referential constraint (", + ").", + sqle.getMessage() + ); } else if ( errorCode == -692 ) { - constraintName = extractUsingTemplate( "Key value for constraint (", ") is still being referenced.", sqle.getMessage() ); + constraintName = extractUsingTemplate( + "Key value for constraint (", + ") is still being referenced.", + sqle.getMessage() + ); } - - if (constraintName != null) { + + if ( constraintName != null ) { // strip table-owner because Informix always returns constraint names as "." - int i = constraintName.indexOf('.'); - if (i != -1) { - constraintName = constraintName.substring(i + 1); + final int i = constraintName.indexOf( '.' ); + if ( i != -1 ) { + constraintName = constraintName.substring( i + 1 ); } } @@ -222,15 +263,38 @@ }; + @Override public boolean supportsCurrentTimestampSelection() { return true; } + @Override public boolean isCurrentTimestampSelectStringCallable() { return false; } + @Override public String getCurrentTimestampSelectString() { return "select distinct current timestamp from informix.systables"; } -} \ No newline at end of file + + @Override + public boolean supportsTemporaryTables() { + return true; + } + + @Override + public String getCreateTemporaryTableString() { + return "create temp table"; + } + + @Override + public String getCreateTemporaryTablePostfix() { + return "with no log"; + } + + @Override + public UniqueDelegate getUniqueDelegate() { + return uniqueDelegate; + } +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/Ingres10Dialect.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/Ingres9Dialect.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/IngresDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/IngresDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/IngresDialect.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/IngresDialect.java 30 Jul 2014 16:15:54 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,29 +20,47 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; import java.sql.Types; -import org.hibernate.Hibernate; -import org.hibernate.dialect.function.SQLFunctionTemplate; +import org.hibernate.cfg.Environment; import org.hibernate.dialect.function.NoArgSQLFunction; +import org.hibernate.dialect.function.SQLFunctionTemplate; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.VarArgsSQLFunction; +import org.hibernate.type.StandardBasicTypes; /** - * An Ingres SQL dialect. + * An SQL dialect for Ingres 9.2. *

    - * Known limitations: - * - only supports simple constants or columns on the left side of an IN, making (1,2,3) in (...) or ( + *

  • + * Only supports simple constants or columns on the left side of an IN, + * making {@code (1,2,3) in (...)} or {@code (subselect) in (...)} non-supported. + *
  • + *
  • + * Supports only 39 digits in decimal. + *
  • + *
  • + * Explicitly set USE_GET_GENERATED_KEYS property to false. + *
  • + *
  • + * Perform string casts to varchar; removes space padding. + *
  • + * + * + * @author Ian Booth + * @author Bruce Lunsford + * @author Max Rydahl Andersen + * @author Raymond Fan */ +@SuppressWarnings("deprecation") public class IngresDialect extends Dialect { - + /** + * Constructs a IngresDialect + */ public IngresDialect() { super(); registerColumnType( Types.BIT, "tinyint" ); @@ -60,7 +78,7 @@ registerColumnType( Types.VARBINARY, 32000, "varbyte($l)" ); registerColumnType( Types.VARBINARY, "long byte" ); registerColumnType( Types.LONGVARBINARY, "long byte" ); - registerColumnType( Types.CHAR, "char(1)" ); + registerColumnType( Types.CHAR, 32000, "char($l)" ); registerColumnType( Types.VARCHAR, 32000, "varchar($l)" ); registerColumnType( Types.VARCHAR, "long varchar" ); registerColumnType( Types.LONGVARCHAR, "long varchar" ); @@ -71,257 +89,222 @@ registerColumnType( Types.CLOB, "clob" ); registerFunction( "abs", new StandardSQLFunction( "abs" ) ); - registerFunction( "atan", new StandardSQLFunction( "atan", Hibernate.DOUBLE ) ); + registerFunction( "atan", new StandardSQLFunction( "atan", StandardBasicTypes.DOUBLE ) ); registerFunction( "bit_add", new StandardSQLFunction( "bit_add" ) ); registerFunction( "bit_and", new StandardSQLFunction( "bit_and" ) ); - registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "octet_length(hex(?1))*4" ) ); + registerFunction( "bit_length", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "octet_length(hex(?1))*4" ) ); registerFunction( "bit_not", new StandardSQLFunction( "bit_not" ) ); registerFunction( "bit_or", new StandardSQLFunction( "bit_or" ) ); registerFunction( "bit_xor", new StandardSQLFunction( "bit_xor" ) ); - registerFunction( "character_length", new StandardSQLFunction( "character_length", Hibernate.LONG ) ); - registerFunction( "charextract", new StandardSQLFunction( "charextract", Hibernate.STRING ) ); - registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "+", ")" ) ); - registerFunction( "cos", new StandardSQLFunction( "cos", Hibernate.DOUBLE ) ); - registerFunction( "current_user", new NoArgSQLFunction( "current_user", Hibernate.STRING, false ) ); - registerFunction( "current_time", new NoArgSQLFunction( "date('now')", Hibernate.TIMESTAMP, false ) ); - registerFunction( "current_timestamp", new NoArgSQLFunction( "date('now')", Hibernate.TIMESTAMP, false ) ); - registerFunction( "current_date", new NoArgSQLFunction( "date('now')", Hibernate.TIMESTAMP, false ) ); - registerFunction( "date_trunc", new StandardSQLFunction( "date_trunc", Hibernate.TIMESTAMP ) ); - registerFunction( "day", new StandardSQLFunction( "day", Hibernate.INTEGER ) ); - registerFunction( "dba", new NoArgSQLFunction( "dba", Hibernate.STRING, true ) ); - registerFunction( "dow", new StandardSQLFunction( "dow", Hibernate.STRING ) ); - registerFunction( "extract", new SQLFunctionTemplate( Hibernate.INTEGER, "date_part('?1', ?3)" ) ); - registerFunction( "exp", new StandardSQLFunction( "exp", Hibernate.DOUBLE ) ); - registerFunction( "gmt_timestamp", new StandardSQLFunction( "gmt_timestamp", Hibernate.STRING ) ); - registerFunction( "hash", new StandardSQLFunction( "hash", Hibernate.INTEGER ) ); - registerFunction( "hex", new StandardSQLFunction( "hex", Hibernate.STRING ) ); - registerFunction( "hour", new StandardSQLFunction( "hour", Hibernate.INTEGER ) ); - registerFunction( "initial_user", new NoArgSQLFunction( "initial_user", Hibernate.STRING, false ) ); - registerFunction( "intextract", new StandardSQLFunction( "intextract", Hibernate.INTEGER ) ); - registerFunction( "left", new StandardSQLFunction( "left", Hibernate.STRING ) ); - registerFunction( "locate", new SQLFunctionTemplate( Hibernate.LONG, "locate(?1, ?2)" ) ); - registerFunction( "length", new StandardSQLFunction( "length", Hibernate.LONG ) ); - registerFunction( "ln", new StandardSQLFunction( "ln", Hibernate.DOUBLE ) ); - registerFunction( "log", new StandardSQLFunction( "log", Hibernate.DOUBLE ) ); + registerFunction( "character_length", new StandardSQLFunction( "character_length", StandardBasicTypes.LONG ) ); + registerFunction( "charextract", new StandardSQLFunction( "charextract", StandardBasicTypes.STRING ) ); + registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(", "+", ")" ) ); + registerFunction( "cos", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "current_user", new NoArgSQLFunction( "current_user", StandardBasicTypes.STRING, false ) ); + registerFunction( "current_time", new NoArgSQLFunction( "date('now')", StandardBasicTypes.TIMESTAMP, false ) ); + registerFunction( "current_timestamp", new NoArgSQLFunction( "date('now')", StandardBasicTypes.TIMESTAMP, false ) ); + registerFunction( "current_date", new NoArgSQLFunction( "date('now')", StandardBasicTypes.TIMESTAMP, false ) ); + registerFunction( "date_trunc", new StandardSQLFunction( "date_trunc", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "day", new StandardSQLFunction( "day", StandardBasicTypes.INTEGER ) ); + registerFunction( "dba", new NoArgSQLFunction( "dba", StandardBasicTypes.STRING, true ) ); + registerFunction( "dow", new StandardSQLFunction( "dow", StandardBasicTypes.STRING ) ); + registerFunction( "extract", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "date_part('?1', ?3)" ) ); + registerFunction( "exp", new StandardSQLFunction( "exp", StandardBasicTypes.DOUBLE ) ); + registerFunction( "gmt_timestamp", new StandardSQLFunction( "gmt_timestamp", StandardBasicTypes.STRING ) ); + registerFunction( "hash", new StandardSQLFunction( "hash", StandardBasicTypes.INTEGER ) ); + registerFunction( "hex", new StandardSQLFunction( "hex", StandardBasicTypes.STRING ) ); + registerFunction( "hour", new StandardSQLFunction( "hour", StandardBasicTypes.INTEGER ) ); + registerFunction( "initial_user", new NoArgSQLFunction( "initial_user", StandardBasicTypes.STRING, false ) ); + registerFunction( "intextract", new StandardSQLFunction( "intextract", StandardBasicTypes.INTEGER ) ); + registerFunction( "left", new StandardSQLFunction( "left", StandardBasicTypes.STRING ) ); + registerFunction( "locate", new SQLFunctionTemplate( StandardBasicTypes.LONG, "locate(?1, ?2)" ) ); + registerFunction( "length", new StandardSQLFunction( "length", StandardBasicTypes.LONG ) ); + registerFunction( "ln", new StandardSQLFunction( "ln", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log", new StandardSQLFunction( "log", StandardBasicTypes.DOUBLE ) ); registerFunction( "lower", new StandardSQLFunction( "lower" ) ); registerFunction( "lowercase", new StandardSQLFunction( "lowercase" ) ); - registerFunction( "minute", new StandardSQLFunction( "minute", Hibernate.INTEGER ) ); - registerFunction( "month", new StandardSQLFunction( "month", Hibernate.INTEGER ) ); - registerFunction( "octet_length", new StandardSQLFunction( "octet_length", Hibernate.LONG ) ); - registerFunction( "pad", new StandardSQLFunction( "pad", Hibernate.STRING ) ); - registerFunction( "position", new StandardSQLFunction( "position", Hibernate.LONG ) ); - registerFunction( "power", new StandardSQLFunction( "power", Hibernate.DOUBLE ) ); - registerFunction( "random", new NoArgSQLFunction( "random", Hibernate.LONG, true ) ); - registerFunction( "randomf", new NoArgSQLFunction( "randomf", Hibernate.DOUBLE, true ) ); - registerFunction( "right", new StandardSQLFunction( "right", Hibernate.STRING ) ); - registerFunction( "session_user", new NoArgSQLFunction( "session_user", Hibernate.STRING, false ) ); - registerFunction( "second", new StandardSQLFunction( "second", Hibernate.INTEGER ) ); - registerFunction( "size", new NoArgSQLFunction( "size", Hibernate.LONG, true ) ); + registerFunction( "minute", new StandardSQLFunction( "minute", StandardBasicTypes.INTEGER ) ); + registerFunction( "month", new StandardSQLFunction( "month", StandardBasicTypes.INTEGER ) ); + registerFunction( "octet_length", new StandardSQLFunction( "octet_length", StandardBasicTypes.LONG ) ); + registerFunction( "pad", new StandardSQLFunction( "pad", StandardBasicTypes.STRING ) ); + registerFunction( "position", new StandardSQLFunction( "position", StandardBasicTypes.LONG ) ); + registerFunction( "power", new StandardSQLFunction( "power", StandardBasicTypes.DOUBLE ) ); + registerFunction( "random", new NoArgSQLFunction( "random", StandardBasicTypes.LONG, true ) ); + registerFunction( "randomf", new NoArgSQLFunction( "randomf", StandardBasicTypes.DOUBLE, true ) ); + registerFunction( "right", new StandardSQLFunction( "right", StandardBasicTypes.STRING ) ); + registerFunction( "session_user", new NoArgSQLFunction( "session_user", StandardBasicTypes.STRING, false ) ); + registerFunction( "second", new StandardSQLFunction( "second", StandardBasicTypes.INTEGER ) ); + registerFunction( "size", new NoArgSQLFunction( "size", StandardBasicTypes.LONG, true ) ); registerFunction( "squeeze", new StandardSQLFunction( "squeeze" ) ); - registerFunction( "sin", new StandardSQLFunction( "sin", Hibernate.DOUBLE ) ); - registerFunction( "soundex", new StandardSQLFunction( "soundex", Hibernate.STRING ) ); - registerFunction( "sqrt", new StandardSQLFunction( "sqrt", Hibernate.DOUBLE ) ); - registerFunction( "substring", new SQLFunctionTemplate( Hibernate.STRING, "substring(?1 FROM ?2 FOR ?3)" ) ); - registerFunction( "system_user", new NoArgSQLFunction( "system_user", Hibernate.STRING, false ) ); - //registerFunction( "trim", new StandardSQLFunction( "trim", Hibernate.STRING ) ); - registerFunction( "unhex", new StandardSQLFunction( "unhex", Hibernate.STRING ) ); + registerFunction( "sin", new StandardSQLFunction( "sin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "soundex", new StandardSQLFunction( "soundex", StandardBasicTypes.STRING ) ); + registerFunction( "sqrt", new StandardSQLFunction( "sqrt", StandardBasicTypes.DOUBLE ) ); + registerFunction( "substring", new SQLFunctionTemplate( StandardBasicTypes.STRING, "substring(?1 FROM ?2 FOR ?3)" ) ); + registerFunction( "system_user", new NoArgSQLFunction( "system_user", StandardBasicTypes.STRING, false ) ); + //registerFunction( "trim", new StandardSQLFunction( "trim", StandardBasicTypes.STRING ) ); + registerFunction( "unhex", new StandardSQLFunction( "unhex", StandardBasicTypes.STRING ) ); registerFunction( "upper", new StandardSQLFunction( "upper" ) ); registerFunction( "uppercase", new StandardSQLFunction( "uppercase" ) ); - registerFunction( "user", new NoArgSQLFunction( "user", Hibernate.STRING, false ) ); - registerFunction( "usercode", new NoArgSQLFunction( "usercode", Hibernate.STRING, true ) ); - registerFunction( "username", new NoArgSQLFunction( "username", Hibernate.STRING, true ) ); - registerFunction( "uuid_create", new StandardSQLFunction( "uuid_create", Hibernate.BYTE ) ); - registerFunction( "uuid_compare", new StandardSQLFunction( "uuid_compare", Hibernate.INTEGER ) ); - registerFunction( "uuid_from_char", new StandardSQLFunction( "uuid_from_char", Hibernate.BYTE ) ); - registerFunction( "uuid_to_char", new StandardSQLFunction( "uuid_to_char", Hibernate.STRING ) ); - registerFunction( "year", new StandardSQLFunction( "year", Hibernate.INTEGER ) ); + registerFunction( "user", new NoArgSQLFunction( "user", StandardBasicTypes.STRING, false ) ); + registerFunction( "usercode", new NoArgSQLFunction( "usercode", StandardBasicTypes.STRING, true ) ); + registerFunction( "username", new NoArgSQLFunction( "username", StandardBasicTypes.STRING, true ) ); + registerFunction( "uuid_create", new StandardSQLFunction( "uuid_create", StandardBasicTypes.BYTE ) ); + registerFunction( "uuid_compare", new StandardSQLFunction( "uuid_compare", StandardBasicTypes.INTEGER ) ); + registerFunction( "uuid_from_char", new StandardSQLFunction( "uuid_from_char", StandardBasicTypes.BYTE ) ); + registerFunction( "uuid_to_char", new StandardSQLFunction( "uuid_to_char", StandardBasicTypes.STRING ) ); + registerFunction( "year", new StandardSQLFunction( "year", StandardBasicTypes.INTEGER ) ); + // Casting to char of numeric values introduces space padding up to the + // maximum width of a value for that return type. Casting to varchar + // does not introduce space padding. + registerFunction( "str", new SQLFunctionTemplate(StandardBasicTypes.STRING, "cast(?1 as varchar)") ); + // Ingres driver supports getGeneratedKeys but only in the following + // form: + // The Ingres DBMS returns only a single table key or a single object + // key per insert statement. Ingres does not return table and object + // keys for INSERT AS SELECT statements. Depending on the keys that are + // produced by the statement executed, auto-generated key parameters in + // execute(), executeUpdate(), and prepareStatement() methods are + // ignored and getGeneratedKeys() returns a result-set containing no + // rows, a single row with one column, or a single row with two columns. + // Ingres JDBC Driver returns table and object keys as BINARY values. + getDefaultProperties().setProperty( Environment.USE_GET_GENERATED_KEYS, "false" ); + // There is no support for a native boolean type that accepts values + // of true, false or unknown. Using the tinyint type requires + // substitions of true and false. + getDefaultProperties().setProperty( Environment.QUERY_SUBSTITUTIONS, "true=1,false=0" ); } - /** - * Do we need to drop constraints before dropping tables in this dialect? - * - * @return boolean - */ + @Override + public String getSelectGUIDString() { + return "select uuid_to_char(uuid_create())"; + } + + @Override public boolean dropConstraints() { return false; } - /** - * Does this dialect support FOR UPDATE OF, allowing - * particular rows to be locked? - * - * @return True (Ingres does support "for update of" syntax...) - */ - public boolean supportsForUpdateOf() { - return true; - } - - /** - * The syntax used to add a column to a table (optional). - */ + @Override public String getAddColumnString() { return "add column"; } - /** - * The keyword used to specify a nullable column. - * - * @return String - */ + @Override public String getNullColumnString() { return " with null"; } - /** - * Does this dialect support sequences? - * - * @return boolean - */ + @Override public boolean supportsSequences() { return true; } - /** - * The syntax that fetches the next value of a sequence, if sequences are supported. - * - * @param sequenceName the name of the sequence - * - * @return String - */ + @Override public String getSequenceNextValString(String sequenceName) { return "select nextval for " + sequenceName; } + @Override public String getSelectSequenceNextValString(String sequenceName) { return sequenceName + ".nextval"; } - /** - * The syntax used to create a sequence, if sequences are supported. - * - * @param sequenceName the name of the sequence - * - * @return String - */ + @Override public String getCreateSequenceString(String sequenceName) { return "create sequence " + sequenceName; } - /** - * The syntax used to drop a sequence, if sequences are supported. - * - * @param sequenceName the name of the sequence - * - * @return String - */ + @Override public String getDropSequenceString(String sequenceName) { return "drop sequence " + sequenceName + " restrict"; } - /** - * A query used to find all sequences - */ + @Override public String getQuerySequencesString() { return "select seq_name from iisequence"; } - /** - * The name of the SQL function that transforms a string to - * lowercase - * - * @return String - */ + @Override public String getLowercaseFunction() { return "lowercase"; } - /** - * Does this Dialect have some kind of LIMIT syntax? - */ + @Override public boolean supportsLimit() { return true; } - /** - * Does this dialect support an offset? - */ + @Override public boolean supportsLimitOffset() { return false; } - /** - * Add a LIMIT clause to the given SQL SELECT - * - * @return the modified SQL - */ + @Override public String getLimitString(String querySelect, int offset, int limit) { if ( offset > 0 ) { - throw new UnsupportedOperationException( "offset not supported" ); + throw new UnsupportedOperationException( "query result offset is not supported" ); } - return new StringBuffer( querySelect.length() + 16 ) + return new StringBuilder( querySelect.length() + 16 ) .append( querySelect ) .insert( 6, " first " + limit ) .toString(); } + @Override public boolean supportsVariableLimit() { return false; } - /** - * Does the LIMIT clause take a "maximum" row number instead - * of a total number of returned rows? - */ + @Override public boolean useMaxForLimit() { return true; } - /** - * Ingres explicitly needs "unique not null", because "with null" is default - */ - public boolean supportsNotNullUnique() { - return false; - } - - /** - * Does this dialect support temporary tables? - */ + @Override public boolean supportsTemporaryTables() { return true; } + @Override public String getCreateTemporaryTableString() { return "declare global temporary table"; } + @Override public String getCreateTemporaryTablePostfix() { return "on commit preserve rows with norecovery"; } + @Override public String generateTemporaryTableName(String baseTableName) { return "session." + super.generateTemporaryTableName( baseTableName ); } - - /** - * Expression for current_timestamp - */ + @Override public String getCurrentTimestampSQLFunctionName() { return "date(now)"; } // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public boolean supportsSubselectAsInPredicateLHS() { return false; } + @Override public boolean supportsEmptyInList() { return false; } - public boolean supportsExpectedLobUsagePattern () { + @Override + public boolean supportsExpectedLobUsagePattern() { return false; } + + @Override + public boolean supportsTupleDistinctCounts() { + return false; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/InterbaseDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/InterbaseDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/InterbaseDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/InterbaseDialect.java 30 Jul 2014 16:15:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,22 +20,26 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; - import java.sql.Types; -import org.hibernate.Hibernate; import org.hibernate.cfg.Environment; +import org.hibernate.dialect.function.NoArgSQLFunction; import org.hibernate.dialect.function.VarArgsSQLFunction; +import org.hibernate.type.StandardBasicTypes; /** * An SQL dialect for Interbase. + * * @author Gavin King */ +@SuppressWarnings("deprecation") public class InterbaseDialect extends Dialect { + /** + * Constructs a InterbaseDialect + */ public InterbaseDialect() { super(); registerColumnType( Types.BIT, "smallint" ); @@ -54,75 +58,90 @@ registerColumnType( Types.NUMERIC, "numeric($p,$s)" ); registerColumnType( Types.BLOB, "blob" ); registerColumnType( Types.CLOB, "blob sub_type 1" ); + registerColumnType( Types.BOOLEAN, "smallint" ); - registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","||",")" ) ); + registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(","||",")" ) ); + registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE, false ) ); - getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH); + getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, NO_BATCH ); } + @Override public String getAddColumnString() { return "add"; } + @Override public String getSequenceNextValString(String sequenceName) { return "select " + getSelectSequenceNextValString( sequenceName ) + " from RDB$DATABASE"; } + @Override public String getSelectSequenceNextValString(String sequenceName) { return "gen_id( " + sequenceName + ", 1 )"; } + @Override public String getCreateSequenceString(String sequenceName) { return "create generator " + sequenceName; } + @Override public String getDropSequenceString(String sequenceName) { return "delete from RDB$GENERATORS where RDB$GENERATOR_NAME = '" + sequenceName.toUpperCase() + "'"; } + @Override public String getQuerySequencesString() { return "select RDB$GENERATOR_NAME from RDB$GENERATORS"; } - + + @Override public String getForUpdateString() { return " with lock"; } + + @Override public String getForUpdateString(String aliases) { return " for update of " + aliases + " with lock"; } + @Override public boolean supportsSequences() { return true; } + @Override public boolean supportsLimit() { return true; } + @Override public String getLimitString(String sql, boolean hasOffset) { - return new StringBuffer( sql.length()+15 ) - .append(sql) - .append(hasOffset ? " rows ? to ?" : " rows ?") - .toString(); + return hasOffset ? sql + " rows ? to ?" : sql + " rows ?"; } + @Override public boolean bindLimitParametersFirst() { return false; } + @Override public boolean bindLimitParametersInReverseOrder() { return false; } - public String getCurrentTimestampCallString() { + @Override + public String getCurrentTimestampSelectString() { // TODO : not sure which (either?) is correct, could not find docs on how to do this. // did find various blogs and forums mentioning that select CURRENT_TIMESTAMP // does not work... return "{?= call CURRENT_TIMESTAMP }"; // return "select CURRENT_TIMESTAMP from RDB$DATABASE"; } + @Override public boolean isCurrentTimestampSelectStringCallable() { return true; } -} \ No newline at end of file +} Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/JDataStoreDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/JDataStoreDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/JDataStoreDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/JDataStoreDialect.java 30 Jul 2014 16:15:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; @@ -29,12 +28,11 @@ import org.hibernate.cfg.Environment; /** - * A Dialect for JDataStore. + * A Dialect for JDataStore. * * @author Vishy Kasar */ public class JDataStoreDialect extends Dialect { - /** * Creates new JDataStoreDialect */ @@ -62,38 +60,48 @@ getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE ); } + @Override public String getAddColumnString() { return "add"; } + @Override public boolean dropConstraints() { return false; } + @Override public String getCascadeConstraintsString() { return " cascade"; } + @Override public boolean supportsIdentityColumns() { return true; } + @Override public String getIdentitySelectString() { - return null; // NOT_SUPPORTED_SHOULD_USE_JDBC3_PreparedStatement.getGeneratedKeys_method + // NOT_SUPPORTED_SHOULD_USE_JDBC3_PreparedStatement.getGeneratedKeys_method + return null; } + @Override public String getIdentityColumnString() { return "autoincrement"; } + @Override public String getNoColumnsInsertString() { return "default values"; } + @Override public boolean supportsColumnCheck() { return false; } + @Override public boolean supportsTableCheck() { return false; } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/LobMergeStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/MckoiDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/MckoiDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/MckoiDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/MckoiDialect.java 30 Jul 2014 16:15:52 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,28 +20,37 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; import java.sql.Types; -import org.hibernate.Hibernate; import org.hibernate.LockMode; -import org.hibernate.persister.entity.Lockable; import org.hibernate.cfg.Environment; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.lock.LockingStrategy; -import org.hibernate.dialect.lock.UpdateLockingStrategy; +import org.hibernate.dialect.lock.OptimisticForceIncrementLockingStrategy; +import org.hibernate.dialect.lock.OptimisticLockingStrategy; +import org.hibernate.dialect.lock.PessimisticForceIncrementLockingStrategy; +import org.hibernate.dialect.lock.PessimisticReadUpdateLockingStrategy; +import org.hibernate.dialect.lock.PessimisticWriteUpdateLockingStrategy; import org.hibernate.dialect.lock.SelectLockingStrategy; +import org.hibernate.dialect.lock.UpdateLockingStrategy; +import org.hibernate.persister.entity.Lockable; import org.hibernate.sql.CaseFragment; import org.hibernate.sql.MckoiCaseFragment; +import org.hibernate.type.StandardBasicTypes; /** * An SQL dialect compatible with McKoi SQL - * @author Doug Currie, Gabe Hicks + * + * @author Doug Currie + * @author Gabe Hicks */ public class MckoiDialect extends Dialect { + /** + * Constructs a MckoiDialect + */ public MckoiDialect() { super(); registerColumnType( Types.BIT, "bit" ); @@ -63,55 +72,78 @@ registerFunction( "upper", new StandardSQLFunction("upper") ); registerFunction( "lower", new StandardSQLFunction("lower") ); - registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) ); + registerFunction( "sqrt", new StandardSQLFunction("sqrt", StandardBasicTypes.DOUBLE) ); registerFunction( "abs", new StandardSQLFunction("abs") ); - registerFunction( "sign", new StandardSQLFunction( "sign", Hibernate.INTEGER ) ); - registerFunction( "length", new StandardSQLFunction( "length", Hibernate.INTEGER ) ); - registerFunction( "round", new StandardSQLFunction( "round", Hibernate.INTEGER ) ); - registerFunction( "mod", new StandardSQLFunction( "mod", Hibernate.INTEGER ) ); + registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) ); + registerFunction( "round", new StandardSQLFunction( "round", StandardBasicTypes.INTEGER ) ); + registerFunction( "mod", new StandardSQLFunction( "mod", StandardBasicTypes.INTEGER ) ); registerFunction( "least", new StandardSQLFunction("least") ); registerFunction( "greatest", new StandardSQLFunction("greatest") ); - registerFunction( "user", new StandardSQLFunction( "user", Hibernate.STRING ) ); - registerFunction( "concat", new StandardSQLFunction( "concat", Hibernate.STRING ) ); + registerFunction( "user", new StandardSQLFunction( "user", StandardBasicTypes.STRING ) ); + registerFunction( "concat", new StandardSQLFunction( "concat", StandardBasicTypes.STRING ) ); - getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH); + getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, NO_BATCH ); } + @Override public String getAddColumnString() { return "add column"; } + @Override public String getSequenceNextValString(String sequenceName) { return "select " + getSelectSequenceNextValString( sequenceName ); } + @Override public String getSelectSequenceNextValString(String sequenceName) { return "nextval('" + sequenceName + "')"; } + @Override public String getCreateSequenceString(String sequenceName) { return "create sequence " + sequenceName; } + @Override public String getDropSequenceString(String sequenceName) { return "drop sequence " + sequenceName; } + @Override public String getForUpdateString() { return ""; } + @Override public boolean supportsSequences() { return true; } + @Override public CaseFragment createCaseFragment() { return new MckoiCaseFragment(); } + @Override public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { // Mckoi has no known variation of a "SELECT ... FOR UPDATE" syntax... - if ( lockMode.greaterThan( LockMode.READ ) ) { + if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) { + return new PessimisticForceIncrementLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.PESSIMISTIC_WRITE) { + return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.PESSIMISTIC_READ) { + return new PessimisticReadUpdateLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.OPTIMISTIC) { + return new OptimisticLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) { + return new OptimisticForceIncrementLockingStrategy( lockable, lockMode); + } + else if ( lockMode.greaterThan( LockMode.READ ) ) { return new UpdateLockingStrategy( lockable, lockMode ); } else { Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/MimerSQLDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/MimerSQLDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/MimerSQLDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/MimerSQLDialect.java 30 Jul 2014 16:15:52 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,21 +20,22 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; import java.sql.Types; -import org.hibernate.Hibernate; import org.hibernate.cfg.Environment; -import org.hibernate.dialect.function.*; +import org.hibernate.dialect.function.StandardSQLFunction; +import org.hibernate.type.StandardBasicTypes; /** * An Hibernate 3 SQL dialect for Mimer SQL. This dialect requires Mimer SQL 9.2.1 or later * because of the mappings to NCLOB, BINARY, and BINARY VARYING. - * @author Fredrik �lund + * + * @author Fredrik lund */ +@SuppressWarnings("deprecation") public class MimerSQLDialect extends Dialect { private static final int NATIONAL_CHAR_LENGTH = 2000; @@ -45,7 +46,6 @@ * this is also the maximum width of the table (exluding LOBs). To avoid breaking the limit all the * time we limit the length of the character columns to CHAR_MAX_LENTH, NATIONAL_CHAR_LENGTH for national * characters, and BINARY_MAX_LENGTH for binary types. - * */ public MimerSQLDialect() { super(); @@ -57,188 +57,145 @@ registerColumnType( Types.CHAR, "NCHAR(1)" ); registerColumnType( Types.VARCHAR, NATIONAL_CHAR_LENGTH, "NATIONAL CHARACTER VARYING($l)" ); registerColumnType( Types.VARCHAR, "NCLOB($l)" ); - registerColumnType( Types.LONGVARCHAR, "CLOB($1)"); + registerColumnType( Types.LONGVARCHAR, "CLOB($1)" ); registerColumnType( Types.FLOAT, "FLOAT" ); registerColumnType( Types.DOUBLE, "DOUBLE PRECISION" ); registerColumnType( Types.DATE, "DATE" ); registerColumnType( Types.TIME, "TIME" ); registerColumnType( Types.TIMESTAMP, "TIMESTAMP" ); registerColumnType( Types.VARBINARY, BINARY_MAX_LENGTH, "BINARY VARYING($l)" ); registerColumnType( Types.VARBINARY, "BLOB($1)" ); - registerColumnType( Types.LONGVARBINARY, "BLOB($1)"); + registerColumnType( Types.LONGVARBINARY, "BLOB($1)" ); registerColumnType( Types.BINARY, BINARY_MAX_LENGTH, "BINARY" ); registerColumnType( Types.BINARY, "BLOB($1)" ); registerColumnType( Types.NUMERIC, "NUMERIC(19, $l)" ); registerColumnType( Types.BLOB, "BLOB($l)" ); registerColumnType( Types.CLOB, "NCLOB($l)" ); - registerFunction("abs", new StandardSQLFunction("abs") ); - registerFunction("sign", new StandardSQLFunction("sign", Hibernate.INTEGER) ); - registerFunction("ceiling", new StandardSQLFunction("ceiling") ); - registerFunction("floor", new StandardSQLFunction("floor") ); - registerFunction("round", new StandardSQLFunction("round") ); + registerFunction( "abs", new StandardSQLFunction( "abs" ) ); + registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) ); + registerFunction( "ceiling", new StandardSQLFunction( "ceiling" ) ); + registerFunction( "floor", new StandardSQLFunction( "floor" ) ); + registerFunction( "round", new StandardSQLFunction( "round" ) ); - registerFunction("dacos", new StandardSQLFunction("dacos", Hibernate.DOUBLE) ); - registerFunction("acos", new StandardSQLFunction("dacos", Hibernate.DOUBLE) ); - registerFunction("dasin", new StandardSQLFunction("dasin", Hibernate.DOUBLE) ); - registerFunction("asin", new StandardSQLFunction("dasin", Hibernate.DOUBLE) ); - registerFunction("datan", new StandardSQLFunction("datan", Hibernate.DOUBLE) ); - registerFunction("atan", new StandardSQLFunction("datan", Hibernate.DOUBLE) ); - registerFunction("datan2", new StandardSQLFunction("datan2", Hibernate.DOUBLE) ); - registerFunction("atan2", new StandardSQLFunction("datan2", Hibernate.DOUBLE) ); - registerFunction("dcos", new StandardSQLFunction("dcos", Hibernate.DOUBLE) ); - registerFunction("cos", new StandardSQLFunction("dcos", Hibernate.DOUBLE) ); - registerFunction("dcot", new StandardSQLFunction("dcot", Hibernate.DOUBLE) ); - registerFunction("cot", new StandardSQLFunction("dcot", Hibernate.DOUBLE) ); - registerFunction("ddegrees", new StandardSQLFunction("ddegrees", Hibernate.DOUBLE) ); - registerFunction("degrees", new StandardSQLFunction("ddegrees", Hibernate.DOUBLE) ); - registerFunction("dexp", new StandardSQLFunction("dexp", Hibernate.DOUBLE) ); - registerFunction("exp", new StandardSQLFunction("dexp", Hibernate.DOUBLE) ); - registerFunction("dlog", new StandardSQLFunction("dlog", Hibernate.DOUBLE) ); - registerFunction("log", new StandardSQLFunction("dlog", Hibernate.DOUBLE) ); - registerFunction("dlog10", new StandardSQLFunction("dlog10", Hibernate.DOUBLE) ); - registerFunction("log10", new StandardSQLFunction("dlog10", Hibernate.DOUBLE) ); - registerFunction("dradian", new StandardSQLFunction("dradian", Hibernate.DOUBLE) ); - registerFunction("radian", new StandardSQLFunction("dradian", Hibernate.DOUBLE) ); - registerFunction("dsin", new StandardSQLFunction("dsin", Hibernate.DOUBLE) ); - registerFunction("sin", new StandardSQLFunction("dsin", Hibernate.DOUBLE) ); - registerFunction("soundex", new StandardSQLFunction("soundex", Hibernate.STRING) ); - registerFunction("dsqrt", new StandardSQLFunction("dsqrt", Hibernate.DOUBLE) ); - registerFunction("sqrt", new StandardSQLFunction("dsqrt", Hibernate.DOUBLE) ); - registerFunction("dtan", new StandardSQLFunction("dtan", Hibernate.DOUBLE) ); - registerFunction("tan", new StandardSQLFunction("dtan", Hibernate.DOUBLE) ); - registerFunction("dpower", new StandardSQLFunction("dpower") ); - registerFunction("power", new StandardSQLFunction("dpower") ); + registerFunction( "dacos", new StandardSQLFunction( "dacos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "acos", new StandardSQLFunction( "dacos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "dasin", new StandardSQLFunction( "dasin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "asin", new StandardSQLFunction( "dasin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "datan", new StandardSQLFunction( "datan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "atan", new StandardSQLFunction( "datan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "datan2", new StandardSQLFunction( "datan2", StandardBasicTypes.DOUBLE ) ); + registerFunction( "atan2", new StandardSQLFunction( "datan2", StandardBasicTypes.DOUBLE ) ); + registerFunction( "dcos", new StandardSQLFunction( "dcos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cos", new StandardSQLFunction( "dcos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "dcot", new StandardSQLFunction( "dcot", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cot", new StandardSQLFunction( "dcot", StandardBasicTypes.DOUBLE ) ); + registerFunction( "ddegrees", new StandardSQLFunction( "ddegrees", StandardBasicTypes.DOUBLE ) ); + registerFunction( "degrees", new StandardSQLFunction( "ddegrees", StandardBasicTypes.DOUBLE ) ); + registerFunction( "dexp", new StandardSQLFunction( "dexp", StandardBasicTypes.DOUBLE ) ); + registerFunction( "exp", new StandardSQLFunction( "dexp", StandardBasicTypes.DOUBLE ) ); + registerFunction( "dlog", new StandardSQLFunction( "dlog", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log", new StandardSQLFunction( "dlog", StandardBasicTypes.DOUBLE ) ); + registerFunction( "dlog10", new StandardSQLFunction( "dlog10", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log10", new StandardSQLFunction( "dlog10", StandardBasicTypes.DOUBLE ) ); + registerFunction( "dradian", new StandardSQLFunction( "dradian", StandardBasicTypes.DOUBLE ) ); + registerFunction( "radian", new StandardSQLFunction( "dradian", StandardBasicTypes.DOUBLE ) ); + registerFunction( "dsin", new StandardSQLFunction( "dsin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sin", new StandardSQLFunction( "dsin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "soundex", new StandardSQLFunction( "soundex", StandardBasicTypes.STRING ) ); + registerFunction( "dsqrt", new StandardSQLFunction( "dsqrt", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sqrt", new StandardSQLFunction( "dsqrt", StandardBasicTypes.DOUBLE ) ); + registerFunction( "dtan", new StandardSQLFunction( "dtan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "tan", new StandardSQLFunction( "dtan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "dpower", new StandardSQLFunction( "dpower" ) ); + registerFunction( "power", new StandardSQLFunction( "dpower" ) ); - registerFunction("date", new StandardSQLFunction("date", Hibernate.DATE) ); - registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER) ); - registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER) ); - registerFunction("time", new StandardSQLFunction("time", Hibernate.TIME) ); - registerFunction("timestamp", new StandardSQLFunction("timestamp", Hibernate.TIMESTAMP) ); - registerFunction("week", new StandardSQLFunction("week", Hibernate.INTEGER) ); + registerFunction( "date", new StandardSQLFunction( "date", StandardBasicTypes.DATE ) ); + registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", StandardBasicTypes.INTEGER ) ); + registerFunction( "time", new StandardSQLFunction( "time", StandardBasicTypes.TIME ) ); + registerFunction( "timestamp", new StandardSQLFunction( "timestamp", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "week", new StandardSQLFunction( "week", StandardBasicTypes.INTEGER ) ); - registerFunction("varchar", new StandardSQLFunction("varchar", Hibernate.STRING) ); - registerFunction("real", new StandardSQLFunction("real", Hibernate.FLOAT) ); - registerFunction("bigint", new StandardSQLFunction("bigint", Hibernate.LONG) ); - registerFunction("char", new StandardSQLFunction("char", Hibernate.CHARACTER) ); - registerFunction("integer", new StandardSQLFunction("integer", Hibernate.INTEGER) ); - registerFunction("smallint", new StandardSQLFunction("smallint", Hibernate.SHORT) ); + registerFunction( "varchar", new StandardSQLFunction( "varchar", StandardBasicTypes.STRING ) ); + registerFunction( "real", new StandardSQLFunction( "real", StandardBasicTypes.FLOAT ) ); + registerFunction( "bigint", new StandardSQLFunction( "bigint", StandardBasicTypes.LONG ) ); + registerFunction( "char", new StandardSQLFunction( "char", StandardBasicTypes.CHARACTER ) ); + registerFunction( "integer", new StandardSQLFunction( "integer", StandardBasicTypes.INTEGER ) ); + registerFunction( "smallint", new StandardSQLFunction( "smallint", StandardBasicTypes.SHORT ) ); - registerFunction("ascii_char", new StandardSQLFunction("ascii_char", Hibernate.CHARACTER) ); - registerFunction("ascii_code", new StandardSQLFunction("ascii_code", Hibernate.STRING)); - registerFunction("unicode_char", new StandardSQLFunction("unicode_char", Hibernate.LONG)); - registerFunction("unicode_code", new StandardSQLFunction("unicode_code", Hibernate.STRING)); - registerFunction("upper", new StandardSQLFunction("upper") ); - registerFunction("lower", new StandardSQLFunction("lower") ); - registerFunction("char_length", new StandardSQLFunction("char_length", Hibernate.LONG) ); - registerFunction("bit_length", new StandardSQLFunction("bit_length", Hibernate.STRING)); + registerFunction( "ascii_char", new StandardSQLFunction( "ascii_char", StandardBasicTypes.CHARACTER ) ); + registerFunction( "ascii_code", new StandardSQLFunction( "ascii_code", StandardBasicTypes.STRING ) ); + registerFunction( "unicode_char", new StandardSQLFunction( "unicode_char", StandardBasicTypes.LONG ) ); + registerFunction( "unicode_code", new StandardSQLFunction( "unicode_code", StandardBasicTypes.STRING ) ); + registerFunction( "upper", new StandardSQLFunction( "upper" ) ); + registerFunction( "lower", new StandardSQLFunction( "lower" ) ); + registerFunction( "char_length", new StandardSQLFunction( "char_length", StandardBasicTypes.LONG ) ); + registerFunction( "bit_length", new StandardSQLFunction( "bit_length", StandardBasicTypes.STRING ) ); - getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "true"); - getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, "50"); + getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "true" ); + getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, "50" ); } - /** - * The syntax used to add a column to a table - */ + + @Override public String getAddColumnString() { return "add column"; } - /** - * We do not have to drop constraints before we drop the table - */ + @Override public boolean dropConstraints() { return false; } - /** - * TODO: Check if Mimer SQL cannot handle the way DB2 does - */ + @Override public boolean supportsIdentityColumns() { return false; } - /** - * Mimer SQL supports sequences - * @return boolean - */ + @Override public boolean supportsSequences() { return true; } - /** - * The syntax used to get the next value of a sequence in Mimer SQL - */ + @Override public String getSequenceNextValString(String sequenceName) { return "select next_value of " + sequenceName + " from system.onerow"; } - /** - * The syntax used to create a sequence. Since we presume the sequences will be used as keys, - * we make them unique. - */ + @Override public String getCreateSequenceString(String sequenceName) { return "create unique sequence " + sequenceName; } - /** - * The syntax used to drop sequences - */ + @Override public String getDropSequenceString(String sequenceName) { return "drop sequence " + sequenceName + " restrict"; } - /** - * Mimer SQL does not support limit - */ + @Override public boolean supportsLimit() { return false; } - /** - * The syntax for using cascade on constraints - */ + @Override public String getCascadeConstraintsString() { return " cascade"; } - /** - * The syntax for fetching all sequnces avialable in the current schema. - */ + @Override public String getQuerySequencesString() { return "select sequence_schema || '.' || sequence_name from information_schema.ext_sequences"; } - /** - * Does the FOR UPDATE OF syntax specify particular - * columns? - */ + @Override public boolean forUpdateOfColumns() { return false; } - /** - * Support the FOR UPDATE syntax? For now, returns false since - * the current version of the Mimer SQL JDBC Driver does not support - * updatable resultsets. Otherwise, Mimer SQL actually supports the for update syntax. - * @return boolean - */ - public boolean supportsForUpdate() { - return false; - } - - - /** - * For now, simply return false since we don't updatable result sets. - */ + @Override public boolean supportsOuterJoinForUpdate() { return false; } } - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQL5Dialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQL5Dialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQL5Dialect.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQL5Dialect.java 30 Jul 2014 16:15:52 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,21 +20,55 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; +import java.sql.SQLException; import java.sql.Types; +import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter; +import org.hibernate.exception.spi.ViolatedConstraintNameExtracter; +import org.hibernate.internal.util.JdbcExceptionHelper; + /** * An SQL dialect for MySQL 5.x specific features. * * @author Steve Ebersole */ public class MySQL5Dialect extends MySQLDialect { + @Override protected void registerVarcharTypes() { registerColumnType( Types.VARCHAR, "longtext" ); // registerColumnType( Types.VARCHAR, 16777215, "mediumtext" ); registerColumnType( Types.VARCHAR, 65535, "varchar($l)" ); + registerColumnType( Types.LONGVARCHAR, "longtext" ); } + + @Override + public boolean supportsColumnCheck() { + return false; + } + + public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() { + return EXTRACTER; + } + + private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { + + public String extractConstraintName(SQLException sqle) { + try { + final int sqlState = Integer.valueOf( JdbcExceptionHelper.extractSqlState( sqle ) ).intValue(); + switch ( sqlState ) { + case 23000: + return extractUsingTemplate( " for key '", "'", sqle.getMessage() ); + default: + return null; + } + } + catch ( NumberFormatException nfe ) { + return null; + } + } + }; + } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQL5InnoDBDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQL5InnoDBDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQL5InnoDBDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQL5InnoDBDialect.java 30 Jul 2014 16:15:51 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,25 +20,27 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; -/** - * @author Gavin King, Scott Marlow +/** A Dialect for MySQL 5 using InnoDB engine + * + * @author Gavin King, + * @author Scott Marlow */ public class MySQL5InnoDBDialect extends MySQL5Dialect { - + @Override public boolean supportsCascadeDelete() { return true; } - + + @Override public String getTableTypeString() { return " ENGINE=InnoDB"; } + @Override public boolean hasSelfReferentialForeignKeyBug() { return true; } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQLDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQLDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQLDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQLDialect.java 30 Jul 2014 16:15:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; @@ -29,19 +28,29 @@ import java.sql.SQLException; import java.sql.Types; -import org.hibernate.Hibernate; +import org.hibernate.JDBCException; +import org.hibernate.NullPrecedence; import org.hibernate.cfg.Environment; import org.hibernate.dialect.function.NoArgSQLFunction; import org.hibernate.dialect.function.StandardSQLFunction; -import org.hibernate.util.StringHelper; +import org.hibernate.exception.LockAcquisitionException; +import org.hibernate.exception.LockTimeoutException; +import org.hibernate.exception.spi.SQLExceptionConversionDelegate; +import org.hibernate.internal.util.JdbcExceptionHelper; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.type.StandardBasicTypes; /** * An SQL dialect for MySQL (prior to 5.x). * * @author Gavin King */ +@SuppressWarnings("deprecation") public class MySQLDialect extends Dialect { + /** + * Constructs a MySQLDialect + */ public MySQLDialect() { super(); registerColumnType( Types.BIT, "bit" ); @@ -52,13 +61,17 @@ registerColumnType( Types.CHAR, "char(1)" ); registerColumnType( Types.FLOAT, "float" ); registerColumnType( Types.DOUBLE, "double precision" ); + registerColumnType( Types.BOOLEAN, "bit" ); // HHH-6935 registerColumnType( Types.DATE, "date" ); registerColumnType( Types.TIME, "time" ); registerColumnType( Types.TIMESTAMP, "datetime" ); registerColumnType( Types.VARBINARY, "longblob" ); registerColumnType( Types.VARBINARY, 16777215, "mediumblob" ); registerColumnType( Types.VARBINARY, 65535, "blob" ); registerColumnType( Types.VARBINARY, 255, "tinyblob" ); + registerColumnType( Types.BINARY, "binary($l)" ); + registerColumnType( Types.LONGVARBINARY, "longblob" ); + registerColumnType( Types.LONGVARBINARY, 16777215, "mediumblob" ); registerColumnType( Types.NUMERIC, "decimal($p,$s)" ); registerColumnType( Types.BLOB, "longblob" ); // registerColumnType( Types.BLOB, 16777215, "mediumblob" ); @@ -68,306 +81,383 @@ // registerColumnType( Types.CLOB, 65535, "text" ); registerVarcharTypes(); - registerFunction("ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) ); - registerFunction("bin", new StandardSQLFunction("bin", Hibernate.STRING) ); - registerFunction("char_length", new StandardSQLFunction("char_length", Hibernate.LONG) ); - registerFunction("character_length", new StandardSQLFunction("character_length", Hibernate.LONG) ); - registerFunction("lcase", new StandardSQLFunction("lcase") ); - registerFunction("lower", new StandardSQLFunction("lower") ); - registerFunction("length", new StandardSQLFunction("length", Hibernate.LONG) ); - registerFunction("ltrim", new StandardSQLFunction("ltrim") ); - registerFunction("ord", new StandardSQLFunction("ord", Hibernate.INTEGER) ); - registerFunction("quote", new StandardSQLFunction("quote") ); - registerFunction("reverse", new StandardSQLFunction("reverse") ); - registerFunction("rtrim", new StandardSQLFunction("rtrim") ); - registerFunction("soundex", new StandardSQLFunction("soundex") ); - registerFunction("space", new StandardSQLFunction("space", Hibernate.STRING) ); - registerFunction("ucase", new StandardSQLFunction("ucase") ); - registerFunction("upper", new StandardSQLFunction("upper") ); - registerFunction("unhex", new StandardSQLFunction("unhex", Hibernate.STRING) ); + registerFunction( "ascii", new StandardSQLFunction( "ascii", StandardBasicTypes.INTEGER ) ); + registerFunction( "bin", new StandardSQLFunction( "bin", StandardBasicTypes.STRING ) ); + registerFunction( "char_length", new StandardSQLFunction( "char_length", StandardBasicTypes.LONG ) ); + registerFunction( "character_length", new StandardSQLFunction( "character_length", StandardBasicTypes.LONG ) ); + registerFunction( "lcase", new StandardSQLFunction( "lcase" ) ); + registerFunction( "lower", new StandardSQLFunction( "lower" ) ); + registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) ); + registerFunction( "ord", new StandardSQLFunction( "ord", StandardBasicTypes.INTEGER ) ); + registerFunction( "quote", new StandardSQLFunction( "quote" ) ); + registerFunction( "reverse", new StandardSQLFunction( "reverse" ) ); + registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) ); + registerFunction( "soundex", new StandardSQLFunction( "soundex" ) ); + registerFunction( "space", new StandardSQLFunction( "space", StandardBasicTypes.STRING ) ); + registerFunction( "ucase", new StandardSQLFunction( "ucase" ) ); + registerFunction( "upper", new StandardSQLFunction( "upper" ) ); + registerFunction( "unhex", new StandardSQLFunction( "unhex", StandardBasicTypes.STRING ) ); - registerFunction("abs", new StandardSQLFunction("abs") ); - registerFunction("sign", new StandardSQLFunction("sign", Hibernate.INTEGER) ); + registerFunction( "abs", new StandardSQLFunction( "abs" ) ); + registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) ); - registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) ); - registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) ); - registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) ); - registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) ); - registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) ); - registerFunction("crc32", new StandardSQLFunction("crc32", Hibernate.LONG) ); - registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) ); - registerFunction("ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) ); - registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE) ); - registerFunction("log2", new StandardSQLFunction("log2", Hibernate.DOUBLE) ); - registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) ); - registerFunction("pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) ); - registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE) ); - registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) ); - registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) ); - registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) ); + registerFunction( "acos", new StandardSQLFunction( "acos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "asin", new StandardSQLFunction( "asin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "atan", new StandardSQLFunction( "atan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cos", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cot", new StandardSQLFunction( "cot", StandardBasicTypes.DOUBLE ) ); + registerFunction( "crc32", new StandardSQLFunction( "crc32", StandardBasicTypes.LONG ) ); + registerFunction( "exp", new StandardSQLFunction( "exp", StandardBasicTypes.DOUBLE ) ); + registerFunction( "ln", new StandardSQLFunction( "ln", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log", new StandardSQLFunction( "log", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log2", new StandardSQLFunction( "log2", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log10", new StandardSQLFunction( "log10", StandardBasicTypes.DOUBLE ) ); + registerFunction( "pi", new NoArgSQLFunction( "pi", StandardBasicTypes.DOUBLE ) ); + registerFunction( "rand", new NoArgSQLFunction( "rand", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sin", new StandardSQLFunction( "sin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sqrt", new StandardSQLFunction( "sqrt", StandardBasicTypes.DOUBLE ) ); + registerFunction( "stddev", new StandardSQLFunction("std", StandardBasicTypes.DOUBLE) ); + registerFunction( "tan", new StandardSQLFunction( "tan", StandardBasicTypes.DOUBLE ) ); - registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) ); - registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) ); + registerFunction( "radians", new StandardSQLFunction( "radians", StandardBasicTypes.DOUBLE ) ); + registerFunction( "degrees", new StandardSQLFunction( "degrees", StandardBasicTypes.DOUBLE ) ); - registerFunction("ceiling", new StandardSQLFunction("ceiling", Hibernate.INTEGER) ); - registerFunction("ceil", new StandardSQLFunction("ceil", Hibernate.INTEGER) ); - registerFunction("floor", new StandardSQLFunction("floor", Hibernate.INTEGER) ); - registerFunction("round", new StandardSQLFunction("round", Hibernate.INTEGER) ); + registerFunction( "ceiling", new StandardSQLFunction( "ceiling", StandardBasicTypes.INTEGER ) ); + registerFunction( "ceil", new StandardSQLFunction( "ceil", StandardBasicTypes.INTEGER ) ); + registerFunction( "floor", new StandardSQLFunction( "floor", StandardBasicTypes.INTEGER ) ); + registerFunction( "round", new StandardSQLFunction( "round" ) ); - registerFunction("datediff", new StandardSQLFunction("datediff", Hibernate.INTEGER) ); - registerFunction("timediff", new StandardSQLFunction("timediff", Hibernate.TIME) ); - registerFunction("date_format", new StandardSQLFunction("date_format", Hibernate.STRING) ); + registerFunction( "datediff", new StandardSQLFunction( "datediff", StandardBasicTypes.INTEGER ) ); + registerFunction( "timediff", new StandardSQLFunction( "timediff", StandardBasicTypes.TIME ) ); + registerFunction( "date_format", new StandardSQLFunction( "date_format", StandardBasicTypes.STRING ) ); - registerFunction("curdate", new NoArgSQLFunction("curdate", Hibernate.DATE) ); - registerFunction("curtime", new NoArgSQLFunction("curtime", Hibernate.TIME) ); - registerFunction("current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) ); - registerFunction("current_time", new NoArgSQLFunction("current_time", Hibernate.TIME, false) ); - registerFunction("current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) ); - registerFunction("date", new StandardSQLFunction("date", Hibernate.DATE) ); - registerFunction("day", new StandardSQLFunction("day", Hibernate.INTEGER) ); - registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth", Hibernate.INTEGER) ); - registerFunction("dayname", new StandardSQLFunction("dayname", Hibernate.STRING) ); - registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER) ); - registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER) ); - registerFunction("from_days", new StandardSQLFunction("from_days", Hibernate.DATE) ); - registerFunction("from_unixtime", new StandardSQLFunction("from_unixtime", Hibernate.TIMESTAMP) ); - registerFunction("hour", new StandardSQLFunction("hour", Hibernate.INTEGER) ); - registerFunction("last_day", new StandardSQLFunction("last_day", Hibernate.DATE) ); - registerFunction("localtime", new NoArgSQLFunction("localtime", Hibernate.TIMESTAMP) ); - registerFunction("localtimestamp", new NoArgSQLFunction("localtimestamp", Hibernate.TIMESTAMP) ); - registerFunction("microseconds", new StandardSQLFunction("microseconds", Hibernate.INTEGER) ); - registerFunction("minute", new StandardSQLFunction("minute", Hibernate.INTEGER) ); - registerFunction("month", new StandardSQLFunction("month", Hibernate.INTEGER) ); - registerFunction("monthname", new StandardSQLFunction("monthname", Hibernate.STRING) ); - registerFunction("now", new NoArgSQLFunction("now", Hibernate.TIMESTAMP) ); - registerFunction("quarter", new StandardSQLFunction("quarter", Hibernate.INTEGER) ); - registerFunction("second", new StandardSQLFunction("second", Hibernate.INTEGER) ); - registerFunction("sec_to_time", new StandardSQLFunction("sec_to_time", Hibernate.TIME) ); - registerFunction("sysdate", new NoArgSQLFunction("sysdate", Hibernate.TIMESTAMP) ); - registerFunction("time", new StandardSQLFunction("time", Hibernate.TIME) ); - registerFunction("timestamp", new StandardSQLFunction("timestamp", Hibernate.TIMESTAMP) ); - registerFunction("time_to_sec", new StandardSQLFunction("time_to_sec", Hibernate.INTEGER) ); - registerFunction("to_days", new StandardSQLFunction("to_days", Hibernate.LONG) ); - registerFunction("unix_timestamp", new StandardSQLFunction("unix_timestamp", Hibernate.LONG) ); - registerFunction("utc_date", new NoArgSQLFunction("utc_date", Hibernate.STRING) ); - registerFunction("utc_time", new NoArgSQLFunction("utc_time", Hibernate.STRING) ); - registerFunction("utc_timestamp", new NoArgSQLFunction("utc_timestamp", Hibernate.STRING) ); - registerFunction("week", new StandardSQLFunction("week", Hibernate.INTEGER) ); - registerFunction("weekday", new StandardSQLFunction("weekday", Hibernate.INTEGER) ); - registerFunction("weekofyear", new StandardSQLFunction("weekofyear", Hibernate.INTEGER) ); - registerFunction("year", new StandardSQLFunction("year", Hibernate.INTEGER) ); - registerFunction("yearweek", new StandardSQLFunction("yearweek", Hibernate.INTEGER) ); + registerFunction( "curdate", new NoArgSQLFunction( "curdate", StandardBasicTypes.DATE ) ); + registerFunction( "curtime", new NoArgSQLFunction( "curtime", StandardBasicTypes.TIME ) ); + registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE, false ) ); + registerFunction( "current_time", new NoArgSQLFunction( "current_time", StandardBasicTypes.TIME, false ) ); + registerFunction( "current_timestamp", new NoArgSQLFunction( "current_timestamp", StandardBasicTypes.TIMESTAMP, false ) ); + registerFunction( "date", new StandardSQLFunction( "date", StandardBasicTypes.DATE ) ); + registerFunction( "day", new StandardSQLFunction( "day", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofmonth", new StandardSQLFunction( "dayofmonth", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayname", new StandardSQLFunction( "dayname", StandardBasicTypes.STRING ) ); + registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", StandardBasicTypes.INTEGER ) ); + registerFunction( "from_days", new StandardSQLFunction( "from_days", StandardBasicTypes.DATE ) ); + registerFunction( "from_unixtime", new StandardSQLFunction( "from_unixtime", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "hour", new StandardSQLFunction( "hour", StandardBasicTypes.INTEGER ) ); + registerFunction( "last_day", new StandardSQLFunction( "last_day", StandardBasicTypes.DATE ) ); + registerFunction( "localtime", new NoArgSQLFunction( "localtime", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "localtimestamp", new NoArgSQLFunction( "localtimestamp", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "microseconds", new StandardSQLFunction( "microseconds", StandardBasicTypes.INTEGER ) ); + registerFunction( "minute", new StandardSQLFunction( "minute", StandardBasicTypes.INTEGER ) ); + registerFunction( "month", new StandardSQLFunction( "month", StandardBasicTypes.INTEGER ) ); + registerFunction( "monthname", new StandardSQLFunction( "monthname", StandardBasicTypes.STRING ) ); + registerFunction( "now", new NoArgSQLFunction( "now", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "quarter", new StandardSQLFunction( "quarter", StandardBasicTypes.INTEGER ) ); + registerFunction( "second", new StandardSQLFunction( "second", StandardBasicTypes.INTEGER ) ); + registerFunction( "sec_to_time", new StandardSQLFunction( "sec_to_time", StandardBasicTypes.TIME ) ); + registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "time", new StandardSQLFunction( "time", StandardBasicTypes.TIME ) ); + registerFunction( "timestamp", new StandardSQLFunction( "timestamp", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "time_to_sec", new StandardSQLFunction( "time_to_sec", StandardBasicTypes.INTEGER ) ); + registerFunction( "to_days", new StandardSQLFunction( "to_days", StandardBasicTypes.LONG ) ); + registerFunction( "unix_timestamp", new StandardSQLFunction( "unix_timestamp", StandardBasicTypes.LONG ) ); + registerFunction( "utc_date", new NoArgSQLFunction( "utc_date", StandardBasicTypes.STRING ) ); + registerFunction( "utc_time", new NoArgSQLFunction( "utc_time", StandardBasicTypes.STRING ) ); + registerFunction( "utc_timestamp", new NoArgSQLFunction( "utc_timestamp", StandardBasicTypes.STRING ) ); + registerFunction( "week", new StandardSQLFunction( "week", StandardBasicTypes.INTEGER ) ); + registerFunction( "weekday", new StandardSQLFunction( "weekday", StandardBasicTypes.INTEGER ) ); + registerFunction( "weekofyear", new StandardSQLFunction( "weekofyear", StandardBasicTypes.INTEGER ) ); + registerFunction( "year", new StandardSQLFunction( "year", StandardBasicTypes.INTEGER ) ); + registerFunction( "yearweek", new StandardSQLFunction( "yearweek", StandardBasicTypes.INTEGER ) ); - registerFunction("hex", new StandardSQLFunction("hex", Hibernate.STRING) ); - registerFunction("oct", new StandardSQLFunction("oct", Hibernate.STRING) ); + registerFunction( "hex", new StandardSQLFunction( "hex", StandardBasicTypes.STRING ) ); + registerFunction( "oct", new StandardSQLFunction( "oct", StandardBasicTypes.STRING ) ); - registerFunction("octet_length", new StandardSQLFunction("octet_length", Hibernate.LONG) ); - registerFunction("bit_length", new StandardSQLFunction("bit_length", Hibernate.LONG) ); + registerFunction( "octet_length", new StandardSQLFunction( "octet_length", StandardBasicTypes.LONG ) ); + registerFunction( "bit_length", new StandardSQLFunction( "bit_length", StandardBasicTypes.LONG ) ); - registerFunction("bit_count", new StandardSQLFunction("bit_count", Hibernate.LONG) ); - registerFunction("encrypt", new StandardSQLFunction("encrypt", Hibernate.STRING) ); - registerFunction("md5", new StandardSQLFunction("md5", Hibernate.STRING) ); - registerFunction("sha1", new StandardSQLFunction("sha1", Hibernate.STRING) ); - registerFunction("sha", new StandardSQLFunction("sha", Hibernate.STRING) ); + registerFunction( "bit_count", new StandardSQLFunction( "bit_count", StandardBasicTypes.LONG ) ); + registerFunction( "encrypt", new StandardSQLFunction( "encrypt", StandardBasicTypes.STRING ) ); + registerFunction( "md5", new StandardSQLFunction( "md5", StandardBasicTypes.STRING ) ); + registerFunction( "sha1", new StandardSQLFunction( "sha1", StandardBasicTypes.STRING ) ); + registerFunction( "sha", new StandardSQLFunction( "sha", StandardBasicTypes.STRING ) ); - registerFunction( "concat", new StandardSQLFunction( "concat", Hibernate.STRING ) ); + registerFunction( "concat", new StandardSQLFunction( "concat", StandardBasicTypes.STRING ) ); - getDefaultProperties().setProperty(Environment.MAX_FETCH_DEPTH, "2"); - getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE); + getDefaultProperties().setProperty( Environment.MAX_FETCH_DEPTH, "2" ); + getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE ); } protected void registerVarcharTypes() { registerColumnType( Types.VARCHAR, "longtext" ); // registerColumnType( Types.VARCHAR, 16777215, "mediumtext" ); // registerColumnType( Types.VARCHAR, 65535, "text" ); registerColumnType( Types.VARCHAR, 255, "varchar($l)" ); + registerColumnType( Types.LONGVARCHAR, "longtext" ); } + @Override public String getAddColumnString() { return "add column"; } - + + @Override public boolean qualifyIndexName() { return false; } + @Override public boolean supportsIdentityColumns() { return true; } - + + @Override public String getIdentitySelectString() { return "select last_insert_id()"; } + @Override public String getIdentityColumnString() { - return "not null auto_increment"; //starts with 1, implicitly + //starts with 1, implicitly + return "not null auto_increment"; } + @Override public String getAddForeignKeyConstraintString( - String constraintName, - String[] foreignKey, - String referencedTable, - String[] primaryKey, boolean referencesPrimaryKey - ) { - String cols = StringHelper.join(", ", foreignKey); - return new StringBuffer(30) - .append(" add index ") - .append(constraintName) - .append(" (") - .append(cols) - .append("), add constraint ") - .append(constraintName) - .append(" foreign key (") - .append(cols) - .append(") references ") - .append(referencedTable) - .append(" (") - .append( StringHelper.join(", ", primaryKey) ) - .append(')') - .toString(); + String constraintName, + String[] foreignKey, + String referencedTable, + String[] primaryKey, + boolean referencesPrimaryKey) { + final String cols = StringHelper.join( ", ", foreignKey ); + final String referencedCols = StringHelper.join( ", ", primaryKey ); + return String.format( + " add constraint %s foreign key (%s) references %s (%s)", + constraintName, + cols, + referencedTable, + referencedCols + ); } + @Override public boolean supportsLimit() { return true; } - + + @Override public String getDropForeignKeyString() { return " drop foreign key "; } + @Override public String getLimitString(String sql, boolean hasOffset) { - return new StringBuffer( sql.length()+20 ) - .append(sql) - .append( hasOffset ? " limit ?, ?" : " limit ?") - .toString(); + return sql + (hasOffset ? " limit ?, ?" : " limit ?"); } - - /* - * Temporary, until MySQL fix Connector/J bug - */ - /*public String getLimitString(String sql, int offset, int limit) { - StringBuffer buf = new StringBuffer( sql.length()+20 ) - .append(sql); - if (offset>0) { - buf.append(" limit ") - .append(offset) - .append(", ") - .append(limit); - } - else { - buf.append(" limit ") - .append(limit); - } - return buf.toString(); - }*/ - /* - * Temporary, until MySQL fix Connector/J bug - */ - /*public boolean supportsVariableLimit() { - return false; - }*/ - + @Override public char closeQuote() { return '`'; } + @Override public char openQuote() { return '`'; } + @Override public boolean supportsIfExistsBeforeTableName() { return true; } + @Override public String getSelectGUIDString() { return "select uuid()"; } + @Override public boolean supportsCascadeDelete() { return false; } - + + @Override public String getTableComment(String comment) { return " comment='" + comment + "'"; } + @Override public String getColumnComment(String comment) { return " comment '" + comment + "'"; } + @Override public boolean supportsTemporaryTables() { return true; } + @Override public String getCreateTemporaryTableString() { return "create temporary table if not exists"; } + @Override + public String getDropTemporaryTableString() { + return "drop temporary table"; + } + + @Override + public Boolean performTemporaryTableDDLInIsolation() { + // because we [drop *temporary* table...] we do not + // have to doAfterTransactionCompletion these in isolation. + return Boolean.FALSE; + } + + @Override public String getCastTypeName(int code) { - if ( code==Types.INTEGER ) { - return "signed"; + switch ( code ) { + case Types.INTEGER: + case Types.BIGINT: + case Types.SMALLINT: + return "signed"; + case Types.FLOAT: + case Types.NUMERIC: + case Types.REAL: + return "decimal"; + case Types.VARCHAR: + return "char"; + case Types.VARBINARY: + return "binary"; + default: + return super.getCastTypeName( code ); } - else if ( code==Types.VARCHAR ) { - return "char"; - } - else if ( code==Types.VARBINARY ) { - return "binary"; - } - else { - return super.getCastTypeName( code ); - } } + @Override public boolean supportsCurrentTimestampSelection() { return true; } + @Override public boolean isCurrentTimestampSelectStringCallable() { return false; } + @Override public String getCurrentTimestampSelectString() { return "select now()"; } + @Override public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException { return col; - } - + } + + @Override public ResultSet getResultSet(CallableStatement ps) throws SQLException { - boolean isResultSet = ps.execute(); - while (!isResultSet && ps.getUpdateCount() != -1) { - isResultSet = ps.getMoreResults(); - } + boolean isResultSet = ps.execute(); + while ( !isResultSet && ps.getUpdateCount() != -1 ) { + isResultSet = ps.getMoreResults(); + } return ps.getResultSet(); } + @Override public boolean supportsRowValueConstructorSyntax() { return true; } - public Boolean performTemporaryTableDDLInIsolation() { - return Boolean.FALSE; + @Override + public String renderOrderByElement(String expression, String collation, String order, NullPrecedence nulls) { + final StringBuilder orderByElement = new StringBuilder(); + if ( nulls != NullPrecedence.NONE ) { + // Workaround for NULLS FIRST / LAST support. + orderByElement.append( "case when " ).append( expression ).append( " is null then " ); + if ( nulls == NullPrecedence.FIRST ) { + orderByElement.append( "0 else 1" ); + } + else { + orderByElement.append( "1 else 0" ); + } + orderByElement.append( " end, " ); + } + // Nulls precedence has already been handled so passing NONE value. + orderByElement.append( super.renderOrderByElement( expression, collation, order, NullPrecedence.NONE ) ); + return orderByElement.toString(); } + // locking support + @Override + public String getForUpdateString() { + return " for update"; + } + + @Override + public String getWriteLockString(int timeout) { + return " for update"; + } + + @Override + public String getReadLockString(int timeout) { + return " lock in share mode"; + } + + // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public boolean supportsEmptyInList() { return false; } + @Override public boolean areStringComparisonsCaseInsensitive() { return true; } + @Override public boolean supportsLobValueChangePropogation() { // note: at least my local MySQL 5.1 install shows this not working... return false; } + @Override public boolean supportsSubqueryOnMutatingTable() { return false; } -} \ No newline at end of file + + @Override + public boolean supportsLockTimeouts() { + // yes, we do handle "lock timeout" conditions in the exception conversion delegate, + // but that's a hardcoded lock timeout period across the whole entire MySQL database. + // MySQL does not support specifying lock timeouts as part of the SQL statement, which is really + // what this meta method is asking. + return false; + } + + @Override + public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() { + return new SQLExceptionConversionDelegate() { + @Override + public JDBCException convert(SQLException sqlException, String message, String sql) { + final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException ); + + if ( "41000".equals( sqlState ) ) { + return new LockTimeoutException( message, sqlException, sql ); + } + + if ( "40001".equals( sqlState ) ) { + return new LockAcquisitionException( message, sqlException, sql ); + } + + return null; + } + }; + } + + @Override + public String getNotExpression(String expression) { + return "not (" + expression + ")"; + } +} Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQLInnoDBDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQLInnoDBDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQLInnoDBDialect.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQLInnoDBDialect.java 30 Jul 2014 16:15:52 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,25 +20,27 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; /** + * A Dialect for MySQL using InnoDB engine + * * @author Gavin King */ public class MySQLInnoDBDialect extends MySQLDialect { - + @Override public boolean supportsCascadeDelete() { return true; } - + + @Override public String getTableTypeString() { return " type=InnoDB"; } + @Override public boolean hasSelfReferentialForeignKeyBug() { return true; } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQLMyISAMDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQLMyISAMDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQLMyISAMDialect.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/MySQLMyISAMDialect.java 30 Jul 2014 16:15:51 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,21 +20,22 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; /** + * A Dialect for MySQL using the MyISAM engine + * * @author Gavin King */ public class MySQLMyISAMDialect extends MySQLDialect { - + @Override public String getTableTypeString() { return " type=MyISAM"; } + @Override public boolean dropConstraints() { return false; } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle10gDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle10gDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle10gDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle10gDialect.java 30 Jul 2014 16:15:54 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,30 +20,51 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; -import org.hibernate.sql.JoinFragment; +import org.hibernate.LockOptions; import org.hibernate.sql.ANSIJoinFragment; +import org.hibernate.sql.JoinFragment; - /** * A dialect specifically for use with Oracle 10g. *

    * The main difference between this dialect and {@link Oracle9iDialect} - * is the use of "ANSI join syntax" here... + * is the use of "ANSI join syntax". * * @author Steve Ebersole */ public class Oracle10gDialect extends Oracle9iDialect { - + /** + * Constructs a Oracle10gDialect + */ public Oracle10gDialect() { super(); } + @Override public JoinFragment createOuterJoinFragment() { return new ANSIJoinFragment(); } + @Override + public String getWriteLockString(int timeout) { + if ( timeout == LockOptions.SKIP_LOCKED ) { + return getForUpdateSkipLockedString(); + } + else { + return super.getWriteLockString( timeout ); + } + } + + @Override + public String getForUpdateSkipLockedString() { + return " for update skip locked"; + } + + @Override + public String getForUpdateSkipLockedString(String aliases) { + return getForUpdateString() + " of " + aliases + " skip locked"; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle8iDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle8iDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle8iDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle8iDialect.java 30 Jul 2014 16:15:52 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,50 +20,61 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; -import java.sql.Types; -import java.sql.SQLException; -import java.sql.ResultSet; import java.sql.CallableStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.util.List; +import org.hibernate.JDBCException; +import org.hibernate.QueryTimeoutException; +import org.hibernate.annotations.common.util.StringHelper; +import org.hibernate.cfg.Environment; +import org.hibernate.dialect.function.NoArgSQLFunction; +import org.hibernate.dialect.function.NvlFunction; +import org.hibernate.dialect.function.SQLFunctionTemplate; +import org.hibernate.dialect.function.StandardSQLFunction; +import org.hibernate.dialect.function.VarArgsSQLFunction; +import org.hibernate.exception.ConstraintViolationException; +import org.hibernate.exception.LockAcquisitionException; +import org.hibernate.exception.LockTimeoutException; +import org.hibernate.exception.spi.SQLExceptionConversionDelegate; +import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter; +import org.hibernate.exception.spi.ViolatedConstraintNameExtracter; +import org.hibernate.internal.util.JdbcExceptionHelper; +import org.hibernate.procedure.internal.StandardCallableStatementSupport; +import org.hibernate.procedure.spi.CallableStatementSupport; import org.hibernate.sql.CaseFragment; import org.hibernate.sql.DecodeCaseFragment; import org.hibernate.sql.JoinFragment; import org.hibernate.sql.OracleJoinFragment; -import org.hibernate.cfg.Environment; -import org.hibernate.dialect.function.StandardSQLFunction; -import org.hibernate.dialect.function.NoArgSQLFunction; -import org.hibernate.dialect.function.VarArgsSQLFunction; -import org.hibernate.dialect.function.SQLFunctionTemplate; -import org.hibernate.dialect.function.NvlFunction; -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; -import org.hibernate.util.ReflectHelper; -import org.hibernate.exception.ViolatedConstraintNameExtracter; -import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter; -import org.hibernate.exception.JDBCExceptionHelper; +import org.hibernate.type.StandardBasicTypes; +import org.hibernate.type.descriptor.sql.BitTypeDescriptor; +import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; /** * A dialect for Oracle 8i. * * @author Steve Ebersole */ +@SuppressWarnings("deprecation") public class Oracle8iDialect extends Dialect { + private static final int PARAM_LIST_SIZE_LIMIT = 1000; + /** + * Constructs a Oracle8iDialect + */ public Oracle8iDialect() { super(); registerCharacterTypeMappings(); registerNumericTypeMappings(); registerDateTimeTypeMappings(); registerLargeObjectTypeMappings(); - registerReverseHibernateTypeMappings(); - registerFunctions(); - registerDefaultProperties(); } @@ -84,6 +95,8 @@ registerColumnType( Types.DOUBLE, "double precision" ); registerColumnType( Types.NUMERIC, "number($p,$s)" ); registerColumnType( Types.DECIMAL, "number($p,$s)" ); + + registerColumnType( Types.BOOLEAN, "number(1,0)" ); } protected void registerDateTimeTypeMappings() { @@ -93,96 +106,102 @@ } protected void registerLargeObjectTypeMappings() { + registerColumnType( Types.BINARY, 2000, "raw($l)" ); + registerColumnType( Types.BINARY, "long raw" ); + registerColumnType( Types.VARBINARY, 2000, "raw($l)" ); registerColumnType( Types.VARBINARY, "long raw" ); registerColumnType( Types.BLOB, "blob" ); registerColumnType( Types.CLOB, "clob" ); + + registerColumnType( Types.LONGVARCHAR, "long" ); + registerColumnType( Types.LONGVARBINARY, "long raw" ); } protected void registerReverseHibernateTypeMappings() { } protected void registerFunctions() { registerFunction( "abs", new StandardSQLFunction("abs") ); - registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) ); + registerFunction( "sign", new StandardSQLFunction("sign", StandardBasicTypes.INTEGER) ); - registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) ); - registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) ); - registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) ); - registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) ); - registerFunction( "cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) ); - registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) ); - registerFunction( "ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) ); - registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) ); - registerFunction( "sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) ); - registerFunction( "stddev", new StandardSQLFunction("stddev", Hibernate.DOUBLE) ); - registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) ); - registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) ); - registerFunction( "tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) ); - registerFunction( "variance", new StandardSQLFunction("variance", Hibernate.DOUBLE) ); + registerFunction( "acos", new StandardSQLFunction("acos", StandardBasicTypes.DOUBLE) ); + registerFunction( "asin", new StandardSQLFunction("asin", StandardBasicTypes.DOUBLE) ); + registerFunction( "atan", new StandardSQLFunction("atan", StandardBasicTypes.DOUBLE) ); + registerFunction( "bitand", new StandardSQLFunction("bitand") ); + registerFunction( "cos", new StandardSQLFunction("cos", StandardBasicTypes.DOUBLE) ); + registerFunction( "cosh", new StandardSQLFunction("cosh", StandardBasicTypes.DOUBLE) ); + registerFunction( "exp", new StandardSQLFunction("exp", StandardBasicTypes.DOUBLE) ); + registerFunction( "ln", new StandardSQLFunction("ln", StandardBasicTypes.DOUBLE) ); + registerFunction( "sin", new StandardSQLFunction("sin", StandardBasicTypes.DOUBLE) ); + registerFunction( "sinh", new StandardSQLFunction("sinh", StandardBasicTypes.DOUBLE) ); + registerFunction( "stddev", new StandardSQLFunction("stddev", StandardBasicTypes.DOUBLE) ); + registerFunction( "sqrt", new StandardSQLFunction("sqrt", StandardBasicTypes.DOUBLE) ); + registerFunction( "tan", new StandardSQLFunction("tan", StandardBasicTypes.DOUBLE) ); + registerFunction( "tanh", new StandardSQLFunction("tanh", StandardBasicTypes.DOUBLE) ); + registerFunction( "variance", new StandardSQLFunction("variance", StandardBasicTypes.DOUBLE) ); registerFunction( "round", new StandardSQLFunction("round") ); registerFunction( "trunc", new StandardSQLFunction("trunc") ); registerFunction( "ceil", new StandardSQLFunction("ceil") ); registerFunction( "floor", new StandardSQLFunction("floor") ); - registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) ); + registerFunction( "chr", new StandardSQLFunction("chr", StandardBasicTypes.CHARACTER) ); registerFunction( "initcap", new StandardSQLFunction("initcap") ); registerFunction( "lower", new StandardSQLFunction("lower") ); registerFunction( "ltrim", new StandardSQLFunction("ltrim") ); registerFunction( "rtrim", new StandardSQLFunction("rtrim") ); registerFunction( "soundex", new StandardSQLFunction("soundex") ); registerFunction( "upper", new StandardSQLFunction("upper") ); - registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) ); - registerFunction( "length", new StandardSQLFunction("length", Hibernate.LONG) ); + registerFunction( "ascii", new StandardSQLFunction("ascii", StandardBasicTypes.INTEGER) ); - registerFunction( "to_char", new StandardSQLFunction("to_char", Hibernate.STRING) ); - registerFunction( "to_date", new StandardSQLFunction("to_date", Hibernate.TIMESTAMP) ); + registerFunction( "to_char", new StandardSQLFunction("to_char", StandardBasicTypes.STRING) ); + registerFunction( "to_date", new StandardSQLFunction("to_date", StandardBasicTypes.TIMESTAMP) ); - registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) ); - registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", Hibernate.TIME, false) ); - registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) ); + registerFunction( "current_date", new NoArgSQLFunction("current_date", StandardBasicTypes.DATE, false) ); + registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIME, false) ); + registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", StandardBasicTypes.TIMESTAMP, false) ); - registerFunction( "last_day", new StandardSQLFunction("last_day", Hibernate.DATE) ); - registerFunction( "sysdate", new NoArgSQLFunction("sysdate", Hibernate.DATE, false) ); - registerFunction( "systimestamp", new NoArgSQLFunction("systimestamp", Hibernate.TIMESTAMP, false) ); - registerFunction( "uid", new NoArgSQLFunction("uid", Hibernate.INTEGER, false) ); - registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) ); + registerFunction( "last_day", new StandardSQLFunction("last_day", StandardBasicTypes.DATE) ); + registerFunction( "sysdate", new NoArgSQLFunction("sysdate", StandardBasicTypes.DATE, false) ); + registerFunction( "systimestamp", new NoArgSQLFunction("systimestamp", StandardBasicTypes.TIMESTAMP, false) ); + registerFunction( "uid", new NoArgSQLFunction("uid", StandardBasicTypes.INTEGER, false) ); + registerFunction( "user", new NoArgSQLFunction("user", StandardBasicTypes.STRING, false) ); - registerFunction( "rowid", new NoArgSQLFunction("rowid", Hibernate.LONG, false) ); - registerFunction( "rownum", new NoArgSQLFunction("rownum", Hibernate.LONG, false) ); + registerFunction( "rowid", new NoArgSQLFunction("rowid", StandardBasicTypes.LONG, false) ); + registerFunction( "rownum", new NoArgSQLFunction("rownum", StandardBasicTypes.LONG, false) ); // Multi-param string dialect functions... - registerFunction( "concat", new VarArgsSQLFunction(Hibernate.STRING, "", "||", "") ); - registerFunction( "instr", new StandardSQLFunction("instr", Hibernate.INTEGER) ); - registerFunction( "instrb", new StandardSQLFunction("instrb", Hibernate.INTEGER) ); - registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) ); - registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) ); - registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) ); - registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) ); - registerFunction( "substrb", new StandardSQLFunction("substrb", Hibernate.STRING) ); - registerFunction( "translate", new StandardSQLFunction("translate", Hibernate.STRING) ); + registerFunction( "concat", new VarArgsSQLFunction(StandardBasicTypes.STRING, "", "||", "") ); + registerFunction( "instr", new StandardSQLFunction("instr", StandardBasicTypes.INTEGER) ); + registerFunction( "instrb", new StandardSQLFunction("instrb", StandardBasicTypes.INTEGER) ); + registerFunction( "lpad", new StandardSQLFunction("lpad", StandardBasicTypes.STRING) ); + registerFunction( "replace", new StandardSQLFunction("replace", StandardBasicTypes.STRING) ); + registerFunction( "rpad", new StandardSQLFunction("rpad", StandardBasicTypes.STRING) ); + registerFunction( "substr", new StandardSQLFunction("substr", StandardBasicTypes.STRING) ); + registerFunction( "substrb", new StandardSQLFunction("substrb", StandardBasicTypes.STRING) ); + registerFunction( "translate", new StandardSQLFunction("translate", StandardBasicTypes.STRING) ); - registerFunction( "substring", new StandardSQLFunction( "substr", Hibernate.STRING ) ); - registerFunction( "locate", new SQLFunctionTemplate( Hibernate.INTEGER, "instr(?2,?1)" ) ); - registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "vsize(?1)*8" ) ); + registerFunction( "substring", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) ); + registerFunction( "locate", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "instr(?2,?1)" ) ); + registerFunction( "bit_length", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "vsize(?1)*8" ) ); registerFunction( "coalesce", new NvlFunction() ); // Multi-param numeric dialect functions... - registerFunction( "atan2", new StandardSQLFunction("atan2", Hibernate.FLOAT) ); - registerFunction( "log", new StandardSQLFunction("log", Hibernate.INTEGER) ); - registerFunction( "mod", new StandardSQLFunction("mod", Hibernate.INTEGER) ); + registerFunction( "atan2", new StandardSQLFunction("atan2", StandardBasicTypes.FLOAT) ); + registerFunction( "log", new StandardSQLFunction("log", StandardBasicTypes.INTEGER) ); + registerFunction( "mod", new StandardSQLFunction("mod", StandardBasicTypes.INTEGER) ); registerFunction( "nvl", new StandardSQLFunction("nvl") ); registerFunction( "nvl2", new StandardSQLFunction("nvl2") ); - registerFunction( "power", new StandardSQLFunction("power", Hibernate.FLOAT) ); + registerFunction( "power", new StandardSQLFunction("power", StandardBasicTypes.FLOAT) ); // Multi-param date dialect functions... - registerFunction( "add_months", new StandardSQLFunction("add_months", Hibernate.DATE) ); - registerFunction( "months_between", new StandardSQLFunction("months_between", Hibernate.FLOAT) ); - registerFunction( "next_day", new StandardSQLFunction("next_day", Hibernate.DATE) ); + registerFunction( "add_months", new StandardSQLFunction("add_months", StandardBasicTypes.DATE) ); + registerFunction( "months_between", new StandardSQLFunction("months_between", StandardBasicTypes.FLOAT) ); + registerFunction( "next_day", new StandardSQLFunction("next_day", StandardBasicTypes.DATE) ); - registerFunction( "str", new StandardSQLFunction("to_char", Hibernate.STRING) ); + registerFunction( "str", new StandardSQLFunction("to_char", StandardBasicTypes.STRING) ); } protected void registerDefaultProperties() { @@ -195,49 +214,57 @@ getDefaultProperties().setProperty( Environment.USE_GET_GENERATED_KEYS, "false" ); } + @Override + protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) { + return sqlCode == Types.BOOLEAN ? BitTypeDescriptor.INSTANCE : super.getSqlTypeDescriptorOverride( sqlCode ); + } + // features which change between 8i, 9i, and 10g ~~~~~~~~~~~~~~~~~~~~~~~~~~ - /** - * Support for the oracle proprietary join syntax... - * - * @return The orqacle join fragment - */ + @Override public JoinFragment createOuterJoinFragment() { return new OracleJoinFragment(); } + @Override + public String getCrossJoinSeparator() { + return ", "; + } + /** * Map case support to the Oracle DECODE function. Oracle did not * add support for CASE until 9i. - * - * @return The oracle CASE -> DECODE fragment + *

    + * {@inheritDoc} */ + @Override public CaseFragment createCaseFragment() { return new DecodeCaseFragment(); } + @Override public String getLimitString(String sql, boolean hasOffset) { sql = sql.trim(); boolean isForUpdate = false; - if ( sql.toLowerCase().endsWith(" for update") ) { + if ( sql.toLowerCase().endsWith( " for update" ) ) { sql = sql.substring( 0, sql.length()-11 ); isForUpdate = true; } - StringBuffer pagingSelect = new StringBuffer( sql.length()+100 ); + final StringBuilder pagingSelect = new StringBuilder( sql.length()+100 ); if (hasOffset) { - pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( "); + pagingSelect.append( "select * from ( select row_.*, rownum rownum_ from ( " ); } else { - pagingSelect.append("select * from ( "); + pagingSelect.append( "select * from ( " ); } - pagingSelect.append(sql); + pagingSelect.append( sql ); if (hasOffset) { - pagingSelect.append(" ) row_ ) where rownum_ <= ? and rownum_ > ?"); + pagingSelect.append( " ) row_ ) where rownum_ <= ? and rownum_ > ?" ); } else { - pagingSelect.append(" ) where rownum <= ?"); + pagingSelect.append( " ) where rownum <= ?" ); } if ( isForUpdate ) { @@ -258,6 +285,7 @@ return super.getSelectClauseNullString( sqlType ); } + @Override public String getSelectClauseNullString(int sqlType) { switch(sqlType) { case Types.VARCHAR: @@ -272,81 +300,101 @@ } } + @Override public String getCurrentTimestampSelectString() { return "select sysdate from dual"; } + @Override public String getCurrentTimestampSQLFunctionName() { return "sysdate"; } // features which remain constant across 8i, 9i, and 10g ~~~~~~~~~~~~~~~~~~ + @Override public String getAddColumnString() { return "add"; } + @Override public String getSequenceNextValString(String sequenceName) { return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual"; } + @Override public String getSelectSequenceNextValString(String sequenceName) { return sequenceName + ".nextval"; } + @Override public String getCreateSequenceString(String sequenceName) { - return "create sequence " + sequenceName; //starts with 1, implicitly + //starts with 1, implicitly + return "create sequence " + sequenceName; } + @Override public String getDropSequenceString(String sequenceName) { return "drop sequence " + sequenceName; } + @Override public String getCascadeConstraintsString() { return " cascade constraints"; } + @Override public boolean dropConstraints() { return false; } + @Override public String getForUpdateNowaitString() { return " for update nowait"; } + @Override public boolean supportsSequences() { return true; } + @Override public boolean supportsPooledSequences() { return true; } + @Override public boolean supportsLimit() { return true; } + @Override public String getForUpdateString(String aliases) { return getForUpdateString() + " of " + aliases; } + @Override public String getForUpdateNowaitString(String aliases) { return getForUpdateString() + " of " + aliases + " nowait"; } + @Override public boolean bindLimitParametersInReverseOrder() { return true; } + @Override public boolean useMaxForLimit() { return true; } + @Override public boolean forUpdateOfColumns() { return true; } + @Override public String getQuerySequencesString() { return " select sequence_name from all_sequences" + " union" @@ -356,15 +404,17 @@ + " and asq.sequence_owner = us.table_owner"; } + @Override public String getSelectGUIDString() { return "select rawtohex(sys_guid()) from dual"; } + @Override public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() { - return EXTRACTER; + return EXTRACTER; } - private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { + private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { /** * Extract the name of the violated constraint from the given SQLException. @@ -373,9 +423,9 @@ * @return The extracted constraint name. */ public String extractConstraintName(SQLException sqle) { - int errorCode = JDBCExceptionHelper.extractErrorCode(sqle); + final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle ); if ( errorCode == 1 || errorCode == 2291 || errorCode == 2292 ) { - return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() ); + return extractUsingTemplate( "(", ")", sqle.getMessage() ); } else if ( errorCode == 1400 ) { // simple nullability constraint @@ -388,74 +438,186 @@ }; - // not final-static to avoid possible classcast exceptions if using different oracle drivers. - int oracletypes_cursor_value = 0; - public int registerResultSetOutParameter(java.sql.CallableStatement statement,int col) throws SQLException { - if(oracletypes_cursor_value==0) { - try { - Class types = ReflectHelper.classForName("oracle.jdbc.driver.OracleTypes"); - oracletypes_cursor_value = types.getField("CURSOR").getInt(types.newInstance()); - } catch (Exception se) { - throw new HibernateException("Problem while trying to load or access OracleTypes.CURSOR value",se); + @Override + public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() { + return new SQLExceptionConversionDelegate() { + @Override + public JDBCException convert(SQLException sqlException, String message, String sql) { + // interpreting Oracle exceptions is much much more precise based on their specific vendor codes. + + final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException ); + + + // lock timeouts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + if ( errorCode == 30006 ) { + // ORA-30006: resource busy; acquire with WAIT timeout expired + throw new LockTimeoutException( message, sqlException, sql ); + } + else if ( errorCode == 54 ) { + // ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired + throw new LockTimeoutException( message, sqlException, sql ); + } + else if ( 4021 == errorCode ) { + // ORA-04021 timeout occurred while waiting to lock object + throw new LockTimeoutException( message, sqlException, sql ); + } + + + // deadlocks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + if ( 60 == errorCode ) { + // ORA-00060: deadlock detected while waiting for resource + return new LockAcquisitionException( message, sqlException, sql ); + } + else if ( 4020 == errorCode ) { + // ORA-04020 deadlock detected while trying to lock object + return new LockAcquisitionException( message, sqlException, sql ); + } + + + // query cancelled ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + if ( 1013 == errorCode ) { + // ORA-01013: user requested cancel of current operation + throw new QueryTimeoutException( message, sqlException, sql ); + } + + + // data integrity violation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + if ( 1407 == errorCode ) { + // ORA-01407: cannot update column to NULL + final String constraintName = getViolatedConstraintNameExtracter().extractConstraintName( sqlException ); + return new ConstraintViolationException( message, sqlException, sql, constraintName ); + } + + return null; } - } + }; + } + + @Override + public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException { // register the type of the out param - an Oracle specific type - statement.registerOutParameter(col, oracletypes_cursor_value); + statement.registerOutParameter( col, OracleTypesHelper.INSTANCE.getOracleCursorTypeSqlType() ); col++; return col; } + @Override public ResultSet getResultSet(CallableStatement ps) throws SQLException { ps.execute(); - return ( ResultSet ) ps.getObject( 1 ); + return (ResultSet) ps.getObject( 1 ); } + @Override public boolean supportsUnionAll() { return true; } + @Override public boolean supportsCommentOn() { return true; } + @Override public boolean supportsTemporaryTables() { return true; } + @Override public String generateTemporaryTableName(String baseTableName) { - String name = super.generateTemporaryTableName(baseTableName); + final String name = super.generateTemporaryTableName( baseTableName ); return name.length() > 30 ? name.substring( 1, 30 ) : name; } + @Override public String getCreateTemporaryTableString() { return "create global temporary table"; } + @Override public String getCreateTemporaryTablePostfix() { return "on commit delete rows"; } + @Override public boolean dropTemporaryTableAfterUse() { return false; } + @Override public boolean supportsCurrentTimestampSelection() { return true; } + @Override public boolean isCurrentTimestampSelectStringCallable() { return false; } - - // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + @Override public boolean supportsEmptyInList() { return false; } - + + @Override public boolean supportsExistsInSelect() { return false; } + @Override + public int getInExpressionCountLimit() { + return PARAM_LIST_SIZE_LIMIT; + } + + @Override + public boolean forceLobAsLastValue() { + return true; + } + + @Override + public boolean useFollowOnLocking() { + return true; + } + + @Override + public String getNotExpression( String expression ) { + return "not (" + expression + ")"; + } + + @Override + public String getQueryHintString(String sql, List hints) { + final String hint = StringHelper.join( ", ", hints.iterator() ); + + if ( StringHelper.isEmpty( hint ) ) { + return sql; + } + + final int pos = sql.indexOf( "select" ); + if ( pos > -1 ) { + final StringBuilder buffer = new StringBuilder( sql.length() + hint.length() + 8 ); + if ( pos > 0 ) { + buffer.append( sql.substring( 0, pos ) ); + } + buffer.append( "select /*+ " ).append( hint ).append( " */" ) + .append( sql.substring( pos + "select".length() ) ); + sql = buffer.toString(); + } + + return sql; + } + + @Override + public int getMaxAliasLength() { + // Oracle's max identifier length is 30, but Hibernate needs to add "uniqueing info" so we account for that, + return 20; + } + + @Override + public CallableStatementSupport getCallableStatementSupport() { + // Oracle supports returning cursors + return StandardCallableStatementSupport.REF_CURSOR_INSTANCE; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle9Dialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle9Dialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle9Dialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle9Dialect.java 30 Jul 2014 16:15:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; @@ -29,35 +28,45 @@ import java.sql.SQLException; import java.sql.Types; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; import org.hibernate.cfg.Environment; import org.hibernate.dialect.function.NoArgSQLFunction; import org.hibernate.dialect.function.NvlFunction; import org.hibernate.dialect.function.SQLFunctionTemplate; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.VarArgsSQLFunction; -import org.hibernate.exception.JDBCExceptionHelper; -import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter; -import org.hibernate.exception.ViolatedConstraintNameExtracter; -import org.hibernate.util.ReflectHelper; +import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter; +import org.hibernate.exception.spi.ViolatedConstraintNameExtracter; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.JdbcExceptionHelper; +import org.hibernate.type.StandardBasicTypes; +import org.jboss.logging.Logger; + /** * An SQL dialect for Oracle 9 (uses ANSI-style syntax where possible). * + * @author Gavin King + * @author David Channon + * * @deprecated Use either Oracle9iDialect or Oracle10gDialect instead - * @author Gavin King, David Channon */ +@SuppressWarnings("deprecation") +@Deprecated public class Oracle9Dialect extends Dialect { - private static final Logger log = LoggerFactory.getLogger( Oracle9Dialect.class ); + private static final int PARAM_LIST_SIZE_LIMIT = 1000; + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + Oracle9Dialect.class.getName() + ); + + /** + * Constructs a Oracle9Dialect + */ public Oracle9Dialect() { super(); - log.warn( "The Oracle9Dialect dialect has been deprecated; use either Oracle9iDialect or Oracle10gDialect instead" ); + LOG.deprecatedOracle9Dialect(); registerColumnType( Types.BIT, "number(1,0)" ); registerColumnType( Types.BIGINT, "number(19,0)" ); registerColumnType( Types.SMALLINT, "number(5,0)" ); @@ -82,208 +91,228 @@ // support the version taking an array of the names of the columns to // be returned (via its RETURNING clause). No other driver seems to // support this overloaded version. - getDefaultProperties().setProperty(Environment.USE_GET_GENERATED_KEYS, "false"); - getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "true"); - getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE); + getDefaultProperties().setProperty( Environment.USE_GET_GENERATED_KEYS, "false" ); + getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "true" ); + getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE ); - registerFunction( "abs", new StandardSQLFunction("abs") ); - registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) ); + registerFunction( "abs", new StandardSQLFunction( "abs" ) ); + registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) ); - registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) ); - registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) ); - registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) ); - registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) ); - registerFunction( "cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) ); - registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) ); - registerFunction( "ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) ); - registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) ); - registerFunction( "sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) ); - registerFunction( "stddev", new StandardSQLFunction("stddev", Hibernate.DOUBLE) ); - registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) ); - registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) ); - registerFunction( "tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) ); - registerFunction( "variance", new StandardSQLFunction("variance", Hibernate.DOUBLE) ); + registerFunction( "acos", new StandardSQLFunction( "acos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "asin", new StandardSQLFunction( "asin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "atan", new StandardSQLFunction( "atan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cos", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cosh", new StandardSQLFunction( "cosh", StandardBasicTypes.DOUBLE ) ); + registerFunction( "exp", new StandardSQLFunction( "exp", StandardBasicTypes.DOUBLE ) ); + registerFunction( "ln", new StandardSQLFunction( "ln", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sin", new StandardSQLFunction( "sin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sinh", new StandardSQLFunction( "sinh", StandardBasicTypes.DOUBLE ) ); + registerFunction( "stddev", new StandardSQLFunction( "stddev", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sqrt", new StandardSQLFunction( "sqrt", StandardBasicTypes.DOUBLE ) ); + registerFunction( "tan", new StandardSQLFunction( "tan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "tanh", new StandardSQLFunction( "tanh", StandardBasicTypes.DOUBLE ) ); + registerFunction( "variance", new StandardSQLFunction( "variance", StandardBasicTypes.DOUBLE ) ); - registerFunction( "round", new StandardSQLFunction("round") ); - registerFunction( "trunc", new StandardSQLFunction("trunc") ); - registerFunction( "ceil", new StandardSQLFunction("ceil") ); - registerFunction( "floor", new StandardSQLFunction("floor") ); + registerFunction( "round", new StandardSQLFunction( "round" ) ); + registerFunction( "trunc", new StandardSQLFunction( "trunc" ) ); + registerFunction( "ceil", new StandardSQLFunction( "ceil" ) ); + registerFunction( "floor", new StandardSQLFunction( "floor" ) ); - registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) ); - registerFunction( "initcap", new StandardSQLFunction("initcap") ); - registerFunction( "lower", new StandardSQLFunction("lower") ); - registerFunction( "ltrim", new StandardSQLFunction("ltrim") ); - registerFunction( "rtrim", new StandardSQLFunction("rtrim") ); - registerFunction( "soundex", new StandardSQLFunction("soundex") ); - registerFunction( "upper", new StandardSQLFunction("upper") ); - registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) ); - registerFunction( "length", new StandardSQLFunction("length", Hibernate.LONG) ); + registerFunction( "chr", new StandardSQLFunction( "chr", StandardBasicTypes.CHARACTER ) ); + registerFunction( "initcap", new StandardSQLFunction( "initcap" ) ); + registerFunction( "lower", new StandardSQLFunction( "lower" ) ); + registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) ); + registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) ); + registerFunction( "soundex", new StandardSQLFunction( "soundex" ) ); + registerFunction( "upper", new StandardSQLFunction( "upper" ) ); + registerFunction( "ascii", new StandardSQLFunction( "ascii", StandardBasicTypes.INTEGER ) ); - registerFunction( "to_char", new StandardSQLFunction("to_char", Hibernate.STRING) ); - registerFunction( "to_date", new StandardSQLFunction("to_date", Hibernate.TIMESTAMP) ); + registerFunction( "to_char", new StandardSQLFunction( "to_char", StandardBasicTypes.STRING ) ); + registerFunction( "to_date", new StandardSQLFunction( "to_date", StandardBasicTypes.TIMESTAMP ) ); - registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) ); - registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", Hibernate.TIME, false) ); - registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) ); - - registerFunction( "last_day", new StandardSQLFunction("last_day", Hibernate.DATE) ); - registerFunction( "sysdate", new NoArgSQLFunction("sysdate", Hibernate.DATE, false) ); - registerFunction( "systimestamp", new NoArgSQLFunction("systimestamp", Hibernate.TIMESTAMP, false) ); - registerFunction( "uid", new NoArgSQLFunction("uid", Hibernate.INTEGER, false) ); - registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) ); + registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE, false ) ); + registerFunction( "current_time", new NoArgSQLFunction( "current_timestamp", StandardBasicTypes.TIME, false ) ); + registerFunction( + "current_timestamp", new NoArgSQLFunction( + "current_timestamp", + StandardBasicTypes.TIMESTAMP, + false + ) + ); - registerFunction( "rowid", new NoArgSQLFunction("rowid", Hibernate.LONG, false) ); - registerFunction( "rownum", new NoArgSQLFunction("rownum", Hibernate.LONG, false) ); + registerFunction( "last_day", new StandardSQLFunction( "last_day", StandardBasicTypes.DATE ) ); + registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.DATE, false ) ); + registerFunction( "systimestamp", new NoArgSQLFunction( "systimestamp", StandardBasicTypes.TIMESTAMP, false ) ); + registerFunction( "uid", new NoArgSQLFunction( "uid", StandardBasicTypes.INTEGER, false ) ); + registerFunction( "user", new NoArgSQLFunction( "user", StandardBasicTypes.STRING, false ) ); + registerFunction( "rowid", new NoArgSQLFunction( "rowid", StandardBasicTypes.LONG, false ) ); + registerFunction( "rownum", new NoArgSQLFunction( "rownum", StandardBasicTypes.LONG, false ) ); + // Multi-param string dialect functions... - registerFunction( "concat", new VarArgsSQLFunction(Hibernate.STRING, "", "||", "") ); - registerFunction( "instr", new StandardSQLFunction("instr", Hibernate.INTEGER) ); - registerFunction( "instrb", new StandardSQLFunction("instrb", Hibernate.INTEGER) ); - registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) ); - registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) ); - registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) ); - registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) ); - registerFunction( "substrb", new StandardSQLFunction("substrb", Hibernate.STRING) ); - registerFunction( "translate", new StandardSQLFunction("translate", Hibernate.STRING) ); + registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "", "||", "" ) ); + registerFunction( "instr", new StandardSQLFunction( "instr", StandardBasicTypes.INTEGER ) ); + registerFunction( "instrb", new StandardSQLFunction( "instrb", StandardBasicTypes.INTEGER ) ); + registerFunction( "lpad", new StandardSQLFunction( "lpad", StandardBasicTypes.STRING ) ); + registerFunction( "replace", new StandardSQLFunction( "replace", StandardBasicTypes.STRING ) ); + registerFunction( "rpad", new StandardSQLFunction( "rpad", StandardBasicTypes.STRING ) ); + registerFunction( "substr", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) ); + registerFunction( "substrb", new StandardSQLFunction( "substrb", StandardBasicTypes.STRING ) ); + registerFunction( "translate", new StandardSQLFunction( "translate", StandardBasicTypes.STRING ) ); - registerFunction( "substring", new StandardSQLFunction( "substr", Hibernate.STRING ) ); - registerFunction( "locate", new SQLFunctionTemplate( Hibernate.INTEGER, "instr(?2,?1)" ) ); - registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "vsize(?1)*8" ) ); + registerFunction( "substring", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) ); + registerFunction( "locate", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "instr(?2,?1)" ) ); + registerFunction( "bit_length", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "vsize(?1)*8" ) ); registerFunction( "coalesce", new NvlFunction() ); // Multi-param numeric dialect functions... - registerFunction( "atan2", new StandardSQLFunction("atan2", Hibernate.FLOAT) ); - registerFunction( "log", new StandardSQLFunction("log", Hibernate.INTEGER) ); - registerFunction( "mod", new StandardSQLFunction("mod", Hibernate.INTEGER) ); - registerFunction( "nvl", new StandardSQLFunction("nvl") ); - registerFunction( "nvl2", new StandardSQLFunction("nvl2") ); - registerFunction( "power", new StandardSQLFunction("power", Hibernate.FLOAT) ); + registerFunction( "atan2", new StandardSQLFunction( "atan2", StandardBasicTypes.FLOAT ) ); + registerFunction( "log", new StandardSQLFunction( "log", StandardBasicTypes.INTEGER ) ); + registerFunction( "mod", new StandardSQLFunction( "mod", StandardBasicTypes.INTEGER ) ); + registerFunction( "nvl", new StandardSQLFunction( "nvl" ) ); + registerFunction( "nvl2", new StandardSQLFunction( "nvl2" ) ); + registerFunction( "power", new StandardSQLFunction( "power", StandardBasicTypes.FLOAT ) ); // Multi-param date dialect functions... - registerFunction( "add_months", new StandardSQLFunction("add_months", Hibernate.DATE) ); - registerFunction( "months_between", new StandardSQLFunction("months_between", Hibernate.FLOAT) ); - registerFunction( "next_day", new StandardSQLFunction("next_day", Hibernate.DATE) ); + registerFunction( "add_months", new StandardSQLFunction( "add_months", StandardBasicTypes.DATE ) ); + registerFunction( "months_between", new StandardSQLFunction( "months_between", StandardBasicTypes.FLOAT ) ); + registerFunction( "next_day", new StandardSQLFunction( "next_day", StandardBasicTypes.DATE ) ); - registerFunction( "str", new StandardSQLFunction("to_char", Hibernate.STRING) ); + registerFunction( "str", new StandardSQLFunction( "to_char", StandardBasicTypes.STRING ) ); } + @Override public String getAddColumnString() { return "add"; } + @Override public String getSequenceNextValString(String sequenceName) { return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual"; } + @Override public String getSelectSequenceNextValString(String sequenceName) { return sequenceName + ".nextval"; } + @Override public String getCreateSequenceString(String sequenceName) { - return "create sequence " + sequenceName; //starts with 1, implicitly + //starts with 1, implicitly + return "create sequence " + sequenceName; } + @Override public String getDropSequenceString(String sequenceName) { return "drop sequence " + sequenceName; } + @Override public String getCascadeConstraintsString() { return " cascade constraints"; } + @Override public boolean dropConstraints() { return false; } + @Override public String getForUpdateNowaitString() { return " for update nowait"; } + @Override public boolean supportsSequences() { return true; } + @Override public boolean supportsPooledSequences() { return true; } + @Override public boolean supportsLimit() { return true; } + @Override public String getLimitString(String sql, boolean hasOffset) { - + sql = sql.trim(); boolean isForUpdate = false; - if ( sql.toLowerCase().endsWith(" for update") ) { - sql = sql.substring( 0, sql.length()-11 ); + if ( sql.toLowerCase().endsWith( " for update" ) ) { + sql = sql.substring( 0, sql.length() - 11 ); isForUpdate = true; } - - StringBuffer pagingSelect = new StringBuffer( sql.length()+100 ); - if (hasOffset) { - pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( "); + + final StringBuilder pagingSelect = new StringBuilder( sql.length() + 100 ); + if ( hasOffset ) { + pagingSelect.append( "select * from ( select row_.*, rownum rownum_ from ( " ); } else { - pagingSelect.append("select * from ( "); + pagingSelect.append( "select * from ( " ); } - pagingSelect.append(sql); - if (hasOffset) { - pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?"); + pagingSelect.append( sql ); + if ( hasOffset ) { + pagingSelect.append( " ) row_ where rownum <= ?) where rownum_ > ?" ); } else { - pagingSelect.append(" ) where rownum <= ?"); + pagingSelect.append( " ) where rownum <= ?" ); } if ( isForUpdate ) { pagingSelect.append( " for update" ); } - + return pagingSelect.toString(); } + @Override public String getForUpdateString(String aliases) { return getForUpdateString() + " of " + aliases; } + @Override public String getForUpdateNowaitString(String aliases) { return getForUpdateString() + " of " + aliases + " nowait"; } + @Override public boolean bindLimitParametersInReverseOrder() { return true; } + @Override public boolean useMaxForLimit() { return true; } - + + @Override public boolean forUpdateOfColumns() { return true; } + @Override public String getQuerySequencesString() { return "select sequence_name from user_sequences"; } + @Override public String getSelectGUIDString() { return "select rawtohex(sys_guid()) from dual"; } - + + @Override public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() { - return EXTRACTER; + return EXTRACTER; } - private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { - - /** - * Extract the name of the violated constraint from the given SQLException. - * - * @param sqle The exception that was the result of the constraint violation. - * @return The extracted constraint name. - */ + private static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { + @Override public String extractConstraintName(SQLException sqle) { - int errorCode = JDBCExceptionHelper.extractErrorCode(sqle); + final int errorCode = JdbcExceptionHelper.extractErrorCode( sqle ); if ( errorCode == 1 || errorCode == 2291 || errorCode == 2292 ) { return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() ); } @@ -295,80 +324,90 @@ return null; } } - }; - // not final-static to avoid possible classcast exceptions if using different oracle drivers. - int oracletypes_cursor_value = 0; - public int registerResultSetOutParameter(java.sql.CallableStatement statement,int col) throws SQLException { - if(oracletypes_cursor_value==0) { - try { - Class types = ReflectHelper.classForName("oracle.jdbc.driver.OracleTypes"); - oracletypes_cursor_value = types.getField("CURSOR").getInt(types.newInstance()); - } catch (Exception se) { - throw new HibernateException("Problem while trying to load or access OracleTypes.CURSOR value",se); - } - } + @Override + public int registerResultSetOutParameter(java.sql.CallableStatement statement, int col) throws SQLException { // register the type of the out param - an Oracle specific type - statement.registerOutParameter(col, oracletypes_cursor_value); + statement.registerOutParameter( col, OracleTypesHelper.INSTANCE.getOracleCursorTypeSqlType() ); col++; return col; } - + + @Override public ResultSet getResultSet(CallableStatement ps) throws SQLException { ps.execute(); - return ( ResultSet ) ps.getObject( 1 ); + return (ResultSet) ps.getObject( 1 ); } + @Override public boolean supportsUnionAll() { return true; } - + + @Override public boolean supportsCommentOn() { return true; } + @Override public boolean supportsTemporaryTables() { return true; } + @Override public String generateTemporaryTableName(String baseTableName) { - String name = super.generateTemporaryTableName(baseTableName); + final String name = super.generateTemporaryTableName( baseTableName ); return name.length() > 30 ? name.substring( 1, 30 ) : name; } + @Override public String getCreateTemporaryTableString() { return "create global temporary table"; } + @Override public String getCreateTemporaryTablePostfix() { return "on commit delete rows"; } + @Override public boolean dropTemporaryTableAfterUse() { return false; } + @Override public boolean supportsCurrentTimestampSelection() { return true; } + @Override public String getCurrentTimestampSelectString() { return "select systimestamp from dual"; } + @Override public boolean isCurrentTimestampSelectStringCallable() { return false; } - - // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + @Override public boolean supportsEmptyInList() { return false; } + @Override public boolean supportsExistsInSelect() { return false; } + + @Override + public int getInExpressionCountLimit() { + return PARAM_LIST_SIZE_LIMIT; + } + + @Override + public String getNotExpression(String expression) { + return "not (" + expression + ")"; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle9iDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle9iDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle9iDialect.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/Oracle9iDialect.java 30 Jul 2014 16:15:54 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,82 +20,134 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; import java.sql.Types; -import org.hibernate.sql.CaseFragment; +import org.hibernate.LockOptions; import org.hibernate.sql.ANSICaseFragment; +import org.hibernate.sql.CaseFragment; /** * A dialect for Oracle 9i databases. *

    - * Unlike the older (deprecated) {@Link Oracl9Dialect), this version specifies - * to not use "ANSI join syntax" because 9i does not seem to properly - * handle it in all cases. + * Specifies to not use "ANSI join syntax" because 9i does not seem to properly handle it in all cases. * * @author Steve Ebersole */ public class Oracle9iDialect extends Oracle8iDialect { + @Override protected void registerCharacterTypeMappings() { registerColumnType( Types.CHAR, "char(1 char)" ); registerColumnType( Types.VARCHAR, 4000, "varchar2($l char)" ); registerColumnType( Types.VARCHAR, "long" ); } + @Override protected void registerDateTimeTypeMappings() { registerColumnType( Types.DATE, "date" ); registerColumnType( Types.TIME, "date" ); registerColumnType( Types.TIMESTAMP, "timestamp" ); } + @Override public CaseFragment createCaseFragment() { // Oracle did add support for ANSI CASE statements in 9i return new ANSICaseFragment(); } + @Override public String getLimitString(String sql, boolean hasOffset) { sql = sql.trim(); + String forUpdateClause = null; boolean isForUpdate = false; - if ( sql.toLowerCase().endsWith(" for update") ) { - sql = sql.substring( 0, sql.length()-11 ); + final int forUpdateIndex = sql.toLowerCase().lastIndexOf( "for update") ; + if ( forUpdateIndex > -1 ) { + // save 'for update ...' and then remove it + forUpdateClause = sql.substring( forUpdateIndex ); + sql = sql.substring( 0, forUpdateIndex-1 ); isForUpdate = true; } - StringBuffer pagingSelect = new StringBuffer( sql.length()+100 ); + final StringBuilder pagingSelect = new StringBuilder( sql.length() + 100 ); if (hasOffset) { - pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( "); + pagingSelect.append( "select * from ( select row_.*, rownum rownum_ from ( " ); } else { - pagingSelect.append("select * from ( "); + pagingSelect.append( "select * from ( " ); } - pagingSelect.append(sql); + pagingSelect.append( sql ); if (hasOffset) { - pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?"); + pagingSelect.append( " ) row_ where rownum <= ?) where rownum_ > ?" ); } else { - pagingSelect.append(" ) where rownum <= ?"); + pagingSelect.append( " ) where rownum <= ?" ); } if ( isForUpdate ) { - pagingSelect.append( " for update" ); + pagingSelect.append( " " ); + pagingSelect.append( forUpdateClause ); } return pagingSelect.toString(); } + @Override public String getSelectClauseNullString(int sqlType) { return getBasicSelectClauseNullString( sqlType ); } + @Override public String getCurrentTimestampSelectString() { return "select systimestamp from dual"; } + @Override public String getCurrentTimestampSQLFunctionName() { // the standard SQL function name is current_timestamp... return "current_timestamp"; } + + @Override + public String getForUpdateString() { + return " for update"; + } + + @Override + public String getWriteLockString(int timeout) { + if ( timeout == LockOptions.NO_WAIT ) { + return " for update nowait"; + } + else if ( timeout > 0 ) { + // convert from milliseconds to seconds + final float seconds = timeout / 1000.0f; + timeout = Math.round( seconds ); + return " for update wait " + timeout; + } + else { + return " for update"; + } + } + + @Override + public String getReadLockString(int timeout) { + return getWriteLockString( timeout ); + } + + /** + * HHH-4907, I don't know if oracle 8 supports this syntax, so I'd think it is better add this + * method here. Reopen this issue if you found/know 8 supports it. + *

    + * {@inheritDoc} + */ + @Override + public boolean supportsRowValueConstructorSyntaxInInList() { + return true; + } + + @Override + public boolean supportsTupleDistinctCounts() { + return false; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/OracleDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/OracleDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/OracleDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/OracleDialect.java 30 Jul 2014 16:15:54 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,78 +20,89 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; import java.sql.Types; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - +import org.hibernate.internal.CoreMessageLogger; import org.hibernate.sql.CaseFragment; import org.hibernate.sql.DecodeCaseFragment; import org.hibernate.sql.JoinFragment; import org.hibernate.sql.OracleJoinFragment; +import org.jboss.logging.Logger; + /** * An SQL dialect for Oracle, compatible with Oracle 8. * * @deprecated Use Oracle8iDialect instead. * @author Gavin King */ +@SuppressWarnings("deprecation") +@Deprecated public class OracleDialect extends Oracle9Dialect { + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + OracleDialect.class.getName() + ); - private static final Logger log = LoggerFactory.getLogger( OracleDialect.class ); - + /** + * Constructs a (DEPRECATED) Oracle9Dialect + */ public OracleDialect() { super(); - log.warn( "The OracleDialect dialect has been deprecated; use Oracle8iDialect instead" ); + LOG.deprecatedOracleDialect(); // Oracle8 and previous define only a "DATE" type which // is used to represent all aspects of date/time registerColumnType( Types.TIMESTAMP, "date" ); registerColumnType( Types.CHAR, "char(1)" ); registerColumnType( Types.VARCHAR, 4000, "varchar2($l)" ); } + @Override public JoinFragment createOuterJoinFragment() { return new OracleJoinFragment(); } + + @Override public CaseFragment createCaseFragment() { return new DecodeCaseFragment(); } + @Override public String getLimitString(String sql, boolean hasOffset) { sql = sql.trim(); boolean isForUpdate = false; - if ( sql.toLowerCase().endsWith(" for update") ) { + if ( sql.toLowerCase().endsWith( " for update" ) ) { sql = sql.substring( 0, sql.length()-11 ); isForUpdate = true; } - - StringBuffer pagingSelect = new StringBuffer( sql.length()+100 ); + + final StringBuilder pagingSelect = new StringBuilder( sql.length()+100 ); if (hasOffset) { - pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( "); + pagingSelect.append( "select * from ( select row_.*, rownum rownum_ from ( " ); } else { - pagingSelect.append("select * from ( "); + pagingSelect.append( "select * from ( " ); } - pagingSelect.append(sql); + pagingSelect.append( sql ); if (hasOffset) { - pagingSelect.append(" ) row_ ) where rownum_ <= ? and rownum_ > ?"); + pagingSelect.append( " ) row_ ) where rownum_ <= ? and rownum_ > ?" ); } else { - pagingSelect.append(" ) where rownum <= ?"); + pagingSelect.append( " ) where rownum <= ?" ); } if ( isForUpdate ) { pagingSelect.append( " for update" ); } - + return pagingSelect.toString(); } + @Override public String getSelectClauseNullString(int sqlType) { switch(sqlType) { case Types.VARCHAR: @@ -106,10 +117,12 @@ } } + @Override public String getCurrentTimestampSelectString() { return "select sysdate from dual"; } + @Override public String getCurrentTimestampSQLFunctionName() { return "sysdate"; } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/OracleTypesHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/PointbaseDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/PointbaseDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/PointbaseDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/PointbaseDialect.java 30 Jul 2014 16:15:55 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,33 +20,39 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; +import java.sql.Types; + +import org.hibernate.LockMode; import org.hibernate.dialect.lock.LockingStrategy; -import org.hibernate.dialect.lock.UpdateLockingStrategy; +import org.hibernate.dialect.lock.OptimisticForceIncrementLockingStrategy; +import org.hibernate.dialect.lock.OptimisticLockingStrategy; +import org.hibernate.dialect.lock.PessimisticForceIncrementLockingStrategy; +import org.hibernate.dialect.lock.PessimisticReadUpdateLockingStrategy; +import org.hibernate.dialect.lock.PessimisticWriteUpdateLockingStrategy; import org.hibernate.dialect.lock.SelectLockingStrategy; +import org.hibernate.dialect.lock.UpdateLockingStrategy; import org.hibernate.persister.entity.Lockable; -import org.hibernate.LockMode; -import java.sql.Types; - /** - * A Dialect for Pointbase. + * A Dialect for Pointbase. + * * @author Ed Mackenzie */ public class PointbaseDialect extends org.hibernate.dialect.Dialect { - /** * Creates new PointbaseDialect */ public PointbaseDialect() { super(); - registerColumnType( Types.BIT, "smallint" ); //no pointbase BIT + //no pointbase BIT + registerColumnType( Types.BIT, "smallint" ); registerColumnType( Types.BIGINT, "bigint" ); registerColumnType( Types.SMALLINT, "smallint" ); - registerColumnType( Types.TINYINT, "smallint" ); //no pointbase TINYINT + //no pointbase TINYINT + registerColumnType( Types.TINYINT, "smallint" ); registerColumnType( Types.INTEGER, "integer" ); registerColumnType( Types.CHAR, "char(1)" ); registerColumnType( Types.VARCHAR, "varchar($l)" ); @@ -63,25 +69,45 @@ registerColumnType( Types.NUMERIC, "numeric($p,$s)" ); } + @Override public String getAddColumnString() { return "add"; } + @Override public boolean dropConstraints() { return false; } + @Override public String getCascadeConstraintsString() { return " cascade"; } + @Override public String getForUpdateString() { return ""; } + @Override public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { // Pointbase has no known variation of a "SELECT ... FOR UPDATE" syntax... - if ( lockMode.greaterThan( LockMode.READ ) ) { + if ( lockMode==LockMode.PESSIMISTIC_FORCE_INCREMENT) { + return new PessimisticForceIncrementLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.PESSIMISTIC_WRITE) { + return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.PESSIMISTIC_READ) { + return new PessimisticReadUpdateLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.OPTIMISTIC) { + return new OptimisticLockingStrategy( lockable, lockMode); + } + else if ( lockMode==LockMode.OPTIMISTIC_FORCE_INCREMENT) { + return new OptimisticForceIncrementLockingStrategy( lockable, lockMode); + } + else if ( lockMode.greaterThan( LockMode.READ ) ) { return new UpdateLockingStrategy( lockable, lockMode ); } else { Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/PostgreSQL81Dialect.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/PostgreSQL82Dialect.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/PostgreSQL9Dialect.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/PostgreSQLDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/PostgreSQLDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/PostgreSQLDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/PostgreSQLDialect.java 30 Jul 2014 16:15:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,341 +20,20 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; -import java.sql.CallableStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; - -import org.hibernate.Hibernate; -import org.hibernate.cfg.Environment; -import org.hibernate.dialect.function.NoArgSQLFunction; -import org.hibernate.dialect.function.PositionSubstringFunction; -import org.hibernate.dialect.function.SQLFunctionTemplate; -import org.hibernate.dialect.function.StandardSQLFunction; -import org.hibernate.dialect.function.VarArgsSQLFunction; -import org.hibernate.exception.JDBCExceptionHelper; -import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter; -import org.hibernate.exception.ViolatedConstraintNameExtracter; -import org.hibernate.id.SequenceGenerator; - /** * An SQL dialect for Postgres + *

    + * For discussion of BLOB support in Postgres, as of 8.4, have a peek at + * http://jdbc.postgresql.org/documentation/84/binary-data.html. + * For the effects in regards to Hibernate see http://in.relation.to/15492.lace + * * @author Gavin King + * + * @deprecated use {@link PostgreSQL82Dialect} instead */ -public class PostgreSQLDialect extends Dialect { - - public PostgreSQLDialect() { - super(); - registerColumnType( Types.BIT, "bool" ); - registerColumnType( Types.BIGINT, "int8" ); - registerColumnType( Types.SMALLINT, "int2" ); - registerColumnType( Types.TINYINT, "int2" ); - registerColumnType( Types.INTEGER, "int4" ); - registerColumnType( Types.CHAR, "char(1)" ); - registerColumnType( Types.VARCHAR, "varchar($l)" ); - registerColumnType( Types.FLOAT, "float4" ); - registerColumnType( Types.DOUBLE, "float8" ); - registerColumnType( Types.DATE, "date" ); - registerColumnType( Types.TIME, "time" ); - registerColumnType( Types.TIMESTAMP, "timestamp" ); - registerColumnType( Types.VARBINARY, "bytea" ); - registerColumnType( Types.CLOB, "text" ); - registerColumnType( Types.BLOB, "oid" ); - registerColumnType( Types.NUMERIC, "numeric($p, $s)" ); - - registerFunction( "abs", new StandardSQLFunction("abs") ); - registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) ); - - registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) ); - registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) ); - registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) ); - registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) ); - registerFunction( "cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) ); - registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) ); - registerFunction( "ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) ); - registerFunction( "log", new StandardSQLFunction("log", Hibernate.DOUBLE) ); - registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) ); - registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) ); - registerFunction( "cbrt", new StandardSQLFunction("cbrt", Hibernate.DOUBLE) ); - registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) ); - registerFunction( "radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) ); - registerFunction( "degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) ); - - registerFunction( "stddev", new StandardSQLFunction("stddev", Hibernate.DOUBLE) ); - registerFunction( "variance", new StandardSQLFunction("variance", Hibernate.DOUBLE) ); - - registerFunction( "random", new NoArgSQLFunction("random", Hibernate.DOUBLE) ); - - registerFunction( "round", new StandardSQLFunction("round") ); - registerFunction( "trunc", new StandardSQLFunction("trunc") ); - registerFunction( "ceil", new StandardSQLFunction("ceil") ); - registerFunction( "floor", new StandardSQLFunction("floor") ); - - registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) ); - registerFunction( "lower", new StandardSQLFunction("lower") ); - registerFunction( "upper", new StandardSQLFunction("upper") ); - registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) ); - registerFunction( "initcap", new StandardSQLFunction("initcap") ); - registerFunction( "to_ascii", new StandardSQLFunction("to_ascii") ); - registerFunction( "quote_ident", new StandardSQLFunction("quote_ident", Hibernate.STRING) ); - registerFunction( "quote_literal", new StandardSQLFunction("quote_literal", Hibernate.STRING) ); - registerFunction( "md5", new StandardSQLFunction("md5") ); - registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) ); - registerFunction( "length", new StandardSQLFunction("length", Hibernate.LONG) ); - registerFunction( "char_length", new StandardSQLFunction("char_length", Hibernate.LONG) ); - registerFunction( "bit_length", new StandardSQLFunction("bit_length", Hibernate.LONG) ); - registerFunction( "octet_length", new StandardSQLFunction("octet_length", Hibernate.LONG) ); - - registerFunction( "age", new StandardSQLFunction("age") ); - registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) ); - registerFunction( "current_time", new NoArgSQLFunction("current_time", Hibernate.TIME, false) ); - registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) ); - registerFunction( "date_trunc", new StandardSQLFunction( "date_trunc", Hibernate.TIMESTAMP ) ); - registerFunction( "localtime", new NoArgSQLFunction("localtime", Hibernate.TIME, false) ); - registerFunction( "localtimestamp", new NoArgSQLFunction("localtimestamp", Hibernate.TIMESTAMP, false) ); - registerFunction( "now", new NoArgSQLFunction("now", Hibernate.TIMESTAMP) ); - registerFunction( "timeofday", new NoArgSQLFunction("timeofday", Hibernate.STRING) ); - - registerFunction( "current_user", new NoArgSQLFunction("current_user", Hibernate.STRING, false) ); - registerFunction( "session_user", new NoArgSQLFunction("session_user", Hibernate.STRING, false) ); - registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) ); - registerFunction( "current_database", new NoArgSQLFunction("current_database", Hibernate.STRING, true) ); - registerFunction( "current_schema", new NoArgSQLFunction("current_schema", Hibernate.STRING, true) ); - - registerFunction( "to_char", new StandardSQLFunction("to_char", Hibernate.STRING) ); - registerFunction( "to_date", new StandardSQLFunction("to_date", Hibernate.DATE) ); - registerFunction( "to_timestamp", new StandardSQLFunction("to_timestamp", Hibernate.TIMESTAMP) ); - registerFunction( "to_number", new StandardSQLFunction("to_number", Hibernate.BIG_DECIMAL) ); - - registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","||",")" ) ); - - registerFunction( "locate", new PositionSubstringFunction() ); - - registerFunction( "str", new SQLFunctionTemplate(Hibernate.STRING, "cast(?1 as varchar)") ); - - getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE); - } - - public String getAddColumnString() { - return "add column"; - } - - public String getSequenceNextValString(String sequenceName) { - return "select " + getSelectSequenceNextValString( sequenceName ); - } - - public String getSelectSequenceNextValString(String sequenceName) { - return "nextval ('" + sequenceName + "')"; - } - - public String getCreateSequenceString(String sequenceName) { - return "create sequence " + sequenceName; //starts with 1, implicitly - } - - public String getDropSequenceString(String sequenceName) { - return "drop sequence " + sequenceName; - } - - public String getCascadeConstraintsString() { - return "";//" cascade"; - } - public boolean dropConstraints() { - return true; - } - - public boolean supportsSequences() { - return true; - } - - public String getQuerySequencesString() { - return "select relname from pg_class where relkind='S'"; - } - - public boolean supportsLimit() { - return true; - } - - public String getLimitString(String sql, boolean hasOffset) { - return new StringBuffer( sql.length()+20 ) - .append(sql) - .append(hasOffset ? " limit ? offset ?" : " limit ?") - .toString(); - } - - public boolean bindLimitParametersInReverseOrder() { - return true; - } - - public boolean supportsIdentityColumns() { - return true; - } - - public String getForUpdateString(String aliases) { - return getForUpdateString() + " of " + aliases; - } - - public String getIdentitySelectString(String table, String column, int type) { - return new StringBuffer().append("select currval('") - .append(table) - .append('_') - .append(column) - .append("_seq')") - .toString(); - } - - public String getIdentityColumnString(int type) { - return type==Types.BIGINT ? - "bigserial not null" : - "serial not null"; - } - - public boolean hasDataTypeInIdentityColumn() { - return false; - } - - public String getNoColumnsInsertString() { - return "default values"; - } - - public Class getNativeIdentifierGeneratorClass() { - return SequenceGenerator.class; - } - - public boolean supportsOuterJoinForUpdate() { - return false; - } - - public boolean useInputStreamToInsertBlob() { - return false; - } - - public boolean supportsUnionAll() { - return true; - } - - /** - * Workaround for postgres bug #1453 - */ - public String getSelectClauseNullString(int sqlType) { - String typeName = getTypeName(sqlType, 1, 1, 0); - //trim off the length/precision/scale - int loc = typeName.indexOf('('); - if (loc>-1) { - typeName = typeName.substring(0, loc); - } - return "null::" + typeName; - } - - public boolean supportsCommentOn() { - return true; - } - - public boolean supportsTemporaryTables() { - return true; - } - - public String getCreateTemporaryTableString() { - return "create temporary table"; - } - - public String getCreateTemporaryTablePostfix() { - return "on commit drop"; - } - - /*public boolean dropTemporaryTableAfterUse() { - //we have to, because postgres sets current tx - //to rollback only after a failed create table - return true; - }*/ - - public boolean supportsCurrentTimestampSelection() { - return true; - } - - public boolean isCurrentTimestampSelectStringCallable() { - return false; - } - - public String getCurrentTimestampSelectString() { - return "select now()"; - } - - public String toBooleanValueString(boolean bool) { - return bool ? "true" : "false"; - } - - public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() { - return EXTRACTER; - } - - /** - * Constraint-name extractor for Postgres contraint violation exceptions. - * Orginally contributed by Denny Bartelt. - */ - private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { - public String extractConstraintName(SQLException sqle) { - try { - int sqlState = Integer.valueOf( JDBCExceptionHelper.extractSqlState(sqle)).intValue(); - switch (sqlState) { - // CHECK VIOLATION - case 23514: return extractUsingTemplate("violates check constraint \"","\"", sqle.getMessage()); - // UNIQUE VIOLATION - case 23505: return extractUsingTemplate("violates unique constraint \"","\"", sqle.getMessage()); - // FOREIGN KEY VIOLATION - case 23503: return extractUsingTemplate("violates foreign key constraint \"","\"", sqle.getMessage()); - // NOT NULL VIOLATION - case 23502: return extractUsingTemplate("null value in column \"","\" violates not-null constraint", sqle.getMessage()); - // TODO: RESTRICT VIOLATION - case 23001: return null; - // ALL OTHER - default: return null; - } - } catch (NumberFormatException nfe) { - return null; - } - } - }; - - public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException { - // Register the type of the out param - PostgreSQL uses Types.OTHER - statement.registerOutParameter(col, Types.OTHER); - col++; - return col; - } - - public ResultSet getResultSet(CallableStatement ps) throws SQLException { - ps.execute(); - ResultSet rs = (ResultSet) ps.getObject(1); - return rs; - } - - public boolean supportsPooledSequences() { - return true; - } - - //only necessary for postgre < 7.4 - //http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/doc/src/sgml/ref/create_sequence.sgml - protected String getCreateSequenceString(String sequenceName, int initialValue, int incrementSize) { - return getCreateSequenceString( sequenceName ) + " start " + initialValue + " increment " + incrementSize; - } - - // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -// seems to not really... -// public boolean supportsRowValueConstructorSyntax() { -// return true; -// } - - public boolean supportsEmptyInList() { - return false; - } - - public boolean supportsExpectedLobUsagePattern() { - // seems to have spotty LOB suppport - return false; - } -} \ No newline at end of file +@Deprecated +public class PostgreSQLDialect extends PostgreSQL82Dialect { +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/PostgresPlusDialect.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/ProgressDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/ProgressDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/ProgressDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/ProgressDialect.java 30 Jul 2014 16:15:54 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; @@ -43,6 +42,9 @@ * */ public class ProgressDialect extends Dialect { + /** + * Constructs a ProgressDialect + */ public ProgressDialect() { super(); registerColumnType( Types.BIT, "bit" ); @@ -61,22 +63,18 @@ registerColumnType( Types.NUMERIC, "numeric($p,$s)" ); } + @Override public boolean hasAlterTable(){ return false; } + @Override public String getAddColumnString() { return "add column"; } + @Override public boolean qualifyIndexName() { return false; } } - - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/RDMSOS2200Dialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/RDMSOS2200Dialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/RDMSOS2200Dialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/RDMSOS2200Dialect.java 30 Jul 2014 16:15:52 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,140 +20,151 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; +import java.sql.Types; + +import org.hibernate.LockMode; import org.hibernate.dialect.function.NoArgSQLFunction; -import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.SQLFunctionTemplate; +import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.lock.LockingStrategy; -import org.hibernate.dialect.lock.UpdateLockingStrategy; +import org.hibernate.dialect.lock.OptimisticForceIncrementLockingStrategy; +import org.hibernate.dialect.lock.OptimisticLockingStrategy; +import org.hibernate.dialect.lock.PessimisticForceIncrementLockingStrategy; +import org.hibernate.dialect.lock.PessimisticReadUpdateLockingStrategy; +import org.hibernate.dialect.lock.PessimisticWriteUpdateLockingStrategy; import org.hibernate.dialect.lock.SelectLockingStrategy; - -import java.sql.Types; -import org.hibernate.Hibernate; -import org.hibernate.LockMode; +import org.hibernate.dialect.lock.UpdateLockingStrategy; +import org.hibernate.internal.CoreMessageLogger; import org.hibernate.persister.entity.Lockable; import org.hibernate.sql.CaseFragment; import org.hibernate.sql.DecodeCaseFragment; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.hibernate.type.StandardBasicTypes; +import org.jboss.logging.Logger; + /** * This is the Hibernate dialect for the Unisys 2200 Relational Database (RDMS). * This dialect was developed for use with Hibernate 3.0.5. Other versions may * require modifications to the dialect. - * + *

    * Version History: * Also change the version displayed below in the constructor * 1.1 * 1.0 2005-10-24 CDH - First dated version for use with CP 11 * * @author Ploski and Hanson */ +@SuppressWarnings("deprecation") public class RDMSOS2200Dialect extends Dialect { - private static Logger log = LoggerFactory.getLogger(RDMSOS2200Dialect.class); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + RDMSOS2200Dialect.class.getName() + ); + /** + * Constructs a RDMSOS2200Dialect + */ public RDMSOS2200Dialect() { super(); - // Display the dialect version. - log.info("RDMSOS2200Dialect version: 1.0"); + // Display the dialect version. + LOG.rdmsOs2200Dialect(); - /** - * This section registers RDMS Biult-in Functions (BIFs) with Hibernate. - * The first parameter is the 'register' function name with Hibernate. - * The second parameter is the defined RDMS SQL Function and it's - * characteristics. If StandardSQLFunction(...) is used, the RDMS BIF - * name and the return type (if any) is specified. If - * SQLFunctionTemplate(...) is used, the return type and a template - * string is provided, plus an optional hasParenthesesIfNoArgs flag. - */ - registerFunction( "abs", new StandardSQLFunction("abs") ); - registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) ); + /** + * This section registers RDMS Built-in Functions (BIFs) with Hibernate. + * The first parameter is the 'register' function name with Hibernate. + * The second parameter is the defined RDMS SQL Function and it's + * characteristics. If StandardSQLFunction(...) is used, the RDMS BIF + * name and the return type (if any) is specified. If + * SQLFunctionTemplate(...) is used, the return type and a template + * string is provided, plus an optional hasParenthesesIfNoArgs flag. + */ + registerFunction( "abs", new StandardSQLFunction( "abs" ) ); + registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) ); - registerFunction("ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) ); - registerFunction("char_length", new StandardSQLFunction("char_length", Hibernate.INTEGER) ); - registerFunction("character_length", new StandardSQLFunction("character_length", Hibernate.INTEGER) ); - registerFunction("length", new StandardSQLFunction("length", Hibernate.INTEGER) ); + registerFunction( "ascii", new StandardSQLFunction( "ascii", StandardBasicTypes.INTEGER ) ); + registerFunction( "char_length", new StandardSQLFunction( "char_length", StandardBasicTypes.INTEGER ) ); + registerFunction( "character_length", new StandardSQLFunction( "character_length", StandardBasicTypes.INTEGER ) ); // The RDMS concat() function only supports 2 parameters - registerFunction( "concat", new SQLFunctionTemplate(Hibernate.STRING, "concat(?1, ?2)") ); - registerFunction( "instr", new StandardSQLFunction("instr", Hibernate.STRING) ); - registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) ); - registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) ); - registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) ); - registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) ); + registerFunction( "concat", new SQLFunctionTemplate( StandardBasicTypes.STRING, "concat(?1, ?2)" ) ); + registerFunction( "instr", new StandardSQLFunction( "instr", StandardBasicTypes.STRING ) ); + registerFunction( "lpad", new StandardSQLFunction( "lpad", StandardBasicTypes.STRING ) ); + registerFunction( "replace", new StandardSQLFunction( "replace", StandardBasicTypes.STRING ) ); + registerFunction( "rpad", new StandardSQLFunction( "rpad", StandardBasicTypes.STRING ) ); + registerFunction( "substr", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) ); - registerFunction("lcase", new StandardSQLFunction("lcase") ); - registerFunction("lower", new StandardSQLFunction("lower") ); - registerFunction("ltrim", new StandardSQLFunction("ltrim") ); - registerFunction("reverse", new StandardSQLFunction("reverse") ); - registerFunction("rtrim", new StandardSQLFunction("rtrim") ); + registerFunction( "lcase", new StandardSQLFunction( "lcase" ) ); + registerFunction( "lower", new StandardSQLFunction( "lower" ) ); + registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) ); + registerFunction( "reverse", new StandardSQLFunction( "reverse" ) ); + registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) ); // RDMS does not directly support the trim() function, we use rtrim() and ltrim() - registerFunction("trim", new SQLFunctionTemplate(Hibernate.INTEGER, "ltrim(rtrim(?1))" ) ); - registerFunction("soundex", new StandardSQLFunction("soundex") ); - registerFunction("space", new StandardSQLFunction("space", Hibernate.STRING) ); - registerFunction("ucase", new StandardSQLFunction("ucase") ); - registerFunction("upper", new StandardSQLFunction("upper") ); + registerFunction( "trim", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "ltrim(rtrim(?1))" ) ); + registerFunction( "soundex", new StandardSQLFunction( "soundex" ) ); + registerFunction( "space", new StandardSQLFunction( "space", StandardBasicTypes.STRING ) ); + registerFunction( "ucase", new StandardSQLFunction( "ucase" ) ); + registerFunction( "upper", new StandardSQLFunction( "upper" ) ); - registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) ); - registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) ); - registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) ); - registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) ); - registerFunction("cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) ); - registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) ); - registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) ); - registerFunction("ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) ); - registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE) ); - registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) ); - registerFunction("pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) ); - registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE) ); - registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) ); - registerFunction("sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) ); - registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) ); - registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) ); - registerFunction("tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) ); + registerFunction( "acos", new StandardSQLFunction( "acos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "asin", new StandardSQLFunction( "asin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "atan", new StandardSQLFunction( "atan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cos", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cosh", new StandardSQLFunction( "cosh", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cot", new StandardSQLFunction( "cot", StandardBasicTypes.DOUBLE ) ); + registerFunction( "exp", new StandardSQLFunction( "exp", StandardBasicTypes.DOUBLE ) ); + registerFunction( "ln", new StandardSQLFunction( "ln", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log", new StandardSQLFunction( "log", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log10", new StandardSQLFunction( "log10", StandardBasicTypes.DOUBLE ) ); + registerFunction( "pi", new NoArgSQLFunction( "pi", StandardBasicTypes.DOUBLE ) ); + registerFunction( "rand", new NoArgSQLFunction( "rand", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sin", new StandardSQLFunction( "sin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sinh", new StandardSQLFunction( "sinh", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sqrt", new StandardSQLFunction( "sqrt", StandardBasicTypes.DOUBLE ) ); + registerFunction( "tan", new StandardSQLFunction( "tan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "tanh", new StandardSQLFunction( "tanh", StandardBasicTypes.DOUBLE ) ); - registerFunction( "round", new StandardSQLFunction("round") ); - registerFunction( "trunc", new StandardSQLFunction("trunc") ); - registerFunction( "ceil", new StandardSQLFunction("ceil") ); - registerFunction( "floor", new StandardSQLFunction("floor") ); + registerFunction( "round", new StandardSQLFunction( "round" ) ); + registerFunction( "trunc", new StandardSQLFunction( "trunc" ) ); + registerFunction( "ceil", new StandardSQLFunction( "ceil" ) ); + registerFunction( "floor", new StandardSQLFunction( "floor" ) ); - registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) ); - registerFunction( "initcap", new StandardSQLFunction("initcap") ); + registerFunction( "chr", new StandardSQLFunction( "chr", StandardBasicTypes.CHARACTER ) ); + registerFunction( "initcap", new StandardSQLFunction( "initcap" ) ); - registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) ); + registerFunction( "user", new NoArgSQLFunction( "user", StandardBasicTypes.STRING, false ) ); - registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) ); - registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", Hibernate.TIME, false) ); - registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) ); - registerFunction("curdate", new NoArgSQLFunction("curdate",Hibernate.DATE) ); - registerFunction("curtime", new NoArgSQLFunction("curtime",Hibernate.TIME) ); - registerFunction("days", new StandardSQLFunction("days",Hibernate.INTEGER) ); - registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth",Hibernate.INTEGER) ); - registerFunction("dayname", new StandardSQLFunction("dayname",Hibernate.STRING) ); - registerFunction("dayofweek", new StandardSQLFunction("dayofweek",Hibernate.INTEGER) ); - registerFunction("dayofyear", new StandardSQLFunction("dayofyear",Hibernate.INTEGER) ); - registerFunction("hour", new StandardSQLFunction("hour",Hibernate.INTEGER) ); - registerFunction("last_day", new StandardSQLFunction("last_day",Hibernate.DATE) ); - registerFunction("microsecond", new StandardSQLFunction("microsecond",Hibernate.INTEGER) ); - registerFunction("minute", new StandardSQLFunction("minute",Hibernate.INTEGER) ); - registerFunction("month", new StandardSQLFunction("month",Hibernate.INTEGER) ); - registerFunction("monthname", new StandardSQLFunction("monthname",Hibernate.STRING) ); - registerFunction("now", new NoArgSQLFunction("now",Hibernate.TIMESTAMP) ); - registerFunction("quarter", new StandardSQLFunction("quarter",Hibernate.INTEGER) ); - registerFunction("second", new StandardSQLFunction("second",Hibernate.INTEGER) ); - registerFunction("time", new StandardSQLFunction("time",Hibernate.TIME) ); - registerFunction("timestamp", new StandardSQLFunction("timestamp",Hibernate.TIMESTAMP) ); - registerFunction("week", new StandardSQLFunction("week",Hibernate.INTEGER) ); - registerFunction("year", new StandardSQLFunction("year",Hibernate.INTEGER) ); + registerFunction( "current_date", new NoArgSQLFunction( "current_date", StandardBasicTypes.DATE, false ) ); + registerFunction( "current_time", new NoArgSQLFunction( "current_timestamp", StandardBasicTypes.TIME, false ) ); + registerFunction( "current_timestamp", new NoArgSQLFunction( "current_timestamp", StandardBasicTypes.TIMESTAMP, false ) ); + registerFunction( "curdate", new NoArgSQLFunction( "curdate", StandardBasicTypes.DATE ) ); + registerFunction( "curtime", new NoArgSQLFunction( "curtime", StandardBasicTypes.TIME ) ); + registerFunction( "days", new StandardSQLFunction( "days", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofmonth", new StandardSQLFunction( "dayofmonth", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayname", new StandardSQLFunction( "dayname", StandardBasicTypes.STRING ) ); + registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", StandardBasicTypes.INTEGER ) ); + registerFunction( "hour", new StandardSQLFunction( "hour", StandardBasicTypes.INTEGER ) ); + registerFunction( "last_day", new StandardSQLFunction( "last_day", StandardBasicTypes.DATE ) ); + registerFunction( "microsecond", new StandardSQLFunction( "microsecond", StandardBasicTypes.INTEGER ) ); + registerFunction( "minute", new StandardSQLFunction( "minute", StandardBasicTypes.INTEGER ) ); + registerFunction( "month", new StandardSQLFunction( "month", StandardBasicTypes.INTEGER ) ); + registerFunction( "monthname", new StandardSQLFunction( "monthname", StandardBasicTypes.STRING ) ); + registerFunction( "now", new NoArgSQLFunction( "now", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "quarter", new StandardSQLFunction( "quarter", StandardBasicTypes.INTEGER ) ); + registerFunction( "second", new StandardSQLFunction( "second", StandardBasicTypes.INTEGER ) ); + registerFunction( "time", new StandardSQLFunction( "time", StandardBasicTypes.TIME ) ); + registerFunction( "timestamp", new StandardSQLFunction( "timestamp", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "week", new StandardSQLFunction( "week", StandardBasicTypes.INTEGER ) ); + registerFunction( "year", new StandardSQLFunction( "year", StandardBasicTypes.INTEGER ) ); - registerFunction("atan2", new StandardSQLFunction("atan2",Hibernate.DOUBLE) ); - registerFunction( "mod", new StandardSQLFunction("mod",Hibernate.INTEGER) ); - registerFunction( "nvl", new StandardSQLFunction("nvl") ); - registerFunction( "power", new StandardSQLFunction("power", Hibernate.DOUBLE) ); + registerFunction( "atan2", new StandardSQLFunction( "atan2", StandardBasicTypes.DOUBLE ) ); + registerFunction( "mod", new StandardSQLFunction( "mod", StandardBasicTypes.INTEGER ) ); + registerFunction( "nvl", new StandardSQLFunction( "nvl" ) ); + registerFunction( "power", new StandardSQLFunction( "power", StandardBasicTypes.DOUBLE ) ); /** * For a list of column types to register, see section A-1 @@ -180,161 +191,191 @@ * Note that $l (dollar-L) will use the length value if provided. * Also new for Hibernate3 is the $p percision and $s (scale) parameters */ - registerColumnType(Types.BIT, "SMALLINT"); - registerColumnType(Types.TINYINT, "SMALLINT"); - registerColumnType(Types.BIGINT, "NUMERIC(21,0)"); - registerColumnType(Types.SMALLINT, "SMALLINT"); - registerColumnType(Types.CHAR, "CHARACTER(1)"); - registerColumnType(Types.DOUBLE, "DOUBLE PRECISION"); - registerColumnType(Types.FLOAT, "FLOAT"); - registerColumnType(Types.REAL, "REAL"); - registerColumnType(Types.INTEGER, "INTEGER"); - registerColumnType(Types.NUMERIC, "NUMERIC(21,$l)"); - registerColumnType(Types.DECIMAL, "NUMERIC(21,$l)"); - registerColumnType(Types.DATE, "DATE"); - registerColumnType(Types.TIME, "TIME"); - registerColumnType(Types.TIMESTAMP, "TIMESTAMP"); - registerColumnType(Types.VARCHAR, "CHARACTER($l)"); - registerColumnType(Types.BLOB, "BLOB($l)" ); - /* + registerColumnType( Types.BIT, "SMALLINT" ); + registerColumnType( Types.TINYINT, "SMALLINT" ); + registerColumnType( Types.BIGINT, "NUMERIC(21,0)" ); + registerColumnType( Types.SMALLINT, "SMALLINT" ); + registerColumnType( Types.CHAR, "CHARACTER(1)" ); + registerColumnType( Types.DOUBLE, "DOUBLE PRECISION" ); + registerColumnType( Types.FLOAT, "FLOAT" ); + registerColumnType( Types.REAL, "REAL" ); + registerColumnType( Types.INTEGER, "INTEGER" ); + registerColumnType( Types.NUMERIC, "NUMERIC(21,$l)" ); + registerColumnType( Types.DECIMAL, "NUMERIC(21,$l)" ); + registerColumnType( Types.DATE, "DATE" ); + registerColumnType( Types.TIME, "TIME" ); + registerColumnType( Types.TIMESTAMP, "TIMESTAMP" ); + registerColumnType( Types.VARCHAR, "CHARACTER($l)" ); + registerColumnType( Types.BLOB, "BLOB($l)" ); + /* * The following types are not supported in RDMS/JDBC and therefore commented out. * However, in some cases, mapping them to CHARACTER columns works * for many applications, but does not work for all cases. */ - // registerColumnType(Types.VARBINARY, "CHARACTER($l)"); - // registerColumnType(Types.BLOB, "CHARACTER($l)" ); // For use prior to CP 11.0 - // registerColumnType(Types.CLOB, "CHARACTER($l)" ); + // registerColumnType(Types.VARBINARY, "CHARACTER($l)"); + // registerColumnType(Types.BLOB, "CHARACTER($l)" ); // For use prior to CP 11.0 + // registerColumnType(Types.CLOB, "CHARACTER($l)" ); } // Dialect method overrides ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - /** - * RDMS does not support qualifing index names with the schema name. - */ + /** + * RDMS does not support qualifing index names with the schema name. + *

    + * {@inheritDoc} + */ + @Override public boolean qualifyIndexName() { return false; } /** * The RDMS DB supports the 'FOR UPDATE OF' clause. However, the RDMS-JDBC - * driver does not support this feature, so a false is return. - * The base dialect also returns a false, but we will leave this over-ride - * in to make sure it stays false. + * driver does not support this feature, so a false is return. + * The base dialect also returns a false, but we will leave this over-ride + * in to make sure it stays false. + *

    + * {@inheritDoc} */ + @Override public boolean forUpdateOfColumns() { return false; } /** * Since the RDMS-JDBC driver does not support for updates, this string is - * set to an empty string. Whenever, the driver does support this feature, - * the returned string should be " FOR UPDATE OF". Note that RDMS does not - * support the string 'FOR UPDATE' string. + * set to an empty string. Whenever, the driver does support this feature, + * the returned string should be " FOR UPDATE OF". Note that RDMS does not + * support the string 'FOR UPDATE' string. + *

    + * {@inheritDoc} */ + @Override public String getForUpdateString() { - return ""; // Original Dialect.java returns " for update"; + // Original Dialect.java returns " for update"; + return ""; } - /** - * RDMS does not support adding Unique constraints via create and alter table. - */ - public boolean supportsUniqueConstraintInCreateAlterTable() { - return true; - } - // Verify the state of this new method in Hibernate 3.0 Dialect.java - /** - * RDMS does not support Cascade Deletes. - * Need to review this in the future when support is provided. - */ + + /** + * RDMS does not support Cascade Deletes. + * Need to review this in the future when support is provided. + *

    + * {@inheritDoc} + */ + @Override public boolean supportsCascadeDelete() { - return false; // Origial Dialect.java returns true; + return false; } /** - * Currently, RDMS-JDBC does not support ForUpdate. - * Need to review this in the future when support is provided. + * Currently, RDMS-JDBC does not support ForUpdate. + * Need to review this in the future when support is provided. + *

    + * {@inheritDoc} */ - public boolean supportsOuterJoinForUpdate() { + @Override + public boolean supportsOuterJoinForUpdate() { return false; } + @Override public String getAddColumnString() { return "add"; } + @Override public String getNullColumnString() { // The keyword used to specify a nullable column. return " null"; } - // *** Sequence methods - start. The RDMS dialect needs these - - // methods to make it possible to use the Native Id generator - + @Override public boolean supportsSequences() { return true; } + @Override public String getSequenceNextValString(String sequenceName) { - // The where clause was added to eliminate this statement from Brute Force Searches. - return "select permuted_id('NEXT',31) from rdms.rdms_dummy where key_col = 1 "; + // The where clause was added to eliminate this statement from Brute Force Searches. + return "select permuted_id('NEXT',31) from rdms.rdms_dummy where key_col = 1 "; } + @Override public String getCreateSequenceString(String sequenceName) { - // We must return a valid RDMS/RSA command from this method to - // prevent RDMS/RSA from issuing *ERROR 400 - return ""; + // We must return a valid RDMS/RSA command from this method to + // prevent RDMS/RSA from issuing *ERROR 400 + return ""; } + @Override public String getDropSequenceString(String sequenceName) { - // We must return a valid RDMS/RSA command from this method to - // prevent RDMS/RSA from issuing *ERROR 400 - return ""; + // We must return a valid RDMS/RSA command from this method to + // prevent RDMS/RSA from issuing *ERROR 400 + return ""; } - // *** Sequence methods - end + @Override + public String getCascadeConstraintsString() { + // Used with DROP TABLE to delete all records in the table. + return " including contents"; + } - public String getCascadeConstraintsString() { - // Used with DROP TABLE to delete all records in the table. - return " including contents"; - } - + @Override public CaseFragment createCaseFragment() { return new DecodeCaseFragment(); } + @Override public boolean supportsLimit() { return true; } + @Override public boolean supportsLimitOffset() { return false; } - public String getLimitString(String sql, int offset, int limit) { - if (offset>0) throw new UnsupportedOperationException("RDMS does not support paged queries"); - return new StringBuffer(sql.length() + 40) - .append(sql) - .append(" fetch first ") - .append(limit) - .append(" rows only ") - .toString(); + @Override + public String getLimitString(String sql, int offset, int limit) { + if ( offset > 0 ) { + throw new UnsupportedOperationException( "query result offset is not supported" ); + } + return sql + " fetch first " + limit + " rows only "; } + @Override public boolean supportsVariableLimit() { return false; } + @Override public boolean supportsUnionAll() { // RDMS supports the UNION ALL clause. - return true; + return true; } + @Override public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { // RDMS has no known variation of a "SELECT ... FOR UPDATE" syntax... - if ( lockMode.greaterThan( LockMode.READ ) ) { + if ( lockMode == LockMode.PESSIMISTIC_FORCE_INCREMENT ) { + return new PessimisticForceIncrementLockingStrategy( lockable, lockMode ); + } + else if ( lockMode == LockMode.PESSIMISTIC_WRITE ) { + return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode ); + } + else if ( lockMode == LockMode.PESSIMISTIC_READ ) { + return new PessimisticReadUpdateLockingStrategy( lockable, lockMode ); + } + else if ( lockMode == LockMode.OPTIMISTIC ) { + return new OptimisticLockingStrategy( lockable, lockMode ); + } + else if ( lockMode == LockMode.OPTIMISTIC_FORCE_INCREMENT ) { + return new OptimisticForceIncrementLockingStrategy( lockable, lockMode ); + } + else if ( lockMode.greaterThan( LockMode.READ ) ) { return new UpdateLockingStrategy( lockable, lockMode ); } else { Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/ResultColumnReferenceStrategy.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/ResultColumnReferenceStrategy.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/ResultColumnReferenceStrategy.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/ResultColumnReferenceStrategy.java 30 Jul 2014 16:15:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,72 +20,57 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; -import java.io.Serializable; -import java.io.ObjectStreamException; -import java.util.Map; -import java.util.HashMap; - /** * Defines how we need to reference columns in the group-by, having, and order-by * clauses. * * @author Steve Ebersole */ -public class ResultColumnReferenceStrategy implements Serializable { - - private static final Map INSTANCES = new HashMap(); - +public enum ResultColumnReferenceStrategy { /** * This strategy says to reference the result columns by the qualified column name * found in the result source. This strategy is not strictly allowed by ANSI SQL * but is Hibernate's legacy behavior and is also the fastest of the strategies; thus * it should be used if supported by the underlying database. */ - public static final ResultColumnReferenceStrategy SOURCE = new ResultColumnReferenceStrategy( "source"); - + SOURCE, /** * For databases which do not support {@link #SOURCE}, ANSI SQL defines two allowable * approaches. One is to reference the result column by the alias it is given in the * result source (if it is given an alias). This strategy says to use this approach. *

    * The other QNSI SQL compliant approach is {@link #ORDINAL}. */ - public static final ResultColumnReferenceStrategy ALIAS = new ResultColumnReferenceStrategy( "alias" ); - + ALIAS, /** * For databases which do not support {@link #SOURCE}, ANSI SQL defines two allowable * approaches. One is to reference the result column by the ordinal position at which * it appears in the result source. This strategy says to use this approach. *

    * The other QNSI SQL compliant approach is {@link #ALIAS}. */ - public static final ResultColumnReferenceStrategy ORDINAL = new ResultColumnReferenceStrategy( "ordinal" ); + ORDINAL; - static { - ResultColumnReferenceStrategy.INSTANCES.put( ResultColumnReferenceStrategy.SOURCE.name, ResultColumnReferenceStrategy.SOURCE ); - ResultColumnReferenceStrategy.INSTANCES.put( ResultColumnReferenceStrategy.ALIAS.name, ResultColumnReferenceStrategy.ALIAS ); - ResultColumnReferenceStrategy.INSTANCES.put( ResultColumnReferenceStrategy.ORDINAL.name, ResultColumnReferenceStrategy.ORDINAL ); + /** + * Resolves the strategy by name, in a case insensitive manner. If the name cannot be resolved, {@link #SOURCE} + * is returned as the default. + * + * @param name The strategy name to resolve + * + * @return The resolved strategy + */ + public static ResultColumnReferenceStrategy resolveByName(String name) { + if ( ALIAS.name().equalsIgnoreCase( name ) ) { + return ALIAS; + } + else if ( ORDINAL.name().equalsIgnoreCase( name ) ) { + return ORDINAL; + } + else { + return SOURCE; + } } - - private final String name; - - public ResultColumnReferenceStrategy(String name) { - this.name = name; - } - - public String toString() { - return name; - } - - private Object readResolve() throws ObjectStreamException { - return parse( name ); - } - - public static ResultColumnReferenceStrategy parse(String name) { - return ( ResultColumnReferenceStrategy ) ResultColumnReferenceStrategy.INSTANCES.get( name ); - } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/SAPDBDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/SAPDBDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/SAPDBDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/SAPDBDialect.java 30 Jul 2014 16:15:52 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,30 +20,30 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; import java.sql.Types; -import org.hibernate.Hibernate; import org.hibernate.cfg.Environment; import org.hibernate.dialect.function.NoArgSQLFunction; +import org.hibernate.dialect.function.SQLFunctionTemplate; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.VarArgsSQLFunction; -import org.hibernate.dialect.function.SQLFunctionTemplate; +import org.hibernate.internal.util.StringHelper; import org.hibernate.sql.CaseFragment; import org.hibernate.sql.DecodeCaseFragment; -import org.hibernate.sql.OracleJoinFragment; -import org.hibernate.sql.JoinFragment; -import org.hibernate.util.StringHelper; +import org.hibernate.type.StandardBasicTypes; /** * An SQL dialect compatible with SAP DB. + * * @author Brad Clow */ public class SAPDBDialect extends Dialect { - + /** + * Constructs a SAPDBDialect + */ public SAPDBDialect() { super(); registerColumnType( Types.BIT, "boolean" ); @@ -62,166 +62,176 @@ registerColumnType( Types.NUMERIC, "fixed($p,$s)" ); registerColumnType( Types.CLOB, "long varchar" ); registerColumnType( Types.BLOB, "long byte" ); - - registerFunction( "abs", new StandardSQLFunction("abs") ); - registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) ); - registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) ); - registerFunction( "ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) ); - registerFunction( "log", new StandardSQLFunction("ln", Hibernate.DOUBLE) ); - registerFunction( "pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) ); - registerFunction( "power", new StandardSQLFunction("power") ); - registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) ); - registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) ); - registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) ); - registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) ); - registerFunction( "cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) ); - registerFunction( "cot", new StandardSQLFunction("cos", Hibernate.DOUBLE) ); - registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) ); - registerFunction( "sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) ); - registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) ); - registerFunction( "tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) ); - registerFunction( "radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) ); - registerFunction( "degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) ); - registerFunction( "atan2", new StandardSQLFunction("atan2", Hibernate.DOUBLE) ); + registerFunction( "abs", new StandardSQLFunction( "abs" ) ); + registerFunction( "sign", new StandardSQLFunction( "sign", StandardBasicTypes.INTEGER ) ); - registerFunction( "round", new StandardSQLFunction("round") ); - registerFunction( "trunc", new StandardSQLFunction("trunc") ); - registerFunction( "ceil", new StandardSQLFunction("ceil") ); - registerFunction( "floor", new StandardSQLFunction("floor") ); - registerFunction( "greatest", new StandardSQLFunction("greatest") ); - registerFunction( "least", new StandardSQLFunction("least") ); + registerFunction( "exp", new StandardSQLFunction( "exp", StandardBasicTypes.DOUBLE ) ); + registerFunction( "ln", new StandardSQLFunction( "ln", StandardBasicTypes.DOUBLE ) ); + registerFunction( "log", new StandardSQLFunction( "ln", StandardBasicTypes.DOUBLE ) ); + registerFunction( "pi", new NoArgSQLFunction( "pi", StandardBasicTypes.DOUBLE ) ); + registerFunction( "power", new StandardSQLFunction( "power" ) ); + registerFunction( "acos", new StandardSQLFunction( "acos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "asin", new StandardSQLFunction( "asin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "atan", new StandardSQLFunction( "atan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cos", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cosh", new StandardSQLFunction( "cosh", StandardBasicTypes.DOUBLE ) ); + registerFunction( "cot", new StandardSQLFunction( "cos", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sin", new StandardSQLFunction( "sin", StandardBasicTypes.DOUBLE ) ); + registerFunction( "sinh", new StandardSQLFunction( "sinh", StandardBasicTypes.DOUBLE ) ); + registerFunction( "tan", new StandardSQLFunction( "tan", StandardBasicTypes.DOUBLE ) ); + registerFunction( "tanh", new StandardSQLFunction( "tanh", StandardBasicTypes.DOUBLE ) ); + registerFunction( "radians", new StandardSQLFunction( "radians", StandardBasicTypes.DOUBLE ) ); + registerFunction( "degrees", new StandardSQLFunction( "degrees", StandardBasicTypes.DOUBLE ) ); + registerFunction( "atan2", new StandardSQLFunction( "atan2", StandardBasicTypes.DOUBLE ) ); - registerFunction("time", new StandardSQLFunction("time", Hibernate.TIME) ); - registerFunction("timestamp", new StandardSQLFunction("timestamp", Hibernate.TIMESTAMP) ); - registerFunction("date", new StandardSQLFunction("date", Hibernate.DATE) ); - registerFunction("microsecond", new StandardSQLFunction("microsecond", Hibernate.INTEGER) ); + registerFunction( "round", new StandardSQLFunction( "round" ) ); + registerFunction( "trunc", new StandardSQLFunction( "trunc" ) ); + registerFunction( "ceil", new StandardSQLFunction( "ceil" ) ); + registerFunction( "floor", new StandardSQLFunction( "floor" ) ); + registerFunction( "greatest", new StandardSQLFunction( "greatest" ) ); + registerFunction( "least", new StandardSQLFunction( "least" ) ); - registerFunction( "second", new SQLFunctionTemplate(Hibernate.INTEGER, "second(?1)") ); - registerFunction( "minute", new SQLFunctionTemplate(Hibernate.INTEGER, "minute(?1)") ); - registerFunction( "hour", new SQLFunctionTemplate(Hibernate.INTEGER, "hour(?1)") ); - registerFunction( "day", new SQLFunctionTemplate(Hibernate.INTEGER, "day(?1)") ); - registerFunction( "month", new SQLFunctionTemplate(Hibernate.INTEGER, "month(?1)") ); - registerFunction( "year", new SQLFunctionTemplate(Hibernate.INTEGER, "year(?1)") ); + registerFunction( "time", new StandardSQLFunction( "time", StandardBasicTypes.TIME ) ); + registerFunction( "timestamp", new StandardSQLFunction( "timestamp", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "date", new StandardSQLFunction( "date", StandardBasicTypes.DATE ) ); + registerFunction( "microsecond", new StandardSQLFunction( "microsecond", StandardBasicTypes.INTEGER ) ); - registerFunction( "extract", new SQLFunctionTemplate(Hibernate.INTEGER, "?1(?3)") ); + registerFunction( "second", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "second(?1)" ) ); + registerFunction( "minute", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "minute(?1)" ) ); + registerFunction( "hour", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "hour(?1)" ) ); + registerFunction( "day", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "day(?1)" ) ); + registerFunction( "month", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "month(?1)" ) ); + registerFunction( "year", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "year(?1)" ) ); - registerFunction("dayname", new StandardSQLFunction("dayname", Hibernate.STRING) ); - registerFunction("monthname", new StandardSQLFunction("monthname", Hibernate.STRING) ); - registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth", Hibernate.INTEGER) ); - registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER) ); - registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER) ); - registerFunction("weekofyear", new StandardSQLFunction("weekofyear", Hibernate.INTEGER) ); + registerFunction( "extract", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "?1(?3)" ) ); - registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) ); - registerFunction( "translate", new StandardSQLFunction("translate", Hibernate.STRING) ); - registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) ); - registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) ); - registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) ); - registerFunction( "initcap", new StandardSQLFunction("initcap", Hibernate.STRING) ); - registerFunction( "lower", new StandardSQLFunction("lower", Hibernate.STRING) ); - registerFunction( "ltrim", new StandardSQLFunction("ltrim", Hibernate.STRING) ); - registerFunction( "rtrim", new StandardSQLFunction("rtrim", Hibernate.STRING) ); - registerFunction( "lfill", new StandardSQLFunction("ltrim", Hibernate.STRING) ); - registerFunction( "rfill", new StandardSQLFunction("rtrim", Hibernate.STRING) ); - registerFunction( "soundex", new StandardSQLFunction("soundex", Hibernate.STRING) ); - registerFunction( "upper", new StandardSQLFunction("upper", Hibernate.STRING) ); - registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.STRING) ); - registerFunction( "index", new StandardSQLFunction("index", Hibernate.INTEGER) ); + registerFunction( "dayname", new StandardSQLFunction( "dayname", StandardBasicTypes.STRING ) ); + registerFunction( "monthname", new StandardSQLFunction( "monthname", StandardBasicTypes.STRING ) ); + registerFunction( "dayofmonth", new StandardSQLFunction( "dayofmonth", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", StandardBasicTypes.INTEGER ) ); + registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", StandardBasicTypes.INTEGER ) ); + registerFunction( "weekofyear", new StandardSQLFunction( "weekofyear", StandardBasicTypes.INTEGER ) ); + registerFunction( "replace", new StandardSQLFunction( "replace", StandardBasicTypes.STRING ) ); + registerFunction( "translate", new StandardSQLFunction( "translate", StandardBasicTypes.STRING ) ); + registerFunction( "lpad", new StandardSQLFunction( "lpad", StandardBasicTypes.STRING ) ); + registerFunction( "rpad", new StandardSQLFunction( "rpad", StandardBasicTypes.STRING ) ); + registerFunction( "substr", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) ); + registerFunction( "initcap", new StandardSQLFunction( "initcap", StandardBasicTypes.STRING ) ); + registerFunction( "lower", new StandardSQLFunction( "lower", StandardBasicTypes.STRING ) ); + registerFunction( "ltrim", new StandardSQLFunction( "ltrim", StandardBasicTypes.STRING ) ); + registerFunction( "rtrim", new StandardSQLFunction( "rtrim", StandardBasicTypes.STRING ) ); + registerFunction( "lfill", new StandardSQLFunction( "ltrim", StandardBasicTypes.STRING ) ); + registerFunction( "rfill", new StandardSQLFunction( "rtrim", StandardBasicTypes.STRING ) ); + registerFunction( "soundex", new StandardSQLFunction( "soundex", StandardBasicTypes.STRING ) ); + registerFunction( "upper", new StandardSQLFunction( "upper", StandardBasicTypes.STRING ) ); + registerFunction( "ascii", new StandardSQLFunction( "ascii", StandardBasicTypes.STRING ) ); + registerFunction( "index", new StandardSQLFunction( "index", StandardBasicTypes.INTEGER ) ); + registerFunction( "value", new StandardSQLFunction( "value" ) ); - - registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) ); - registerFunction( "substring", new StandardSQLFunction( "substr", Hibernate.STRING ) ); - registerFunction( "locate", new StandardSQLFunction("index", Hibernate.INTEGER) ); + + registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(", "||", ")" ) ); + registerFunction( "substring", new StandardSQLFunction( "substr", StandardBasicTypes.STRING ) ); + registerFunction( "locate", new StandardSQLFunction( "index", StandardBasicTypes.INTEGER ) ); registerFunction( "coalesce", new StandardSQLFunction( "value" ) ); - getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE); + getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE ); } + @Override public boolean dropConstraints() { return false; } + @Override public String getAddColumnString() { return "add"; } + @Override public String getAddForeignKeyConstraintString( - String constraintName, - String[] foreignKey, - String referencedTable, - String[] primaryKey, boolean referencesPrimaryKey - ) { - StringBuffer res = new StringBuffer(30) - .append(" foreign key ") - .append(constraintName) - .append(" (") - .append( StringHelper.join(", ", foreignKey) ) - .append(") references ") - .append(referencedTable); - - if(!referencesPrimaryKey) { - res.append(" (") - .append( StringHelper.join(", ", primaryKey) ) - .append(')'); + String constraintName, + String[] foreignKey, + String referencedTable, + String[] primaryKey, + boolean referencesPrimaryKey) { + final StringBuilder res = new StringBuilder( 30 ) + .append( " foreign key " ) + .append( constraintName ) + .append( " (" ) + .append( StringHelper.join( ", ", foreignKey ) ) + .append( ") references " ) + .append( referencedTable ); + + if ( !referencesPrimaryKey ) { + res.append( " (" ) + .append( StringHelper.join( ", ", primaryKey ) ) + .append( ')' ); } - + return res.toString(); } + @Override public String getAddPrimaryKeyConstraintString(String constraintName) { return " primary key "; } + @Override public String getNullColumnString() { return " null"; } + @Override public String getSequenceNextValString(String sequenceName) { return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual"; } + @Override public String getSelectSequenceNextValString(String sequenceName) { return sequenceName + ".nextval"; } + @Override public String getCreateSequenceString(String sequenceName) { return "create sequence " + sequenceName; } + @Override public String getDropSequenceString(String sequenceName) { return "drop sequence " + sequenceName; } + @Override public String getQuerySequencesString() { return "select sequence_name from domain.sequences"; } - public JoinFragment createOuterJoinFragment() { - return new OracleJoinFragment(); - } - - + @Override public boolean supportsSequences() { return true; } + @Override public CaseFragment createCaseFragment() { return new DecodeCaseFragment(); } + @Override public boolean supportsTemporaryTables() { return true; } + @Override public String getCreateTemporaryTablePostfix() { return "ignore rollback"; } + @Override public String generateTemporaryTableName(String baseTableName) { - return "temp." + super.generateTemporaryTableName(baseTableName); + return "temp." + super.generateTemporaryTableName( baseTableName ); } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/SQLServer2005Dialect.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/SQLServer2008Dialect.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/SQLServer2012Dialect.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/SQLServerDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/SQLServerDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/SQLServerDialect.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/SQLServerDialect.java 30 Jul 2014 16:15:54 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,141 +20,193 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; import java.sql.Types; -import org.hibernate.Hibernate; import org.hibernate.LockMode; +import org.hibernate.LockOptions; +import org.hibernate.dialect.function.AnsiTrimEmulationFunction; import org.hibernate.dialect.function.SQLFunctionTemplate; import org.hibernate.dialect.function.StandardSQLFunction; -import org.hibernate.dialect.function.AnsiTrimEmulationFunction; +import org.hibernate.type.StandardBasicTypes; +import org.hibernate.type.descriptor.sql.SmallIntTypeDescriptor; +import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; /** - * A dialect for Microsoft SQL Server 2000 and 2005 + * A dialect for Microsoft SQL Server 2000 * * @author Gavin King */ -public class SQLServerDialect extends SybaseDialect { +@SuppressWarnings("deprecation") +public class SQLServerDialect extends AbstractTransactSQLDialect { + private static final int PARAM_LIST_SIZE_LIMIT = 2100; + /** + * Constructs a SQLServerDialect + */ public SQLServerDialect() { registerColumnType( Types.VARBINARY, "image" ); registerColumnType( Types.VARBINARY, 8000, "varbinary($l)" ); + registerColumnType( Types.LONGVARBINARY, "image" ); + registerColumnType( Types.LONGVARCHAR, "text" ); + registerColumnType( Types.BOOLEAN, "bit" ); - registerFunction( "second", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(second, ?1)" ) ); - registerFunction( "minute", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(minute, ?1)" ) ); - registerFunction( "hour", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(hour, ?1)" ) ); - registerFunction( "locate", new StandardSQLFunction( "charindex", Hibernate.INTEGER ) ); + registerFunction( "second", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "datepart(second, ?1)" ) ); + registerFunction( "minute", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "datepart(minute, ?1)" ) ); + registerFunction( "hour", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "datepart(hour, ?1)" ) ); + registerFunction( "locate", new StandardSQLFunction( "charindex", StandardBasicTypes.INTEGER ) ); - registerFunction( "extract", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(?1, ?3)" ) ); - registerFunction( "mod", new SQLFunctionTemplate( Hibernate.INTEGER, "?1 % ?2" ) ); - registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "datalength(?1) * 8" ) ); + registerFunction( "extract", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "datepart(?1, ?3)" ) ); + registerFunction( "mod", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "?1 % ?2" ) ); + registerFunction( "bit_length", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "datalength(?1) * 8" ) ); registerFunction( "trim", new AnsiTrimEmulationFunction() ); registerKeyword( "top" ); } + @Override public String getNoColumnsInsertString() { return "default values"; } static int getAfterSelectInsertPoint(String sql) { - int selectIndex = sql.toLowerCase().indexOf( "select" ); + final int selectIndex = sql.toLowerCase().indexOf( "select" ); final int selectDistinctIndex = sql.toLowerCase().indexOf( "select distinct" ); - return selectIndex + ( selectDistinctIndex == selectIndex ? 15 : 6 ); + return selectIndex + (selectDistinctIndex == selectIndex ? 15 : 6); } + @Override public String getLimitString(String querySelect, int offset, int limit) { if ( offset > 0 ) { - throw new UnsupportedOperationException( "sql server has no offset" ); + throw new UnsupportedOperationException( "query result offset is not supported" ); } - return new StringBuffer( querySelect.length() + 8 ) + return new StringBuilder( querySelect.length() + 8 ) .append( querySelect ) .insert( getAfterSelectInsertPoint( querySelect ), " top " + limit ) .toString(); } /** * Use insert table(...) values(...) select SCOPE_IDENTITY() + *

    + * {@inheritDoc} */ + @Override public String appendIdentitySelectToInsert(String insertSQL) { return insertSQL + " select scope_identity()"; } + @Override public boolean supportsLimit() { return true; } + @Override public boolean useMaxForLimit() { return true; } + @Override public boolean supportsLimitOffset() { return false; } + @Override public boolean supportsVariableLimit() { return false; } + @Override public char closeQuote() { return ']'; } + @Override public char openQuote() { return '['; } - public String appendLockHint(LockMode mode, String tableName) { - if ( mode.greaterThan( LockMode.READ ) ) { - // does this need holdlock also? : return tableName + " with (updlock, rowlock, holdlock)"; - return tableName + " with (updlock, rowlock)"; + @Override + public String appendLockHint(LockOptions lockOptions, String tableName) { + final LockMode mode = lockOptions.getLockMode(); + switch ( mode ) { + case UPGRADE: + case UPGRADE_NOWAIT: + case PESSIMISTIC_WRITE: + case WRITE: + return tableName + " with (updlock, rowlock)"; + case PESSIMISTIC_READ: + return tableName + " with (holdlock, rowlock)"; + case UPGRADE_SKIPLOCKED: + return tableName + " with (updlock, rowlock, readpast)"; + default: + return tableName; } - else { - return tableName; - } } - public String getSelectGUIDString() { - return "select newid()"; - } - // The current_timestamp is more accurate, but only known to be supported - // in SQL Server 7.0 and later (i.e., Sybase not known to support it at all) + /** + * The current_timestamp is more accurate, but only known to be supported in SQL Server 7.0 and later and + * Sybase not known to support it at all + *

    + * {@inheritDoc} + */ + @Override public String getCurrentTimestampSelectString() { return "select current_timestamp"; } // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public boolean areStringComparisonsCaseInsensitive() { return true; } + @Override public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() { return false; } + @Override public boolean supportsCircularCascadeDeleteConstraints() { // SQL Server (at least up through 2005) does not support defining - // cascade delete constraints which can circel back to the mutating + // cascade delete constraints which can circle back to the mutating // table return false; } + @Override public boolean supportsLobValueChangePropogation() { // note: at least my local SQL Server 2005 Express shows this not working... return false; } + @Override public boolean doesReadCommittedCauseWritersToBlockReaders() { - return false; // here assume SQLServer2005 using snapshot isolation, which does not have this problem + // here assume SQLServer2005 using snapshot isolation, which does not have this problem + return false; } + @Override public boolean doesRepeatableReadCauseReadersToBlockWriters() { - return false; // here assume SQLServer2005 using snapshot isolation, which does not have this problem + // here assume SQLServer2005 using snapshot isolation, which does not have this problem + return false; } + + @Override + protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) { + return sqlCode == Types.TINYINT ? + SmallIntTypeDescriptor.INSTANCE : + super.getSqlTypeDescriptorOverride( sqlCode ); + } + + @Override + public int getInExpressionCountLimit() { + return PARAM_LIST_SIZE_LIMIT; + } } + Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/Sybase11Dialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/Sybase11Dialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/Sybase11Dialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/Sybase11Dialect.java 30 Jul 2014 16:15:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; @@ -29,15 +28,24 @@ /** * A SQL dialect suitable for use with Sybase 11.9.2 (specifically: avoids ANSI JOIN syntax) + * * @author Colm O' Flaherty */ public class Sybase11Dialect extends SybaseDialect { + /** + * Constructs a Sybase11Dialect + */ public Sybase11Dialect() { super(); } + @Override public JoinFragment createOuterJoinFragment() { return new Sybase11JoinFragment(); } + @Override + public String getCrossJoinSeparator() { + return ", "; + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/SybaseASE157Dialect.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/SybaseASE15Dialect.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/SybaseAnywhereDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/SybaseAnywhereDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/SybaseAnywhereDialect.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/SybaseAnywhereDialect.java 30 Jul 2014 16:15:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,37 +20,43 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; + /** * SQL Dialect for Sybase Anywhere * extending Sybase (Enterprise) Dialect * (Tested on ASA 8.x) - * @author ? */ public class SybaseAnywhereDialect extends SybaseDialect { - /** * Sybase Anywhere syntax would require a "DEFAULT" for each column specified, * but I suppose Hibernate use this syntax only with tables with just 1 column + *

    + * {@inheritDoc} */ + @Override public String getNoColumnsInsertString() { return "values (default)"; } - /** - * ASA does not require to drop constraint before dropping tables, and DROP statement - * syntax used by Hibernate to drop constraint is not compatible with ASA, so disable it + * ASA does not require to drop constraint before dropping tables, so disable it. + *

    + * NOTE : Also, the DROP statement syntax used by Hibernate to drop constraints is + * not compatible with ASA. + *

    + * {@inheritDoc} */ + @Override public boolean dropConstraints() { return false; } + @Override public boolean supportsInsertSelectIdentity() { return false; } -} \ No newline at end of file +} Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/SybaseDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/SybaseDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/SybaseDialect.java 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/SybaseDialect.java 30 Jul 2014 16:15:52 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,242 +20,44 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; -import java.sql.CallableStatement; -import java.sql.ResultSet; -import java.sql.SQLException; import java.sql.Types; -import java.util.Map; -import java.util.Iterator; -import org.hibernate.Hibernate; -import org.hibernate.LockMode; -import org.hibernate.cfg.Environment; -import org.hibernate.dialect.function.CharIndexFunction; -import org.hibernate.dialect.function.NoArgSQLFunction; -import org.hibernate.dialect.function.SQLFunctionTemplate; -import org.hibernate.dialect.function.StandardSQLFunction; -import org.hibernate.dialect.function.VarArgsSQLFunction; +import org.hibernate.type.descriptor.sql.BlobTypeDescriptor; +import org.hibernate.type.descriptor.sql.ClobTypeDescriptor; +import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; + /** - * An SQL dialect compatible with Sybase and MS SQL Server. - * @author Gavin King + * All Sybase dialects share an IN list size limit. + * + * @author Brett Meyer */ +public class SybaseDialect extends AbstractTransactSQLDialect { + private static final int PARAM_LIST_SIZE_LIMIT = 250000; -public class SybaseDialect extends Dialect { - public SybaseDialect() { - super(); - registerColumnType( Types.BIT, "tinyint" ); //Sybase BIT type does not support null values - registerColumnType( Types.BIGINT, "numeric(19,0)" ); - registerColumnType( Types.SMALLINT, "smallint" ); - registerColumnType( Types.TINYINT, "tinyint" ); - registerColumnType( Types.INTEGER, "int" ); - registerColumnType( Types.CHAR, "char(1)" ); - registerColumnType( Types.VARCHAR, "varchar($l)" ); - registerColumnType( Types.FLOAT, "float" ); - registerColumnType( Types.DOUBLE, "double precision" ); - registerColumnType( Types.DATE, "datetime" ); - registerColumnType( Types.TIME, "datetime" ); - registerColumnType( Types.TIMESTAMP, "datetime" ); - registerColumnType( Types.VARBINARY, "varbinary($l)" ); - registerColumnType( Types.NUMERIC, "numeric($p,$s)" ); - registerColumnType( Types.BLOB, "image" ); - registerColumnType( Types.CLOB, "text" ); - - registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) ); - registerFunction( "char", new StandardSQLFunction("char", Hibernate.CHARACTER) ); - registerFunction( "len", new StandardSQLFunction("len", Hibernate.LONG) ); - registerFunction( "lower", new StandardSQLFunction("lower") ); - registerFunction( "upper", new StandardSQLFunction("upper") ); - registerFunction( "str", new StandardSQLFunction("str", Hibernate.STRING) ); - registerFunction( "ltrim", new StandardSQLFunction("ltrim") ); - registerFunction( "rtrim", new StandardSQLFunction("rtrim") ); - registerFunction( "reverse", new StandardSQLFunction("reverse") ); - registerFunction( "space", new StandardSQLFunction("space", Hibernate.STRING) ); - - registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING) ); - - registerFunction( "current_timestamp", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP) ); - registerFunction( "current_time", new NoArgSQLFunction("getdate", Hibernate.TIME) ); - registerFunction( "current_date", new NoArgSQLFunction("getdate", Hibernate.DATE) ); - - registerFunction( "getdate", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP) ); - registerFunction( "getutcdate", new NoArgSQLFunction("getutcdate", Hibernate.TIMESTAMP) ); - registerFunction( "day", new StandardSQLFunction("day", Hibernate.INTEGER) ); - registerFunction( "month", new StandardSQLFunction("month", Hibernate.INTEGER) ); - registerFunction( "year", new StandardSQLFunction("year", Hibernate.INTEGER) ); - registerFunction( "datename", new StandardSQLFunction("datename", Hibernate.STRING) ); - - registerFunction( "abs", new StandardSQLFunction("abs") ); - registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) ); - - registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) ); - registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) ); - registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) ); - registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) ); - registerFunction( "cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) ); - registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) ); - registerFunction( "log", new StandardSQLFunction( "log", Hibernate.DOUBLE) ); - registerFunction( "log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) ); - registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) ); - registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) ); - registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) ); - registerFunction( "pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) ); - registerFunction( "square", new StandardSQLFunction("square") ); - registerFunction( "rand", new StandardSQLFunction("rand", Hibernate.FLOAT) ); - - registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) ); - registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) ); - - registerFunction( "round", new StandardSQLFunction("round") ); - registerFunction( "ceiling", new StandardSQLFunction("ceiling") ); - registerFunction( "floor", new StandardSQLFunction("floor") ); - - registerFunction( "isnull", new StandardSQLFunction("isnull") ); - - registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","+",")" ) ); - - registerFunction( "length", new StandardSQLFunction( "len", Hibernate.INTEGER ) ); - registerFunction( "trim", new SQLFunctionTemplate( Hibernate.STRING, "ltrim(rtrim(?1))") ); - registerFunction( "locate", new CharIndexFunction() ); - - getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH); + @Override + public int getInExpressionCountLimit() { + return PARAM_LIST_SIZE_LIMIT; } - - public String getAddColumnString() { - return "add"; + + @Override + protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) { + switch (sqlCode) { + case Types.BLOB: + return BlobTypeDescriptor.PRIMITIVE_ARRAY_BINDING; + case Types.CLOB: + // Some Sybase drivers cannot support getClob. See HHH-7889 + return ClobTypeDescriptor.STREAM_BINDING_EXTRACTING; + default: + return super.getSqlTypeDescriptorOverride( sqlCode ); + } } + + @Override public String getNullColumnString() { return " null"; } - public boolean qualifyIndexName() { - return false; - } - - public String getForUpdateString() { - return ""; - } - - public boolean supportsIdentityColumns() { - return true; - } - public String getIdentitySelectString() { - return "select @@identity"; - } - public String getIdentityColumnString() { - return "identity not null"; //starts with 1, implicitly - } - - public boolean supportsInsertSelectIdentity() { - return true; - } - - public String appendIdentitySelectToInsert(String insertSQL) { - return insertSQL + "\nselect @@identity"; - } - - public String appendLockHint(LockMode mode, String tableName) { - if ( mode.greaterThan( LockMode.READ ) ) { - return tableName + " holdlock"; - } - else { - return tableName; - } - } - - public String applyLocksToSql(String sql, Map aliasedLockModes, Map keyColumnNames) { - Iterator itr = aliasedLockModes.entrySet().iterator(); - StringBuffer buffer = new StringBuffer( sql ); - int correction = 0; - while ( itr.hasNext() ) { - final Map.Entry entry = ( Map.Entry ) itr.next(); - final LockMode lockMode = ( LockMode ) entry.getValue(); - if ( lockMode.greaterThan( LockMode.READ ) ) { - final String alias = ( String ) entry.getKey(); - int start = -1, end = -1; - if ( sql.endsWith( " " + alias ) ) { - start = ( sql.length() - alias.length() ) + correction; - end = start + alias.length(); - } - else { - int position = sql.indexOf( " " + alias + " " ); - if ( position <= -1 ) { - position = sql.indexOf( " " + alias + "," ); - } - if ( position > -1 ) { - start = position + correction + 1; - end = start + alias.length(); - } - } - - if ( start > -1 ) { - final String lockHint = appendLockHint( lockMode, alias ); - buffer.replace( start, end, lockHint ); - correction += ( lockHint.length() - alias.length() ); - } - } - } - return buffer.toString(); - } - - public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException { - return col; // sql server just returns automatically - } - - public ResultSet getResultSet(CallableStatement ps) throws SQLException { - boolean isResultSet = ps.execute(); -// This assumes you will want to ignore any update counts - while ( !isResultSet && ps.getUpdateCount() != -1 ) { - isResultSet = ps.getMoreResults(); - } -// You may still have other ResultSets or update counts left to process here -// but you can't do it now or the ResultSet you just got will be closed - return ps.getResultSet(); - } - - public boolean supportsCurrentTimestampSelection() { - return true; - } - - public boolean isCurrentTimestampSelectStringCallable() { - return false; - } - - public String getCurrentTimestampSelectString() { - return "select getdate()"; - } - - public boolean supportsTemporaryTables() { - return true; - } - - public String generateTemporaryTableName(String baseTableName) { - return "#" + baseTableName; - } - - public boolean dropTemporaryTableAfterUse() { - return true; // sql-server, at least needed this dropped after use; strange! - } - - - // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - public boolean supportsEmptyInList() { - return false; - } - - public boolean supportsExistsInSelect() { - return false; - } - - public boolean doesReadCommittedCauseWritersToBlockReaders() { - return true; - } - - public boolean doesRepeatableReadCauseReadersToBlockWriters() { - return true; - } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/TeradataDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/TeradataDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/TeradataDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/TeradataDialect.java 30 Jul 2014 16:15:54 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,17 +20,15 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; - import java.sql.Types; -import org.hibernate.Hibernate; import org.hibernate.HibernateException; import org.hibernate.cfg.Environment; import org.hibernate.dialect.function.SQLFunctionTemplate; import org.hibernate.dialect.function.VarArgsSQLFunction; +import org.hibernate.type.StandardBasicTypes; /** * A dialect for the Teradata database created by MCR as part of the @@ -39,6 +37,7 @@ * @author Jay Nance */ public class TeradataDialect extends Dialect { + private static final int PARAM_LIST_SIZE_LIMIT = 1024; /** * Constructor @@ -63,34 +62,35 @@ registerColumnType( Types.DATE, "DATE" ); registerColumnType( Types.TIME, "TIME" ); registerColumnType( Types.TIMESTAMP, "TIMESTAMP" ); - registerColumnType( Types.BOOLEAN, "BYTEINT" ); // hibernate seems to ignore this type... + // hibernate seems to ignore this type... + registerColumnType( Types.BOOLEAN, "BYTEINT" ); registerColumnType( Types.BLOB, "BLOB" ); registerColumnType( Types.CLOB, "CLOB" ); - registerFunction( "year", new SQLFunctionTemplate( Hibernate.INTEGER, "extract(year from ?1)" ) ); - registerFunction( "length", new SQLFunctionTemplate( Hibernate.INTEGER, "character_length(?1)" ) ); - registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) ); - registerFunction( "substring", new SQLFunctionTemplate( Hibernate.STRING, "substring(?1 from ?2 for ?3)" ) ); - registerFunction( "locate", new SQLFunctionTemplate( Hibernate.STRING, "position(?1 in ?2)" ) ); - registerFunction( "mod", new SQLFunctionTemplate( Hibernate.STRING, "?1 mod ?2" ) ); - registerFunction( "str", new SQLFunctionTemplate( Hibernate.STRING, "cast(?1 as varchar(255))" ) ); + registerFunction( "year", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "extract(year from ?1)" ) ); + registerFunction( "length", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "character_length(?1)" ) ); + registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "(", "||", ")" ) ); + registerFunction( "substring", new SQLFunctionTemplate( StandardBasicTypes.STRING, "substring(?1 from ?2 for ?3)" ) ); + registerFunction( "locate", new SQLFunctionTemplate( StandardBasicTypes.STRING, "position(?1 in ?2)" ) ); + registerFunction( "mod", new SQLFunctionTemplate( StandardBasicTypes.STRING, "?1 mod ?2" ) ); + registerFunction( "str", new SQLFunctionTemplate( StandardBasicTypes.STRING, "cast(?1 as varchar(255))" ) ); // bit_length feels a bit broken to me. We have to cast to char in order to // pass when a numeric value is supplied. But of course the answers given will // be wildly different for these two datatypes. 1234.5678 will be 9 bytes as // a char string but will be 8 or 16 bytes as a true numeric. // Jay Nance 2006-09-22 registerFunction( - "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "octet_length(cast(?1 as char))*4" ) + "bit_length", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "octet_length(cast(?1 as char))*4" ) ); // The preference here would be - // SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_timestamp(?1)", false) + // SQLFunctionTemplate( StandardBasicTypes.TIMESTAMP, "current_timestamp(?1)", false) // but this appears not to work. // Jay Nance 2006-09-22 - registerFunction( "current_timestamp", new SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_timestamp" ) ); - registerFunction( "current_time", new SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_time" ) ); - registerFunction( "current_date", new SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_date" ) ); + registerFunction( "current_timestamp", new SQLFunctionTemplate( StandardBasicTypes.TIMESTAMP, "current_timestamp" ) ); + registerFunction( "current_time", new SQLFunctionTemplate( StandardBasicTypes.TIMESTAMP, "current_time" ) ); + registerFunction( "current_date", new SQLFunctionTemplate( StandardBasicTypes.TIMESTAMP, "current_date" ) ); // IBID for current_time and current_date registerKeyword( "password" ); @@ -113,87 +113,87 @@ } /** - * Does this dialect support the FOR UPDATE syntax? - * - * @return empty string ... Teradata does not support FOR UPDATE syntax + * Teradata does not support FOR UPDATE syntax + *

    + * {@inheritDoc} */ + @Override public String getForUpdateString() { return ""; } + @Override public boolean supportsIdentityColumns() { return false; } + @Override public boolean supportsSequences() { return false; } + @Override public String getAddColumnString() { return "Add Column"; } + @Override public boolean supportsTemporaryTables() { return true; } + @Override public String getCreateTemporaryTableString() { return "create global temporary table"; } + @Override public String getCreateTemporaryTablePostfix() { return " on commit preserve rows"; } + @Override public Boolean performTemporaryTableDDLInIsolation() { return Boolean.TRUE; } + @Override public boolean dropTemporaryTableAfterUse() { return false; } - /** - * Get the name of the database type associated with the given - * java.sql.Types typecode. - * - * @param code java.sql.Types typecode - * @param length the length or precision of the column - * @param precision the precision of the column - * @param scale the scale of the column - * - * @return the database type name - * - * @throws HibernateException - */ - public String getTypeName(int code, int length, int precision, int scale) throws HibernateException { - /* - * We might want a special case for 19,2. This is very common for money types - * and here it is converted to 18,1 - */ - float f = precision > 0 ? ( float ) scale / ( float ) precision : 0; - int p = ( precision > 18 ? 18 : precision ); - int s = ( precision > 18 ? ( int ) ( 18.0 * f ) : ( scale > 18 ? 18 : scale ) ); + @Override + public String getTypeName(int code, long length, int precision, int scale) throws HibernateException { + // We might want a special case for 19,2. This is very common for money types + // and here it is converted to 18,1 + final float f = precision > 0 ? (float) scale / (float) precision : 0; + final int p = ( precision > 18 ? 18 : precision ); + final int s = ( precision > 18 ? (int) ( 18.0 * f ) : ( scale > 18 ? 18 : scale ) ); return super.getTypeName( code, length, p, s ); } + @Override public boolean supportsCascadeDelete() { return false; } + @Override public boolean supportsCircularCascadeDeleteConstraints() { return false; } + @Override public boolean areStringComparisonsCaseInsensitive() { return true; } + @Override public boolean supportsEmptyInList() { return false; } + @Override public String getSelectClauseNullString(int sqlType) { String v = "null"; @@ -235,27 +235,39 @@ case Types.DATALINK: case Types.BOOLEAN: break; + default: + break; } return v; } + @Override public String getCreateMultisetTableString() { return "create multiset table "; } + @Override public boolean supportsLobValueChangePropogation() { return false; } + @Override public boolean doesReadCommittedCauseWritersToBlockReaders() { return true; } + @Override public boolean doesRepeatableReadCauseReadersToBlockWriters() { return true; } + @Override public boolean supportsBindAsCallableArgument() { return false; } -} \ No newline at end of file + + @Override + public int getInExpressionCountLimit() { + return PARAM_LIST_SIZE_LIMIT; + } +} Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/TimesTenDialect.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/TimesTenDialect.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/TimesTenDialect.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/TimesTenDialect.java 30 Jul 2014 16:15:54 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,41 +20,48 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; import java.sql.Types; -import org.hibernate.Hibernate; import org.hibernate.LockMode; -import org.hibernate.persister.entity.Lockable; import org.hibernate.cfg.Environment; import org.hibernate.dialect.function.NoArgSQLFunction; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.lock.LockingStrategy; -import org.hibernate.dialect.lock.UpdateLockingStrategy; +import org.hibernate.dialect.lock.OptimisticForceIncrementLockingStrategy; +import org.hibernate.dialect.lock.OptimisticLockingStrategy; +import org.hibernate.dialect.lock.PessimisticForceIncrementLockingStrategy; +import org.hibernate.dialect.lock.PessimisticReadUpdateLockingStrategy; +import org.hibernate.dialect.lock.PessimisticWriteUpdateLockingStrategy; import org.hibernate.dialect.lock.SelectLockingStrategy; +import org.hibernate.dialect.lock.UpdateLockingStrategy; +import org.hibernate.persister.entity.Lockable; import org.hibernate.sql.JoinFragment; import org.hibernate.sql.OracleJoinFragment; +import org.hibernate.type.StandardBasicTypes; /** * A SQL dialect for TimesTen 5.1. - * + *

    * Known limitations: * joined-subclass support because of no CASE support in TimesTen * No support for subqueries that includes aggregation - * - size() in HQL not supported - * - user queries that does subqueries with aggregation - * No CLOB/BLOB support + * - size() in HQL not supported + * - user queries that does subqueries with aggregation + * No CLOB/BLOB support * No cascade delete support. * No Calendar support * No support for updating primary keys. - * + * * @author Sherry Listgarten and Max Andersen */ +@SuppressWarnings("deprecation") public class TimesTenDialect extends Dialect { - + /** + * Constructs a TimesTenDialect + */ public TimesTenDialect() { super(); registerColumnType( Types.BIT, "TINYINT" ); @@ -73,147 +80,180 @@ registerColumnType( Types.NUMERIC, "DECIMAL($p, $s)" ); // TimesTen has no BLOB/CLOB support, but these types may be suitable // for some applications. The length is limited to 4 million bytes. - registerColumnType( Types.BLOB, "VARBINARY(4000000)" ); - registerColumnType( Types.CLOB, "VARCHAR(4000000)" ); - - getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "true"); - getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE); - registerFunction( "lower", new StandardSQLFunction("lower") ); - registerFunction( "upper", new StandardSQLFunction("upper") ); - registerFunction( "rtrim", new StandardSQLFunction("rtrim") ); - registerFunction( "concat", new StandardSQLFunction("concat", Hibernate.STRING) ); - registerFunction( "mod", new StandardSQLFunction("mod") ); - registerFunction( "to_char", new StandardSQLFunction("to_char",Hibernate.STRING) ); - registerFunction( "to_date", new StandardSQLFunction("to_date",Hibernate.TIMESTAMP) ); - registerFunction( "sysdate", new NoArgSQLFunction("sysdate", Hibernate.TIMESTAMP, false) ); - registerFunction( "getdate", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP, false) ); - registerFunction( "nvl", new StandardSQLFunction("nvl") ); + registerColumnType( Types.BLOB, "VARBINARY(4000000)" ); + registerColumnType( Types.CLOB, "VARCHAR(4000000)" ); + getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "true" ); + getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE ); + registerFunction( "lower", new StandardSQLFunction( "lower" ) ); + registerFunction( "upper", new StandardSQLFunction( "upper" ) ); + registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) ); + registerFunction( "concat", new StandardSQLFunction( "concat", StandardBasicTypes.STRING ) ); + registerFunction( "mod", new StandardSQLFunction( "mod" ) ); + registerFunction( "to_char", new StandardSQLFunction( "to_char", StandardBasicTypes.STRING ) ); + registerFunction( "to_date", new StandardSQLFunction( "to_date", StandardBasicTypes.TIMESTAMP ) ); + registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", StandardBasicTypes.TIMESTAMP, false ) ); + registerFunction( "getdate", new NoArgSQLFunction( "getdate", StandardBasicTypes.TIMESTAMP, false ) ); + registerFunction( "nvl", new StandardSQLFunction( "nvl" ) ); + } - + + @Override public boolean dropConstraints() { - return true; + return true; } - + + @Override public boolean qualifyIndexName() { - return false; + return false; } - public boolean supportsUnique() { - return false; + @Override + public String getAddColumnString() { + return "add"; } - - public boolean supportsUniqueConstraintInCreateAlterTable() { - return false; - } - - public String getAddColumnString() { - return "add"; - } + @Override public boolean supportsSequences() { return true; } + @Override public String getSelectSequenceNextValString(String sequenceName) { return sequenceName + ".nextval"; } + @Override public String getSequenceNextValString(String sequenceName) { return "select first 1 " + sequenceName + ".nextval from sys.tables"; } + @Override public String getCreateSequenceString(String sequenceName) { return "create sequence " + sequenceName; } + @Override public String getDropSequenceString(String sequenceName) { return "drop sequence " + sequenceName; } + @Override public String getQuerySequencesString() { return "select NAME from sys.sequences"; } + @Override public JoinFragment createOuterJoinFragment() { return new OracleJoinFragment(); } - // new methods in dialect3 - /*public boolean supportsForUpdateNowait() { - return false; - }*/ - + @Override + public String getCrossJoinSeparator() { + return ", "; + } + + @Override public String getForUpdateString() { return ""; } - + + @Override public boolean supportsColumnCheck() { return false; } + @Override public boolean supportsTableCheck() { return false; } - + + @Override public boolean supportsLimitOffset() { return false; } + @Override public boolean supportsVariableLimit() { return false; } + @Override public boolean supportsLimit() { return true; } + @Override public boolean useMaxForLimit() { return true; } + @Override public String getLimitString(String querySelect, int offset, int limit) { if ( offset > 0 ) { - throw new UnsupportedOperationException( "TimesTen does not support offset" ); + throw new UnsupportedOperationException( "query result offset is not supported" ); } - return new StringBuffer( querySelect.length()+8 ) - .append(querySelect) - .insert( 6, " first " + limit ) - .toString(); + return new StringBuilder( querySelect.length() + 8 ) + .append( querySelect ) + .insert( 6, " first " + limit ) + .toString(); } + @Override public boolean supportsCurrentTimestampSelection() { return true; } + @Override public String getCurrentTimestampSelectString() { return "select first 1 sysdate from sys.tables"; } + @Override public boolean isCurrentTimestampSelectStringCallable() { return false; } + @Override public boolean supportsTemporaryTables() { return true; } + @Override public String generateTemporaryTableName(String baseTableName) { - String name = super.generateTemporaryTableName(baseTableName); + final String name = super.generateTemporaryTableName( baseTableName ); return name.length() > 30 ? name.substring( 1, 30 ) : name; } + @Override public String getCreateTemporaryTableString() { return "create global temporary table"; } + @Override public String getCreateTemporaryTablePostfix() { return "on commit delete rows"; } + @Override public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) { // TimesTen has no known variation of a "SELECT ... FOR UPDATE" syntax... - if ( lockMode.greaterThan( LockMode.READ ) ) { + if ( lockMode == LockMode.PESSIMISTIC_FORCE_INCREMENT ) { + return new PessimisticForceIncrementLockingStrategy( lockable, lockMode ); + } + else if ( lockMode == LockMode.PESSIMISTIC_WRITE ) { + return new PessimisticWriteUpdateLockingStrategy( lockable, lockMode ); + } + else if ( lockMode == LockMode.PESSIMISTIC_READ ) { + return new PessimisticReadUpdateLockingStrategy( lockable, lockMode ); + } + else if ( lockMode == LockMode.OPTIMISTIC ) { + return new OptimisticLockingStrategy( lockable, lockMode ); + } + else if ( lockMode == LockMode.OPTIMISTIC_FORCE_INCREMENT ) { + return new OptimisticForceIncrementLockingStrategy( lockable, lockMode ); + } + else if ( lockMode.greaterThan( LockMode.READ ) ) { return new UpdateLockingStrategy( lockable, lockMode ); } else { @@ -223,6 +263,7 @@ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + @Override public boolean supportsEmptyInList() { return false; } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/TypeNames.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/TypeNames.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/TypeNames.java 17 Aug 2012 14:33:39 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/TypeNames.java 30 Jul 2014 16:15:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,115 +20,135 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect; -import java.util.Map; import java.util.HashMap; +import java.util.Map; import java.util.TreeMap; -import java.util.Iterator; import org.hibernate.MappingException; -import org.hibernate.util.StringHelper; +import org.hibernate.internal.util.StringHelper; /** - * This class maps a type to names. Associations - * may be marked with a capacity. Calling the get() - * method with a type and actual size n will return - * the associated name with smallest capacity >= n, + * This class maps a type to names. Associations may be marked with a capacity. Calling the get() + * method with a type and actual size n will return the associated name with smallest capacity >= n, * if available and an unmarked default type otherwise. * Eg, setting *

    - *	names.put(type,        "TEXT" );
    - *	names.put(type,   255, "VARCHAR($l)" );
    - *	names.put(type, 65534, "LONGVARCHAR($l)" );
    + *	names.put( type,        "TEXT" );
    + *	names.put( type,   255, "VARCHAR($l)" );
    + *	names.put( type, 65534, "LONGVARCHAR($l)" );
      * 
    * will give you back the following: *
    - *  names.get(type)         // --> "TEXT" (default)
    - *  names.get(type,    100) // --> "VARCHAR(100)" (100 is in [0:255])
    - *  names.get(type,   1000) // --> "LONGVARCHAR(1000)" (1000 is in [256:65534])
    - *  names.get(type, 100000) // --> "TEXT" (default)
    + *  names.get( type )         // --> "TEXT" (default)
    + *  names.get( type,    100 ) // --> "VARCHAR(100)" (100 is in [0:255])
    + *  names.get( type,   1000 ) // --> "LONGVARCHAR(1000)" (1000 is in [256:65534])
    + *  names.get( type, 100000 ) // --> "TEXT" (default)
      * 
    * On the other hand, simply putting *
    - *	names.put(type, "VARCHAR($l)" );
    + *	names.put( type, "VARCHAR($l)" );
      * 
    * would result in *
    - *  names.get(type)        // --> "VARCHAR($l)" (will cause trouble)
    - *  names.get(type, 100)   // --> "VARCHAR(100)"
    - *  names.get(type, 10000) // --> "VARCHAR(10000)"
    + *  names.get( type )        // --> "VARCHAR($l)" (will cause trouble)
    + *  names.get( type, 100 )   // --> "VARCHAR(100)"
    + *  names.get( type, 10000 ) // --> "VARCHAR(10000)"
      * 
    * * @author Christoph Beck */ public class TypeNames { + /** + * Holds default type mappings for a typeCode. This is the non-sized mapping + */ + private Map defaults = new HashMap(); - private HashMap weighted = new HashMap(); - private HashMap defaults = new HashMap(); + /** + * Holds the weighted mappings for a typeCode. The nested map is a TreeMap to sort its contents + * based on the key (the weighting) to ensure proper iteration ordering during {@link #get(int, long, int, int)} + */ + private Map> weighted = new HashMap>(); /** * get default type name for specified type - * @param typecode the type key + * + * @param typeCode the type key + * * @return the default type name associated with specified key + * + * @throws MappingException Indicates that no registrations were made for that typeCode */ - public String get(int typecode) throws MappingException { - String result = (String) defaults.get( new Integer(typecode) ); - if (result==null) throw new MappingException("No Dialect mapping for JDBC type: " + typecode); + public String get(int typeCode) throws MappingException { + final String result = defaults.get( typeCode ); + if ( result == null ) { + throw new MappingException( "No Dialect mapping for JDBC type: " + typeCode ); + } return result; } /** * get type name for specified type and size - * @param typecode the type key + * + * @param typeCode the type key * @param size the SQL length * @param scale the SQL scale * @param precision the SQL precision - * @return the associated name with smallest capacity >= size, - * if available and the default type name otherwise + * + * @return the associated name with smallest capacity >= size, if available and the default type name otherwise + * + * @throws MappingException Indicates that no registrations were made for that typeCode */ - public String get(int typecode, int size, int precision, int scale) throws MappingException { - Map map = (Map) weighted.get( new Integer(typecode) ); - if ( map!=null && map.size()>0 ) { + public String get(int typeCode, long size, int precision, int scale) throws MappingException { + final Map map = weighted.get( typeCode ); + if ( map != null && map.size() > 0 ) { // iterate entries ordered by capacity to find first fit - Iterator entries = map.entrySet().iterator(); - while ( entries.hasNext() ) { - Map.Entry entry = (Map.Entry)entries.next(); - if ( size <= ( (Integer) entry.getKey() ).intValue() ) { - return replace( (String) entry.getValue(), size, precision, scale ); + for ( Map.Entry entry: map.entrySet() ) { + if ( size <= entry.getKey() ) { + return replace( entry.getValue(), size, precision, scale ); } } } - return replace( get(typecode), size, precision, scale ); + + // if we get here one of 2 things happened: + // 1) There was no weighted registration for that typeCode + // 2) There was no weighting whose max capacity was big enough to contain size + return replace( get( typeCode ), size, precision, scale ); } - - private static String replace(String type, int size, int precision, int scale) { - type = StringHelper.replaceOnce(type, "$s", Integer.toString(scale) ); - type = StringHelper.replaceOnce(type, "$l", Integer.toString(size) ); - return StringHelper.replaceOnce(type, "$p", Integer.toString(precision) ); + + private static String replace(String type, long size, int precision, int scale) { + type = StringHelper.replaceOnce( type, "$s", Integer.toString( scale ) ); + type = StringHelper.replaceOnce( type, "$l", Long.toString( size ) ); + return StringHelper.replaceOnce( type, "$p", Integer.toString( precision ) ); } /** - * set a type name for specified type key and capacity - * @param typecode the type key + * Register a weighted typeCode mapping + * + * @param typeCode the JDBC type code + * @param capacity The capacity for this weighting + * @param value The mapping (type name) */ - public void put(int typecode, int capacity, String value) { - TreeMap map = (TreeMap)weighted.get( new Integer(typecode) ); - if (map == null) {// add new ordered map - map = new TreeMap(); - weighted.put( new Integer(typecode), map ); + public void put(int typeCode, long capacity, String value) { + Map map = weighted.get( typeCode ); + if ( map == null ) { + // add new ordered map + map = new TreeMap(); + weighted.put( typeCode, map ); } - map.put(new Integer(capacity), value); + map.put( capacity, value ); } /** - * set a default type name for specified type key - * @param typecode the type key + * Register a default (non-weighted) typeCode mapping + * + * @param typeCode the type key + * @param value The mapping (type name) */ - public void put(int typecode, String value) { - defaults.put( new Integer(typecode), value ); + public void put(int typeCode, String value) { + defaults.put( typeCode, value ); } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/package.html,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/package.html 17 Aug 2012 14:33:40 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/package.html 30 Jul 2014 16:15:51 -0000 1.1.2.1 @@ -1,10 +1,10 @@ Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/function/AbstractAnsiTrimEmulationFunction.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,19 +20,10 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; +import org.hibernate.type.StandardBasicTypes; -import org.hibernate.Hibernate; -import org.hibernate.QueryException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.type.Type; - -import java.util.List; -import java.util.ArrayList; - /** * A {@link SQLFunction} implementation that emulates the ANSI SQL trim function * on dialects which do not support the full definition. However, this function @@ -42,129 +33,260 @@ * * @author Steve Ebersole */ -public class AnsiTrimEmulationFunction implements SQLFunction { +public class AnsiTrimEmulationFunction extends AbstractAnsiTrimEmulationFunction { + /** + * The default {@code ltrim} function name + */ + public static final String LTRIM = "ltrim"; - private static final SQLFunction LEADING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( ?1 )"); - private static final SQLFunction TRAILING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "rtrim( ?1 )"); - private static final SQLFunction BOTH_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?1 ) )"); - private static final SQLFunction BOTH_SPACE_TRIM_FROM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?2 ) )"); + /** + * The default {@code rtrim} function name + */ + public static final String RTRIM = "rtrim"; - private static final SQLFunction LEADING_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( rtrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ), ' ', ?2 ), '${space}$', ' ' )" ); - private static final SQLFunction TRAILING_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( ltrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ), ' ', ?2 ), '${space}$', ' ' )" ); - private static final SQLFunction BOTH_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( ltrim( rtrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ) ), ' ', ?2 ), '${space}$', ' ' )" ); + /** + * The default {@code replace} function name + */ + public static final String REPLACE = "replace"; - public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { - return Hibernate.STRING; + /** + * The placeholder used to represent whitespace + */ + public static final String SPACE_PLACEHOLDER = "${space}$"; + + /** + * The SQLFunctionTemplate pattern for the trimming leading spaces + */ + public static final String LEADING_SPACE_TRIM_TEMPLATE = LTRIM + "(?1)"; + + /** + * The SQLFunctionTemplate pattern for the trimming trailing spaces + */ + public static final String TRAILING_SPACE_TRIM_TEMPLATE = RTRIM + "(?1)"; + + /** + * The SQLFunctionTemplate pattern for the trimming both leading and trailing spaces + */ + public static final String BOTH_SPACE_TRIM_TEMPLATE = LTRIM + "(" + RTRIM + "(?1))"; + + /** + * The SQLFunctionTemplate pattern for the trimming both leading and trailing spaces, with the optional FROM keyword. + * Different because we need to skip the FROM keyword in the SQLFunctionTemplate processing + */ + public static final String BOTH_SPACE_TRIM_FROM_TEMPLATE = LTRIM + "(" + RTRIM + "(?2))"; + + /** + * A template for the series of calls required to trim non-space chars from the beginning of text. + *

    + * NOTE : essentially we:

      + *
    1. replace all space chars with the text '${space}$'
    2. + *
    3. replace all the actual replacement chars with space chars
    4. + *
    5. perform left-trimming (that removes any of the space chars we just added which occur at the beginning of the text)
    6. + *
    7. replace all space chars with the replacement char
    8. + *
    9. replace all the '${space}$' text with space chars
    10. + *
    + */ + public static final String LEADING_TRIM_TEMPLATE = + REPLACE + "(" + + REPLACE + "(" + + LTRIM + "(" + + REPLACE + "(" + + REPLACE + "(" + + "?1," + + "' '," + + "'" + SPACE_PLACEHOLDER + "'" + + ")," + + "?2," + + "' '" + + ")" + + ")," + + "' '," + + "?2" + + ")," + + "'" + SPACE_PLACEHOLDER + "'," + + "' '" + + ")"; + + /** + * A template for the series of calls required to trim non-space chars from the end of text. + *

    + * NOTE: essentially the same series of calls as outlined in {@link #LEADING_TRIM_TEMPLATE} except that here, + * instead of left-trimming the added spaces, we right-trim them to remove them from the end of the text. + */ + public static final String TRAILING_TRIM_TEMPLATE = + REPLACE + "(" + + REPLACE + "(" + + RTRIM + "(" + + REPLACE + "(" + + REPLACE + "(" + + "?1," + + "' '," + + "'" + SPACE_PLACEHOLDER + "'" + + ")," + + "?2," + + "' '" + + ")" + + ")," + + "' '," + + "?2" + + ")," + + "'" + SPACE_PLACEHOLDER + "'," + + "' '" + + ")"; + + /** + * A template for the series of calls required to trim non-space chars from both the beginning and the end of text. + *

    + * NOTE: again, we have a series of calls that is essentially the same as outlined in {@link #LEADING_TRIM_TEMPLATE} + * except that here we perform both left (leading) and right (trailing) trimming. + */ + public static final String BOTH_TRIM_TEMPLATE = + REPLACE + "(" + + REPLACE + "(" + + LTRIM + "(" + + RTRIM + "(" + + REPLACE + "(" + + REPLACE + "(" + + "?1," + + "' '," + + "'" + SPACE_PLACEHOLDER + "'" + + ")," + + "?2," + + "' '" + + ")" + + ")" + + ")," + + "' '," + + "?2" + + ")," + + "'" + SPACE_PLACEHOLDER + "'," + + "' '" + + ")"; + + private final SQLFunction leadingSpaceTrim; + private final SQLFunction trailingSpaceTrim; + private final SQLFunction bothSpaceTrim; + private final SQLFunction bothSpaceTrimFrom; + + private final SQLFunction leadingTrim; + private final SQLFunction trailingTrim; + private final SQLFunction bothTrim; + + /** + * Constructs a new AnsiTrimEmulationFunction using {@link #LTRIM}, {@link #RTRIM}, and {@link #REPLACE} + * respectively. + * + * @see #AnsiTrimEmulationFunction(String,String,String) + */ + public AnsiTrimEmulationFunction() { + this( LTRIM, RTRIM, REPLACE ); } - public boolean hasArguments() { - return true; + /** + * Constructs a trim() emulation function definition using the specified function calls. + * + * @param ltrimFunctionName The left trim function to use. + * @param rtrimFunctionName The right trim function to use. + * @param replaceFunctionName The replace function to use. + */ + public AnsiTrimEmulationFunction(String ltrimFunctionName, String rtrimFunctionName, String replaceFunctionName) { + leadingSpaceTrim = new SQLFunctionTemplate( + StandardBasicTypes.STRING, + LEADING_SPACE_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName ) + ); + + trailingSpaceTrim = new SQLFunctionTemplate( + StandardBasicTypes.STRING, + TRAILING_SPACE_TRIM_TEMPLATE.replaceAll( RTRIM, rtrimFunctionName ) + ); + + bothSpaceTrim = new SQLFunctionTemplate( + StandardBasicTypes.STRING, + BOTH_SPACE_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName ) + .replaceAll( RTRIM, rtrimFunctionName ) + ); + + bothSpaceTrimFrom = new SQLFunctionTemplate( + StandardBasicTypes.STRING, + BOTH_SPACE_TRIM_FROM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName ) + .replaceAll( RTRIM, rtrimFunctionName ) + ); + + leadingTrim = new SQLFunctionTemplate( + StandardBasicTypes.STRING, + LEADING_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName ) + .replaceAll( RTRIM, rtrimFunctionName ) + .replaceAll( REPLACE,replaceFunctionName ) + ); + + trailingTrim = new SQLFunctionTemplate( + StandardBasicTypes.STRING, + TRAILING_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName ) + .replaceAll( RTRIM, rtrimFunctionName ) + .replaceAll( REPLACE,replaceFunctionName ) + ); + + bothTrim = new SQLFunctionTemplate( + StandardBasicTypes.STRING, + BOTH_TRIM_TEMPLATE.replaceAll( LTRIM, ltrimFunctionName ) + .replaceAll( RTRIM, rtrimFunctionName ) + .replaceAll( REPLACE,replaceFunctionName ) + ); } - public boolean hasParenthesesIfNoArguments() { - return false; + /** + * {@inheritDoc} + */ + @Override + protected SQLFunction resolveBothSpaceTrimFunction() { + return bothSpaceTrim; } - public String render(List args, SessionFactoryImplementor factory) throws QueryException { - // according to both the ANSI-SQL and EJB3 specs, trim can either take - // exactly one parameter or a variable number of parameters between 1 and 4. - // from the SQL spec: - // - // ::= - // TRIM - // - // ::= - // [ [ ] [ ] FROM ] - // - // ::= - // LEADING - // | TRAILING - // | BOTH - // - // If only is omitted, BOTH is assumed; - // if is omitted, space is assumed - if ( args.size() == 1 ) { - // we have the form: trim(trimSource) - // so we trim leading and trailing spaces - return BOTH_SPACE_TRIM.render( args, factory ); - } - else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) { - // we have the form: trim(from trimSource). - // This is functionally equivalent to trim(trimSource) - return BOTH_SPACE_TRIM_FROM.render( args, factory ); - } - else { - // otherwise, a trim-specification and/or a trim-character - // have been specified; we need to decide which options - // are present and "do the right thing" - boolean leading = true; // should leading trim-characters be trimmed? - boolean trailing = true; // should trailing trim-characters be trimmed? - String trimCharacter = null; // the trim-character - String trimSource = null; // the trim-source + /** + * {@inheritDoc} + */ + @Override + protected SQLFunction resolveBothSpaceTrimFromFunction() { + return bothSpaceTrimFrom; + } - // potentialTrimCharacterArgIndex = 1 assumes that a - // trim-specification has been specified. we handle the - // exception to that explicitly - int potentialTrimCharacterArgIndex = 1; - String firstArg = ( String ) args.get( 0 ); - if ( "leading".equalsIgnoreCase( firstArg ) ) { - trailing = false; - } - else if ( "trailing".equalsIgnoreCase( firstArg ) ) { - leading = false; - } - else if ( "both".equalsIgnoreCase( firstArg ) ) { - } - else { - potentialTrimCharacterArgIndex = 0; - } + /** + * {@inheritDoc} + */ + @Override + protected SQLFunction resolveLeadingSpaceTrimFunction() { + return leadingSpaceTrim; + } - String potentialTrimCharacter = ( String ) args.get( potentialTrimCharacterArgIndex ); - if ( "from".equalsIgnoreCase( potentialTrimCharacter ) ) { - trimCharacter = "' '"; - trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 ); - } - else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) { - trimCharacter = "' '"; - trimSource = potentialTrimCharacter; - } - else { - trimCharacter = potentialTrimCharacter; - if ( "from".equalsIgnoreCase( ( String ) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) { - trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 2 ); - } - else { - trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 ); - } - } + /** + * {@inheritDoc} + */ + @Override + protected SQLFunction resolveTrailingSpaceTrimFunction() { + return trailingSpaceTrim; + } - List argsToUse = null; - argsToUse = new ArrayList(); - argsToUse.add( trimSource ); - argsToUse.add( trimCharacter ); + /** + * {@inheritDoc} + */ + @Override + protected SQLFunction resolveBothTrimFunction() { + return bothTrim; + } - if ( trimCharacter.equals( "' '" ) ) { - if ( leading && trailing ) { - return BOTH_SPACE_TRIM.render( argsToUse, factory ); - } - else if ( leading ) { - return LEADING_SPACE_TRIM.render( argsToUse, factory ); - } - else { - return TRAILING_SPACE_TRIM.render( argsToUse, factory ); - } - } - else { - if ( leading && trailing ) { - return BOTH_TRIM.render( argsToUse, factory ); - } - else if ( leading ) { - return LEADING_TRIM.render( argsToUse, factory ); - } - else { - return TRAILING_TRIM.render( argsToUse, factory ); - } - } - } + /** + * {@inheritDoc} + */ + @Override + protected SQLFunction resolveLeadingTrimFunction() { + return leadingTrim; } + + /** + * {@inheritDoc} + */ + @Override + protected SQLFunction resolveTrailingTrimFunction() { + return trailingTrim; + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/function/AnsiTrimFunction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/function/AvgWithArgumentCastFunction.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/CastFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/CastFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/CastFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/CastFunction.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,59 +20,54 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; import java.util.List; import org.hibernate.QueryException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.type.Type; -import org.hibernate.type.TypeFactory; /** - * ANSI-SQL style cast(foo as type) where the type is - * a Hibernate type + * ANSI-SQL style {@code cast(foo as type)} where the type is a Hibernate type + * * @author Gavin King */ public class CastFunction implements SQLFunction { - - public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { - return columnType; //note there is a wierd implementation in the client side - } - + @Override public boolean hasArguments() { return true; } + @Override public boolean hasParenthesesIfNoArguments() { return true; } - public String render(List args, SessionFactoryImplementor factory) throws QueryException { + @Override + public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { + // this is really just a guess, unless the caller properly identifies the 'type' argument here + return columnType; + } + + @Override + public String render(Type columnType, List args, SessionFactoryImplementor factory) throws QueryException { if ( args.size()!=2 ) { throw new QueryException("cast() requires two arguments"); } - String type = (String) args.get(1); - int[] sqlTypeCodes = TypeFactory.heuristicType(type).sqlTypes(factory); + final String type = (String) args.get( 1 ); + final int[] sqlTypeCodes = factory.getTypeResolver().heuristicType( type ).sqlTypes( factory ); if ( sqlTypeCodes.length!=1 ) { throw new QueryException("invalid Hibernate type for cast()"); } String sqlType = factory.getDialect().getCastTypeName( sqlTypeCodes[0] ); - if (sqlType==null) { - //TODO: never reached, since getTypeName() actually throws an exception! + if ( sqlType == null ) { + //TODO: never reached, since getExplicitHibernateTypeName() actually throws an exception! sqlType = type; } - /*else { - //trim off the length/precision/scale - int loc = sqlType.indexOf('('); - if (loc>-1) { - sqlType = sqlType.substring(0, loc); - } - }*/ - return "cast(" + args.get(0) + " as " + sqlType + ')'; + return "cast(" + args.get( 0 ) + " as " + sqlType + ')'; } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/CharIndexFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/CharIndexFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/CharIndexFunction.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/CharIndexFunction.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,48 +20,54 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; - import java.util.List; -import org.hibernate.Hibernate; import org.hibernate.QueryException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.Type; /** * Emulation of locate() on Sybase + * * @author Nathan Moon */ public class CharIndexFunction implements SQLFunction { - - public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { - return Hibernate.INTEGER; - } - + @Override public boolean hasArguments() { return true; } + @Override public boolean hasParenthesesIfNoArguments() { return true; } - public String render(List args, SessionFactoryImplementor factory) throws QueryException { - boolean threeArgs = args.size() > 2; - Object pattern = args.get(0); - Object string = args.get(1); - Object start = threeArgs ? args.get(2) : null; + @Override + public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { + return StandardBasicTypes.INTEGER; + } - StringBuffer buf = new StringBuffer(); - buf.append("charindex(").append( pattern ).append(", "); - if (threeArgs) buf.append( "right("); + @Override + public String render(Type columnType, List args, SessionFactoryImplementor factory) throws QueryException { + final boolean threeArgs = args.size() > 2; + final Object pattern = args.get( 0 ); + final Object string = args.get( 1 ); + final Object start = threeArgs ? args.get( 2 ) : null; + + final StringBuilder buf = new StringBuilder(); + buf.append( "charindex(" ).append( pattern ).append( ", " ); + if (threeArgs) { + buf.append( "right(" ); + } buf.append( string ); - if (threeArgs) buf.append( ", char_length(" ).append( string ).append(")-(").append( start ).append("-1))"); - buf.append(')'); + if (threeArgs) { + buf.append( ", char_length(" ).append( string ).append( ")-(" ).append( start ).append( "-1))" ); + } + buf.append( ')' ); return buf.toString(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ClassicAvgFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ClassicAvgFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ClassicAvgFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ClassicAvgFunction.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,29 +20,30 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ 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.engine.spi.Mapping; +import org.hibernate.type.StandardBasicTypes; 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 { + /** + * Constructs a ClassicAvgFunction + */ public ClassicAvgFunction() { super( "avg" ); } + @Override public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { int[] sqlTypes; try { @@ -51,13 +52,17 @@ catch ( MappingException me ) { throw new QueryException( me ); } - if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in avg()" ); - int sqlType = sqlTypes[0]; + + if ( sqlTypes.length != 1 ) { + throw new QueryException( "multi-column type in avg()" ); + } + + final int sqlType = sqlTypes[0]; if ( sqlType == Types.INTEGER || sqlType == Types.BIGINT || sqlType == Types.TINYINT ) { - return Hibernate.FLOAT; + return StandardBasicTypes.FLOAT; } else { return columnType; } } -} \ No newline at end of file +} Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ClassicCountFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ClassicCountFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ClassicCountFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ClassicCountFunction.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,27 +20,28 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; -import org.hibernate.Hibernate; -import org.hibernate.engine.Mapping; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.type.StandardBasicTypes; 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 { + /** + * Constructs a ClassicCountFunction + */ public ClassicCountFunction() { super( "count" ); } + @Override public Type getReturnType(Type columnType, Mapping mapping) { - return Hibernate.INTEGER; + return StandardBasicTypes.INTEGER; } -} \ No newline at end of file +} Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ClassicSumFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ClassicSumFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ClassicSumFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ClassicSumFunction.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,19 +20,20 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ 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 { + /** + * Constructs a ClassicSumFunction + */ public ClassicSumFunction() { super( "sum" ); } -} \ No newline at end of file +} Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ConditionalParenthesisFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ConditionalParenthesisFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ConditionalParenthesisFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ConditionalParenthesisFunction.java 30 Jul 2014 16:16:52 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,13 +20,11 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; - import java.util.List; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.type.Type; /** @@ -36,28 +34,39 @@ * @author Jonathan Levinson */ public class ConditionalParenthesisFunction extends StandardSQLFunction { - + /** + * Constructs a ConditionalParenthesisFunction with the given name + * + * @param name The function name + */ public ConditionalParenthesisFunction(String name) { super( name ); } + /** + * Constructs a ConditionalParenthesisFunction with the given name + * + * @param name The function name + * @param type The function return type + */ public ConditionalParenthesisFunction(String name, Type type) { super( name, type ); } + @Override public boolean hasParenthesesIfNoArguments() { return false; } - public String render(List args, SessionFactoryImplementor factory) { - final boolean hasArgs = !args.isEmpty(); - StringBuffer buf = new StringBuffer(); - buf.append( getName() ); + @Override + public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor sessionFactory) { + final boolean hasArgs = !arguments.isEmpty(); + final StringBuilder buf = new StringBuilder( getName() ); if ( hasArgs ) { buf.append( "(" ); - for ( int i = 0; i < args.size(); i++ ) { - buf.append( args.get( i ) ); - if ( i < args.size() - 1 ) { + for ( int i = 0; i < arguments.size(); i++ ) { + buf.append( arguments.get( i ) ); + if ( i < arguments.size() - 1 ) { buf.append( ", " ); } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ConvertFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ConvertFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ConvertFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/ConvertFunction.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,16 +20,14 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; - import java.util.List; import org.hibernate.QueryException; -import org.hibernate.Hibernate; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.Type; /** @@ -38,25 +36,29 @@ * @author Jonathan Levinson */ public class ConvertFunction implements SQLFunction { - - public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { - return Hibernate.STRING; - } - + @Override public boolean hasArguments() { return true; } + @Override public boolean hasParenthesesIfNoArguments() { return true; } - public String render(List args, SessionFactoryImplementor factory) throws QueryException { + @Override + public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException { + return StandardBasicTypes.STRING; + } + + @Override + public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) throws QueryException { if ( args.size() != 2 && args.size() != 3 ) { throw new QueryException( "convert() requires two or three arguments" ); } - String type = ( String ) args.get( 1 ); + final String type = (String) args.get( 1 ); + if ( args.size() == 2 ) { return "{fn convert(" + args.get( 0 ) + " , " + type + ")}"; } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/DerbyConcatFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/DerbyConcatFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/DerbyConcatFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/DerbyConcatFunction.java 30 Jul 2014 16:16:52 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,23 +20,22 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; -import java.util.List; import java.util.Iterator; +import java.util.List; -import org.hibernate.Hibernate; import org.hibernate.QueryException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.Type; /** * A specialized concat() function definition in which:

      - *
    1. we translate to use the concat operator ('||')
    2. - *
    3. wrap dynamic parameters in CASTs to VARCHAR
    4. + *
    5. we translate to use the concat operator ('||')
    6. + *
    7. wrap dynamic parameters in CASTs to VARCHAR
    8. *
    *

    * This last spec is to deal with a limitation on DB2 and variants (e.g. Derby) @@ -51,28 +50,31 @@ /** * {@inheritDoc} *

    - * Here we always return {@link Hibernate#STRING}. + * Here we always return true */ - public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { - return Hibernate.STRING; + @Override + public boolean hasArguments() { + return true; } /** * {@inheritDoc} *

    * Here we always return true */ - public boolean hasArguments() { + @Override + public boolean hasParenthesesIfNoArguments() { return true; } /** * {@inheritDoc} *

    - * Here we always return true + * Here we always return {@link StandardBasicTypes#STRING}. */ - public boolean hasParenthesesIfNoArguments() { - return true; + @Override + public Type getReturnType(Type argumentType, Mapping mapping) throws QueryException { + return StandardBasicTypes.STRING; } /** @@ -82,28 +84,26 @@ * this method. The logic here says that if not all the incoming args are dynamic parameters * (i.e. ?) then we simply use the Derby concat operator (||) on the unchanged * arg elements. However, if all the args are dynamic parameters, then we need to wrap the individual - * arg elements in cast function calls, use the concantenation operator on the cast + * arg elements in cast function calls, use the concatenation operator on the cast * returns, and then wrap that whole thing in a call to the Derby varchar function. */ - public String render(List args, SessionFactoryImplementor factory) throws QueryException { - boolean areAllArgsParams = true; - Iterator itr = args.iterator(); - while ( itr.hasNext() ) { - final String arg = ( String ) itr.next(); - if ( ! "?".equals( arg ) ) { - areAllArgsParams = false; + @Override + public String render(Type argumentType, List args, SessionFactoryImplementor factory) throws QueryException { + // first figure out if all arguments are dynamic (jdbc parameters) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + boolean areAllArgumentsDynamic = true; + for ( Object arg1 : args ) { + final String arg = (String) arg1; + if ( !"?".equals( arg ) ) { + // we found a non-dynamic argument + areAllArgumentsDynamic = false; break; } } - if ( areAllArgsParams ) { + if ( areAllArgumentsDynamic ) { return join( args.iterator(), - new StringTransformer() { - public String transform(String string) { - return "cast( ? as varchar(32672) )"; - } - }, + CAST_STRING_TRANSFORMER, new StringJoinTemplate() { public String getBeginning() { return "varchar( "; @@ -120,11 +120,7 @@ else { return join( args.iterator(), - new StringTransformer() { - public String transform(String string) { - return string; - } - }, + NO_TRANSFORM_STRING_TRANSFORMER, new StringJoinTemplate() { public String getBeginning() { return "("; @@ -141,9 +137,31 @@ } private static interface StringTransformer { + /** + * Transform a string to another + * + * @param string The String to be transformed + * + * @return The transformed form + */ public String transform(String string); } + private static final StringTransformer CAST_STRING_TRANSFORMER = new StringTransformer() { + @Override + public String transform(String string) { + // expectation is that incoming string is "?" + return "cast( ? as varchar(32672) )"; + } + }; + + private static final StringTransformer NO_TRANSFORM_STRING_TRANSFORMER = new StringTransformer() { + @Override + public String transform(String string) { + return string; + } + }; + private static interface StringJoinTemplate { /** * Getter for property 'beginning'. @@ -165,10 +183,11 @@ public String getEnding(); } - private String join(Iterator/**/ elements, StringTransformer elementTransformer, StringJoinTemplate template) { - StringBuffer buffer = new StringBuffer( template.getBeginning() ); + private static String join(Iterator/**/ elements, StringTransformer elementTransformer, StringJoinTemplate template) { + // todo : make this available via StringHelper? + final StringBuilder buffer = new StringBuilder( template.getBeginning() ); while ( elements.hasNext() ) { - final String element = ( String ) elements.next(); + final String element = (String) elements.next(); buffer.append( elementTransformer.transform( element ) ); if ( elements.hasNext() ) { buffer.append( template.getSeparator() ); Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/NoArgSQLFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/NoArgSQLFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/NoArgSQLFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/NoArgSQLFunction.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,53 +20,69 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; import java.util.List; import org.hibernate.QueryException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.type.Type; - /** * A function which takes no arguments + * * @author Michi */ public class NoArgSQLFunction implements SQLFunction { - private Type returnType; - private boolean hasParenthesesIfNoArguments; - private String name; + private Type returnType; + private boolean hasParenthesesIfNoArguments; + private String name; - public NoArgSQLFunction(String name, Type returnType) { - this(name, returnType, true); - } + /** + * Constructs a NoArgSQLFunction + * + * @param name The function name + * @param returnType The function return type + */ + public NoArgSQLFunction(String name, Type returnType) { + this( name, returnType, true ); + } - public NoArgSQLFunction(String name, Type returnType, boolean hasParenthesesIfNoArguments) { - this.returnType = returnType; - this.hasParenthesesIfNoArguments = hasParenthesesIfNoArguments; - this.name = name; - } + /** + * Constructs a NoArgSQLFunction + * + * @param name The function name + * @param returnType The function return type + * @param hasParenthesesIfNoArguments Does the function call need parenthesis if there are no arguments? + */ + public NoArgSQLFunction(String name, Type returnType, boolean hasParenthesesIfNoArguments) { + this.returnType = returnType; + this.hasParenthesesIfNoArguments = hasParenthesesIfNoArguments; + this.name = name; + } - public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { - return returnType; - } + @Override + public boolean hasArguments() { + return false; + } - public boolean hasArguments() { - return false; - } + @Override + public boolean hasParenthesesIfNoArguments() { + return hasParenthesesIfNoArguments; + } - public boolean hasParenthesesIfNoArguments() { - return hasParenthesesIfNoArguments; - } - - public String render(List args, SessionFactoryImplementor factory) throws QueryException { - if ( args.size()>0 ) { - throw new QueryException("function takes no arguments: " + name); - } - return hasParenthesesIfNoArguments ? name + "()" : name; - } + @Override + public Type getReturnType(Type argumentType, Mapping mapping) throws QueryException { + return returnType; + } + + @Override + public String render(Type argumentType, List args, SessionFactoryImplementor factory) throws QueryException { + if ( args.size() > 0 ) { + throw new QueryException( "function takes no arguments: " + name ); + } + return hasParenthesesIfNoArguments ? name + "()" : name; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/NvlFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/NvlFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/NvlFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/NvlFunction.java 30 Jul 2014 16:16:52 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,46 +20,48 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; import java.util.List; import org.hibernate.QueryException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.type.Type; /** - * Emulation of coalesce() on Oracle, using multiple - * nvl() calls + * Emulation of coalesce() on Oracle, using multiple nvl() calls + * * @author Gavin King */ public class NvlFunction implements SQLFunction { - - public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { - return columnType; - } - + @Override public boolean hasArguments() { return true; } + @Override public boolean hasParenthesesIfNoArguments() { return true; } - public String render(List args, SessionFactoryImplementor factory) throws QueryException { - int lastIndex = args.size()-1; - Object last = args.remove(lastIndex); - if ( lastIndex==0 ) return last.toString(); - Object secondLast = args.get(lastIndex-1); - String nvl = "nvl(" + secondLast + ", " + last + ")"; - args.set(lastIndex-1, nvl); - return render(args, factory); + @Override + public Type getReturnType(Type argumentType, Mapping mapping) throws QueryException { + return argumentType; } - - + @Override + @SuppressWarnings("unchecked") + public String render(Type argumentType, List args, SessionFactoryImplementor factory) throws QueryException { + final int lastIndex = args.size()-1; + final Object last = args.remove( lastIndex ); + if ( lastIndex==0 ) { + return last.toString(); + } + final Object secondLast = args.get( lastIndex-1 ); + final String nvl = "nvl(" + secondLast + ", " + last + ")"; + args.set( lastIndex-1, nvl ); + return render( argumentType, args, factory ); + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/PositionSubstringFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/PositionSubstringFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/PositionSubstringFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/PositionSubstringFunction.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,50 +20,60 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; - import java.util.List; -import org.hibernate.Hibernate; import org.hibernate.QueryException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.Type; /** * Emulation of locate() on PostgreSQL + * * @author Gavin King */ public class PositionSubstringFunction implements SQLFunction { - - public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { - return Hibernate.INTEGER; - } - + @Override public boolean hasArguments() { return true; } + @Override public boolean hasParenthesesIfNoArguments() { return true; } - public String render(List args, SessionFactoryImplementor factory) throws QueryException { - boolean threeArgs = args.size() > 2; - Object pattern = args.get(0); - Object string = args.get(1); - Object start = threeArgs ? args.get(2) : null; + @Override + public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException { + return StandardBasicTypes.INTEGER; + } - StringBuffer buf = new StringBuffer(); - if (threeArgs) buf.append('('); - buf.append("position(").append( pattern ).append(" in "); - if (threeArgs) buf.append( "substring("); + @Override + public String render(Type firstArgumentType, List args, SessionFactoryImplementor factory) throws QueryException { + final boolean threeArgs = args.size() > 2; + final Object pattern = args.get( 0 ); + final Object string = args.get( 1 ); + final Object start = threeArgs ? args.get( 2 ) : null; + + final StringBuilder buf = new StringBuilder(); + if (threeArgs) { + buf.append( '(' ); + } + buf.append( "position(" ).append( pattern ).append( " in " ); + if (threeArgs) { + buf.append( "substring("); + } buf.append( string ); - if (threeArgs) buf.append( ", " ).append( start ).append(')'); - buf.append(')'); - if (threeArgs) buf.append('+').append( start ).append("-1)"); + if (threeArgs) { + buf.append( ", " ).append( start ).append( ')' ); + } + buf.append( ')' ); + if (threeArgs) { + buf.append( '+' ).append( start ).append( "-1)" ); + } return buf.toString(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/SQLFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/SQLFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/SQLFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/SQLFunction.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,15 +20,14 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; import java.util.List; import org.hibernate.QueryException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.type.Type; /** @@ -40,42 +39,51 @@ * provide details required for processing of the function. * * @author David Channon + * @author Steve Ebersole */ public interface SQLFunction { /** - * The return type of the function. May be either a concrete type which - * is preset, or variable depending upon the type of the first function - * argument. - * - * @param columnType the type of the first argument - * @param mapping The mapping source. - * @return The type to be expected as a return. - * @throws org.hibernate.QueryException Indicates an issue resolving the return type. - */ - public Type getReturnType(Type columnType, Mapping mapping) throws QueryException; - - /** * Does this function have any arguments? * * @return True if the function expects to have parameters; false otherwise. */ public boolean hasArguments(); /** - * If there are no arguments, are parens required? + * If there are no arguments, are parentheses required? * * @return True if a no-arg call of this function requires parentheses. */ public boolean hasParenthesesIfNoArguments(); /** + * The return type of the function. May be either a concrete type which is preset, or variable depending upon + * the type of the first function argument. + *

    + * Note, the 'firstArgumentType' parameter should match the one passed into {@link #render} + * + * @param firstArgumentType The type of the first argument + * @param mapping The mapping source. + * + * @return The type to be expected as a return. + * + * @throws org.hibernate.QueryException Indicates an issue resolving the return type. + */ + public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException; + + /** * Render the function call as SQL fragment. + *

    + * Note, the 'firstArgumentType' parameter should match the one passed into {@link #getReturnType} * - * @param args The function arguments + * @param firstArgumentType The type of the first argument + * @param arguments The function arguments * @param factory The SessionFactory + * * @return The rendered function call + * * @throws org.hibernate.QueryException Indicates a problem rendering the * function call. */ - public String render(List args, SessionFactoryImplementor factory) throws QueryException; + public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor factory) throws QueryException; } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/SQLFunctionRegistry.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/SQLFunctionRegistry.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/SQLFunctionRegistry.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/SQLFunctionRegistry.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; @@ -29,29 +28,52 @@ import org.hibernate.dialect.Dialect; +/** + * Defines a registry for SQLFunction instances + * + * @author Steve Ebersole + */ public class SQLFunctionRegistry { - private final Dialect dialect; - private final Map userFunctions; - - public SQLFunctionRegistry(Dialect dialect, Map userFunctions) { + private final Map userFunctions; + + /** + * Constructs a SQLFunctionRegistry + * + * @param dialect The dialect + * @param userFunctions Any application-supplied function definitions + */ + public SQLFunctionRegistry(Dialect dialect, Map userFunctions) { this.dialect = dialect; - this.userFunctions = new HashMap(); - this.userFunctions.putAll( userFunctions ); + this.userFunctions = new HashMap( userFunctions ); } - + + /** + * Find a SQLFunction by name + * + * @param functionName The name of the function to locate + * + * @return The located function, maye return {@code null} + */ 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 ? + final String name = functionName.toLowerCase(); + final SQLFunction userFunction = userFunctions.get( name ); + return userFunction != null + ? userFunction + : dialect.getFunctions().get( name ); } + /** + * Does this registry contain the named function + * + * @param functionName The name of the function to attempt to locate + * + * @return {@code true} if the registry contained that function + */ + @SuppressWarnings("UnusedDeclaration") 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. + final String name = functionName.toLowerCase(); + return userFunctions.containsKey( name ) || dialect.getFunctions().containsKey( name ); } } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/SQLFunctionTemplate.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/SQLFunctionTemplate.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/SQLFunctionTemplate.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/SQLFunctionTemplate.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,127 +20,78 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; +import java.util.List; + import org.hibernate.QueryException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.type.Type; -import java.util.ArrayList; -import java.util.List; - /** - * Represents HQL functions that can have different representations in different SQL dialects. - * E.g. in HQL we can define function concat(?1, ?2) to concatenate two strings - * p1 and p2. Target SQL function will be dialect-specific, e.g. (?1 || ?2) for - * Oracle, concat(?1, ?2) for MySql, (?1 + ?2) for MS SQL. - * Each dialect will define a template as a string (exactly like above) marking function + * Represents HQL functions that can have different representations in different SQL dialects where that + * difference can be handled via a template/pattern. + *

    + * E.g. in HQL we can define function concat(?1, ?2) to concatenate two strings + * p1 and p2. Dialects would register different versions of this class *using the same name* (concat) but with + * different templates or patterns; (?1 || ?2) for Oracle, concat(?1, ?2) for MySql, + * (?1 + ?2) for MS SQL. Each dialect will define a template as a string (exactly like above) marking function * parameters with '?' followed by parameter's index (first index is 1). * * @author Alexey Loubyansky - * @version $Revision$ */ public class SQLFunctionTemplate implements SQLFunction { private final Type type; - private final boolean hasArguments; + private final TemplateRenderer renderer; private final boolean hasParenthesesIfNoArgs; - private final String template; - private final String[] chunks; - private final int[] paramIndexes; - + /** + * Constructs a SQLFunctionTemplate + * + * @param type The functions return type + * @param template The function template + */ public SQLFunctionTemplate(Type type, String template) { this( type, template, true ); } + /** + * Constructs a SQLFunctionTemplate + * + * @param type The functions return type + * @param template The function template + * @param hasParenthesesIfNoArgs If there are no arguments, are parentheses required? + */ public SQLFunctionTemplate(Type type, String template, boolean hasParenthesesIfNoArgs) { this.type = type; - this.template = template; - - List chunkList = new ArrayList(); - List paramList = new ArrayList(); - StringBuffer chunk = new StringBuffer( 10 ); - StringBuffer index = new StringBuffer( 2 ); - - for ( int i = 0; i < template.length(); ++i ) { - char c = template.charAt( i ); - if ( c == '?' ) { - chunkList.add( chunk.toString() ); - chunk.delete( 0, chunk.length() ); - - while ( ++i < template.length() ) { - c = template.charAt( i ); - if ( Character.isDigit( c ) ) { - index.append( c ); - } - else { - chunk.append( c ); - break; - } - } - - paramList.add( new Integer( Integer.parseInt( index.toString() ) - 1 ) ); - index.delete( 0, index.length() ); - } - else { - chunk.append( c ); - } - } - - if ( chunk.length() > 0 ) { - chunkList.add( chunk.toString() ); - } - - chunks = ( String[] ) chunkList.toArray( new String[chunkList.size()] ); - paramIndexes = new int[paramList.size()]; - for ( int i = 0; i < paramIndexes.length; ++i ) { - paramIndexes[i] = ( ( Integer ) paramList.get( i ) ).intValue(); - } - - hasArguments = paramIndexes.length > 0; + this.renderer = new TemplateRenderer( template ); this.hasParenthesesIfNoArgs = hasParenthesesIfNoArgs; } - /** - * Applies the template to passed in arguments. - * @param args function arguments - * - * @return generated SQL function call - */ - public String render(List args, SessionFactoryImplementor factory) { - StringBuffer buf = new StringBuffer(); - for ( int i = 0; i < chunks.length; ++i ) { - if ( i < paramIndexes.length ) { - Object arg = paramIndexes[i] < args.size() ? args.get( paramIndexes[i] ) : null; - if ( arg != null ) { - buf.append( chunks[i] ).append( arg ); - } - } - else { - buf.append( chunks[i] ); - } - } - return buf.toString(); + @Override + public String render(Type argumentType, List args, SessionFactoryImplementor factory) { + return renderer.render( args, factory ); } - // SQLFunction implementation - - public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { + @Override + public Type getReturnType(Type argumentType, Mapping mapping) throws QueryException { return type; } + @Override public boolean hasArguments() { - return hasArguments; + return renderer.getAnticipatedNumberOfArguments() > 0; } + @Override public boolean hasParenthesesIfNoArguments() { return hasParenthesesIfNoArgs; } + @Override public String toString() { - return template; + return renderer.getTemplate(); } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/function/StandardAnsiSqlAggregationFunctions.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/StandardJDBCEscapeFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/StandardJDBCEscapeFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/StandardJDBCEscapeFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/StandardJDBCEscapeFunction.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,14 +20,12 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; - import java.util.List; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.type.Type; -import org.hibernate.engine.SessionFactoryImplementor; /** * Analogous to {@link org.hibernate.dialect.function.StandardSQLFunction} @@ -37,18 +35,22 @@ * @author Steve Ebersole */ public class StandardJDBCEscapeFunction extends StandardSQLFunction { - public StandardJDBCEscapeFunction(String name) { - super( name ); - } - + /** + * Constructs a StandardJDBCEscapeFunction + * + * @param name The function name + * @param typeValue The function return type + */ public StandardJDBCEscapeFunction(String name, Type typeValue) { super( name, typeValue ); } - public String render(List args, SessionFactoryImplementor factory) { - return "{fn " + super.render( args, factory ) + "}"; + @Override + public String render(Type argumentType, List args, SessionFactoryImplementor factory) { + return "{fn " + super.render( argumentType, args, factory ) + "}"; } + @Override public String toString() { return "{fn " + getName() + "...}"; } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/StandardSQLFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/StandardSQLFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/StandardSQLFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/StandardSQLFunction.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,14 +20,13 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; import java.util.List; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.type.Type; /** @@ -40,7 +39,7 @@ */ public class StandardSQLFunction implements SQLFunction { private final String name; - private final Type type; + private final Type registeredType; /** * Construct a standard SQL function definition with a variable return type; @@ -60,11 +59,11 @@ * Construct a standard SQL function definition with a static return type. * * @param name The name of the function. - * @param type The static return type. + * @param registeredType The static return type. */ - public StandardSQLFunction(String name, Type type) { + public StandardSQLFunction(String name, Type registeredType) { this.name = name; - this.type = type; + this.registeredType = registeredType; } /** @@ -83,48 +82,40 @@ * not static. */ public Type getType() { - return type; + return registeredType; } - /** - * {@inheritDoc} - */ - public Type getReturnType(Type columnType, Mapping mapping) { - // return the concrete type, or the underlying type if a concrete type - // was not specified - return type == null ? columnType : type; - } - - /** - * {@inheritDoc} - */ + @Override public boolean hasArguments() { return true; } - /** - * {@inheritDoc} - */ + @Override public boolean hasParenthesesIfNoArguments() { return true; } - /** - * {@inheritDoc} - */ - public String render(List args, SessionFactoryImplementor factory) { - StringBuffer buf = new StringBuffer(); + @Override + public Type getReturnType(Type firstArgumentType, Mapping mapping) { + return registeredType == null ? firstArgumentType : registeredType; + } + + @Override + public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor sessionFactory) { + final StringBuilder buf = new StringBuilder(); buf.append( name ).append( '(' ); - for ( int i = 0; i < args.size(); i++ ) { - buf.append( args.get( i ) ); - if ( i < args.size() - 1 ) { + for ( int i = 0; i < arguments.size(); i++ ) { + buf.append( arguments.get( i ) ); + if ( i < arguments.size() - 1 ) { buf.append( ", " ); } } return buf.append( ')' ).toString(); } + @Override public String toString() { return name; } + } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/function/TemplateRenderer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/function/TrimFunctionTemplate.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/VarArgsSQLFunction.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/VarArgsSQLFunction.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/VarArgsSQLFunction.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/VarArgsSQLFunction.java 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,41 +20,39 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.function; import java.util.List; import org.hibernate.QueryException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.type.Type; /** - * Support for slightly more general templating than {@link StandardSQLFunction}, - * with an unlimited number of arguments. + * Support for slightly more general templating than {@link StandardSQLFunction}, with an unlimited number of arguments. * * @author Gavin King */ public class VarArgsSQLFunction implements SQLFunction { private final String begin; private final String sep; private final String end; - private final Type type; + private final Type registeredType; /** * Constructs a VarArgsSQLFunction instance with a 'static' return type. An example of a 'static' * return type would be something like an UPPER function which is always returning * a SQL VARCHAR and thus a string type. * - * @param type The return type. + * @param registeredType The return type. * @param begin The beginning of the function templating. * @param sep The separator for each individual function argument. * @param end The end of the function templating. */ - public VarArgsSQLFunction(Type type, String begin, String sep, String end) { - this.type = type; + public VarArgsSQLFunction(Type registeredType, String begin, String sep, String end) { + this.registeredType = registeredType; this.begin = begin; this.sep = sep; this.end = end; @@ -70,54 +68,42 @@ * @param sep The separator for each individual function argument. * @param end The end of the function templating. * - * @see #getReturnType Specifically, the 'columnType' argument is the 'dynamic' type. + * @see #getReturnType Specifically, the 'firstArgumentType' argument is the 'dynamic' type. */ public VarArgsSQLFunction(String begin, String sep, String end) { this( null, begin, sep, end ); } - /** - * {@inheritDoc} - */ - public Type getReturnType(Type columnType, Mapping mapping) throws QueryException { - return type == null ? columnType : type; - } - - /** - * {@inheritDoc} - *

    - * Always returns true here. - */ + @Override public boolean hasArguments() { return true; } - /** - * {@inheritDoc} - *

    - * Always returns true here. - */ + @Override public boolean hasParenthesesIfNoArguments() { return true; } - /** - * {@inheritDoc} - */ - public String render(List args, SessionFactoryImplementor factory) throws QueryException { - StringBuffer buf = new StringBuffer().append( begin ); - for ( int i = 0; i < args.size(); i++ ) { - buf.append( transformArgument( ( String ) args.get( i ) ) ); - if ( i < args.size() - 1 ) { + @Override + public Type getReturnType(Type firstArgumentType, Mapping mapping) throws QueryException { + return registeredType == null ? firstArgumentType : registeredType; + } + + @Override + public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor factory) { + final StringBuilder buf = new StringBuilder().append( begin ); + for ( int i = 0; i < arguments.size(); i++ ) { + buf.append( transformArgument( (String) arguments.get( i ) ) ); + if ( i < arguments.size() - 1 ) { buf.append( sep ); } } return buf.append( end ).toString(); } /** - * Called from {@link #render} to allow applying a change or transformation to each individual - * argument. + * Called from {@link #render} to allow applying a change or transformation + * to each individual argument. * * @param argument The argument being processed. * @return The transformed argument; may be the same, though should never be null. Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/function/package.html,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/package.html 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/function/package.html 30 Jul 2014 16:16:53 -0000 1.1.2.1 @@ -1,10 +1,10 @@ Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/AbstractSelectLockingStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/LockingStrategy.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/LockingStrategy.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/LockingStrategy.java 17 Aug 2012 14:33:56 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/LockingStrategy.java 30 Jul 2014 16:16:29 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,20 +20,18 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.lock; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.StaleObjectStateException; -import org.hibernate.JDBCException; - import java.io.Serializable; +import org.hibernate.StaleObjectStateException; +import org.hibernate.engine.spi.SessionImplementor; + /** * A strategy abstraction for how locks are obtained in the underlying database. *

    - * All locking provided implemenations assume the underlying database supports + * All locking provided implementations assume the underlying database supports * (and that the connection is in) at least read-committed transaction isolation. * The most glaring exclusion to this is HSQLDB which only offers support for * READ_UNCOMMITTED isolation. @@ -51,11 +49,13 @@ * @param id The id of the row to be locked * @param version The current version (or null if not versioned) * @param object The object logically being locked (currently not used) + * @param timeout timeout in milliseconds, 0 = no wait, -1 = wait indefinitely * @param session The session from which the lock request originated - * @throws StaleObjectStateException Indicates an optimisitic lock failure - * as part of acquiring the requested database lock. - * @throws JDBCException + * + * @throws StaleObjectStateException Indicates an inability to locate the database row as part of acquiring + * the requested lock. + * @throws LockingStrategyException Indicates a failure in the lock attempt */ - public void lock(Serializable id, Object version, Object object, SessionImplementor session) - throws StaleObjectStateException, JDBCException; + public void lock(Serializable id, Object version, Object object, int timeout, SessionImplementor session) + throws StaleObjectStateException, LockingStrategyException; } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/LockingStrategyException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/OptimisticEntityLockException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/OptimisticForceIncrementLockingStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/OptimisticLockingStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/PessimisticEntityLockException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/PessimisticForceIncrementLockingStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/PessimisticReadSelectLockingStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/PessimisticReadUpdateLockingStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/PessimisticWriteSelectLockingStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/PessimisticWriteUpdateLockingStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/SelectLockingStrategy.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/SelectLockingStrategy.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/SelectLockingStrategy.java 17 Aug 2012 14:33:56 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/SelectLockingStrategy.java 30 Jul 2014 16:16:29 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,25 +20,24 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.lock; -import org.hibernate.persister.entity.Lockable; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.StaleObjectStateException; -import org.hibernate.JDBCException; -import org.hibernate.LockMode; -import org.hibernate.sql.SimpleSelect; -import org.hibernate.pretty.MessageHelper; -import org.hibernate.exception.JDBCExceptionHelper; - import java.io.Serializable; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.hibernate.JDBCException; +import org.hibernate.LockMode; +import org.hibernate.LockOptions; +import org.hibernate.StaleObjectStateException; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.persister.entity.Lockable; +import org.hibernate.pretty.MessageHelper; +import org.hibernate.sql.SimpleSelect; + /** * A locking strategy where the locks are obtained through select statements. *

    @@ -47,96 +46,85 @@ * * @see org.hibernate.dialect.Dialect#getForUpdateString(org.hibernate.LockMode) * @see org.hibernate.dialect.Dialect#appendLockHint(org.hibernate.LockMode, String) - * @since 3.2 * * @author Steve Ebersole + * @since 3.2 */ -public class SelectLockingStrategy implements LockingStrategy { - - private final Lockable lockable; - private final LockMode lockMode; - private final String sql; - +public class SelectLockingStrategy extends AbstractSelectLockingStrategy { /** * Construct a locking strategy based on SQL SELECT statements. * * @param lockable The metadata for the entity to be locked. * @param lockMode Indictates the type of lock to be acquired. */ public SelectLockingStrategy(Lockable lockable, LockMode lockMode) { - this.lockable = lockable; - this.lockMode = lockMode; - this.sql = generateLockString(); + super( lockable, lockMode ); } - /** - * @see LockingStrategy#lock - */ + @Override public void lock( - Serializable id, - Object version, - Object object, - SessionImplementor session) throws StaleObjectStateException, JDBCException { - - SessionFactoryImplementor factory = session.getFactory(); + Serializable id, + Object version, + Object object, + int timeout, + SessionImplementor session) throws StaleObjectStateException, JDBCException { + final String sql = determineSql( timeout ); + final SessionFactoryImplementor factory = session.getFactory(); try { - PreparedStatement st = session.getBatcher().prepareSelectStatement( sql ); + final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql ); try { - lockable.getIdentifierType().nullSafeSet( st, id, 1, session ); - if ( lockable.isVersioned() ) { - lockable.getVersionType().nullSafeSet( + getLockable().getIdentifierType().nullSafeSet( st, id, 1, session ); + if ( getLockable().isVersioned() ) { + getLockable().getVersionType().nullSafeSet( st, version, - lockable.getIdentifierType().getColumnSpan( factory ) + 1, + getLockable().getIdentifierType().getColumnSpan( factory ) + 1, session ); } - ResultSet rs = st.executeQuery(); + final ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st ); try { if ( !rs.next() ) { if ( factory.getStatistics().isStatisticsEnabled() ) { factory.getStatisticsImplementor() - .optimisticFailure( lockable.getEntityName() ); + .optimisticFailure( getLockable().getEntityName() ); } - throw new StaleObjectStateException( lockable.getEntityName(), id ); + throw new StaleObjectStateException( getLockable().getEntityName(), id ); } } finally { - rs.close(); + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st ); } } finally { - session.getBatcher().closeStatement( st ); + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - session.getFactory().getSQLExceptionConverter(), + throw session.getFactory().getSQLExceptionHelper().convert( sqle, - "could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ), + "could not lock: " + MessageHelper.infoString( getLockable(), id, session.getFactory() ), sql ); } } - protected LockMode getLockMode() { - return lockMode; - } - - protected String generateLockString() { - SessionFactoryImplementor factory = lockable.getFactory(); - SimpleSelect select = new SimpleSelect( factory.getDialect() ) - .setLockMode( lockMode ) - .setTableName( lockable.getRootTableName() ) - .addColumn( lockable.getRootTableIdentifierColumnNames()[0] ) - .addCondition( lockable.getRootTableIdentifierColumnNames(), "=?" ); - if ( lockable.isVersioned() ) { - select.addCondition( lockable.getVersionColumnName(), "=?" ); + protected String generateLockString(int timeout) { + final SessionFactoryImplementor factory = getLockable().getFactory(); + final LockOptions lockOptions = new LockOptions( getLockMode() ); + lockOptions.setTimeOut( timeout ); + final SimpleSelect select = new SimpleSelect( factory.getDialect() ) + .setLockOptions( lockOptions ) + .setTableName( getLockable().getRootTableName() ) + .addColumn( getLockable().getRootTableIdentifierColumnNames()[0] ) + .addCondition( getLockable().getRootTableIdentifierColumnNames(), "=?" ); + if ( getLockable().isVersioned() ) { + select.addCondition( getLockable().getVersionColumnName(), "=?" ); } if ( factory.getSettings().isCommentsEnabled() ) { - select.setComment( lockMode + " lock " + lockable.getEntityName() ); + select.setComment( getLockMode() + " lock " + getLockable().getEntityName() ); } return select.toStatementString(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/UpdateLockingStrategy.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/UpdateLockingStrategy.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/UpdateLockingStrategy.java 17 Aug 2012 14:33:56 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/UpdateLockingStrategy.java 30 Jul 2014 16:16:29 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,38 +20,39 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.dialect.lock; -import org.hibernate.persister.entity.Lockable; -import org.hibernate.LockMode; +import java.io.Serializable; +import java.sql.PreparedStatement; +import java.sql.SQLException; + import org.hibernate.HibernateException; -import org.hibernate.StaleObjectStateException; import org.hibernate.JDBCException; +import org.hibernate.LockMode; +import org.hibernate.StaleObjectStateException; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.persister.entity.Lockable; import org.hibernate.pretty.MessageHelper; -import org.hibernate.exception.JDBCExceptionHelper; import org.hibernate.sql.Update; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.engine.SessionFactoryImplementor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.SQLException; +import org.jboss.logging.Logger; /** * A locking strategy where the locks are obtained through update statements. *

    * This strategy is not valid for read style locks. * - * @since 3.2 - * * @author Steve Ebersole + * @since 3.2 */ public class UpdateLockingStrategy implements LockingStrategy { - private static final Logger log = LoggerFactory.getLogger( UpdateLockingStrategy.class ); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + UpdateLockingStrategy.class.getName() + ); private final Lockable lockable; private final LockMode lockMode; @@ -71,29 +72,29 @@ throw new HibernateException( "[" + lockMode + "] not valid for update statement" ); } if ( !lockable.isVersioned() ) { - log.warn( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]" ); + LOG.writeLocksNotSupported( lockable.getEntityName() ); this.sql = null; } else { this.sql = generateLockString(); } } - /** - * @see LockingStrategy#lock - */ + @Override public void lock( Serializable id, - Object version, - Object object, - SessionImplementor session) throws StaleObjectStateException, JDBCException { + Object version, + Object object, + int timeout, + SessionImplementor session) throws StaleObjectStateException, JDBCException { if ( !lockable.isVersioned() ) { throw new HibernateException( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]" ); } + // todo : should we additionally check the current isolation mode explicitly? - SessionFactoryImplementor factory = session.getFactory(); + final SessionFactoryImplementor factory = session.getFactory(); try { - PreparedStatement st = session.getBatcher().prepareSelectStatement( sql ); + final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql ); try { lockable.getVersionType().nullSafeSet( st, version, 1, session ); int offset = 2; @@ -105,33 +106,34 @@ lockable.getVersionType().nullSafeSet( st, version, offset, session ); } - int affected = st.executeUpdate(); + final int affected = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ); if ( affected < 0 ) { - factory.getStatisticsImplementor().optimisticFailure( lockable.getEntityName() ); + if (factory.getStatistics().isStatisticsEnabled()) { + factory.getStatisticsImplementor().optimisticFailure( lockable.getEntityName() ); + } throw new StaleObjectStateException( lockable.getEntityName(), id ); } } finally { - session.getBatcher().closeStatement( st ); + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - session.getFactory().getSQLExceptionConverter(), - sqle, - "could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ), - sql + throw session.getFactory().getSQLExceptionHelper().convert( + sqle, + "could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ), + sql ); } } protected String generateLockString() { - SessionFactoryImplementor factory = lockable.getFactory(); - Update update = new Update( factory.getDialect() ); + final SessionFactoryImplementor factory = lockable.getFactory(); + final Update update = new Update( factory.getDialect() ); update.setTableName( lockable.getRootTableName() ); - update.setPrimaryKeyColumnNames( lockable.getRootTableIdentifierColumnNames() ); + update.addPrimaryKeyColumns( lockable.getRootTableIdentifierColumnNames() ); update.setVersionColumnName( lockable.getVersionColumnName() ); update.addColumn( lockable.getVersionColumnName() ); if ( factory.getSettings().isCommentsEnabled() ) { Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/lock/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/pagination/AbstractLimitHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/pagination/CUBRIDLimitHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/pagination/LegacyLimitHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/pagination/LimitHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/pagination/LimitHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/pagination/NoopLimitHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/pagination/SQLServer2005LimitHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/pagination/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/unique/DB2UniqueDelegate.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/unique/DefaultUniqueDelegate.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/unique/InformixUniqueDelegate.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/unique/UniqueDelegate.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/dialect/unique/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/CacheSQLStateConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/Configurable.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/exception/ConstraintViolationException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/exception/ConstraintViolationException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/exception/ConstraintViolationException.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/exception/ConstraintViolationException.java 30 Jul 2014 16:16:57 -0000 1.1.2.1 @@ -23,11 +23,10 @@ * */ package org.hibernate.exception; +import java.sql.SQLException; import org.hibernate.JDBCException; -import java.sql.SQLException; - /** * Implementation of JDBCException indicating that the requested DML operation * resulted in a violation of a defined integrity constraint. Index: 3rdParty_sources/hibernate-core/org/hibernate/exception/DataException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/exception/DataException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/exception/DataException.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/exception/DataException.java 30 Jul 2014 16:16:57 -0000 1.1.2.1 @@ -23,11 +23,10 @@ * */ package org.hibernate.exception; +import java.sql.SQLException; import org.hibernate.JDBCException; -import java.sql.SQLException; - /** * Implementation of JDBCException indicating that evaluation of the * valid SQL statement against the given data resulted in some Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/ExceptionUtils.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/exception/GenericJDBCException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/exception/GenericJDBCException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/exception/GenericJDBCException.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/exception/GenericJDBCException.java 30 Jul 2014 16:16:56 -0000 1.1.2.1 @@ -23,11 +23,10 @@ * */ package org.hibernate.exception; +import java.sql.SQLException; import org.hibernate.JDBCException; -import java.sql.SQLException; - /** * Generic, non-specific JDBCException. * Index: 3rdParty_sources/hibernate-core/org/hibernate/exception/JDBCConnectionException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/exception/JDBCConnectionException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/exception/JDBCConnectionException.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/exception/JDBCConnectionException.java 30 Jul 2014 16:16:56 -0000 1.1.2.1 @@ -23,11 +23,10 @@ * */ package org.hibernate.exception; +import java.sql.SQLException; import org.hibernate.JDBCException; -import java.sql.SQLException; - /** * Implementation of JDBCException indicating problems with communicating with the * database (can also include incorrect JDBC setup). Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/JDBCExceptionHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/exception/LockAcquisitionException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/exception/LockAcquisitionException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/exception/LockAcquisitionException.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/exception/LockAcquisitionException.java 30 Jul 2014 16:16:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,14 +20,13 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.exception; -import org.hibernate.JDBCException; - import java.sql.SQLException; +import org.hibernate.JDBCException; + /** * Implementation of JDBCException indicating a problem acquiring lock * on the database. Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/LockTimeoutException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/Nestable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/NestableDelegate.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/NestableException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/NestableRuntimeException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/SQLExceptionConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/SQLExceptionConverterFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/exception/SQLGrammarException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/exception/SQLGrammarException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/exception/SQLGrammarException.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/exception/SQLGrammarException.java 30 Jul 2014 16:16:57 -0000 1.1.2.1 @@ -23,11 +23,10 @@ * */ package org.hibernate.exception; +import java.sql.SQLException; import org.hibernate.JDBCException; -import java.sql.SQLException; - /** * Implementation of JDBCException indicating that the SQL sent to the database * server was invalid (syntax error, invalid object references, etc). Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/SQLStateConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/TemplatedViolatedConstraintNameExtracter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/ViolatedConstraintNameExtracter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/internal/CacheSQLExceptionConversionDelegate.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/internal/SQLExceptionTypeDelegate.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/internal/SQLStateConversionDelegate.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/internal/SQLStateConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/internal/StandardSQLExceptionConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/spi/AbstractSQLExceptionConversionDelegate.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/spi/Configurable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/spi/ConversionContext.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/spi/SQLExceptionConversionDelegate.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/spi/SQLExceptionConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/spi/SQLExceptionConverterFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/spi/TemplatedViolatedConstraintNameExtracter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/exception/spi/ViolatedConstraintNameExtracter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/id/AbstractPostInsertGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/AbstractPostInsertGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/AbstractPostInsertGenerator.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/AbstractPostInsertGenerator.java 30 Jul 2014 16:16:18 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,25 +20,33 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id; import java.io.Serializable; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.spi.SessionImplementor; /** - * Basic implementation of the {@link PostInsertIdentifierGenerator} - * contract. + * Basic implementation of the {@link PostInsertIdentifierGenerator} contract. * * @author Gavin King */ -public abstract class AbstractPostInsertGenerator implements PostInsertIdentifierGenerator { - /** - * {@inheritDoc} - */ +public abstract class AbstractPostInsertGenerator + implements PostInsertIdentifierGenerator, BulkInsertionCapableIdentifierGenerator { + @Override public Serializable generate(SessionImplementor s, Object obj) { - return IdentifierGeneratorFactory.POST_INSERT_INDICATOR; + return IdentifierGeneratorHelper.POST_INSERT_INDICATOR; } + + @Override + public boolean supportsBulkInsertionIdentifierGeneration() { + return true; + } + + @Override + public String determineBulkInsertionIdentifierGenerationSelectFragment(Dialect dialect) { + return null; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/id/AbstractUUIDGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/AbstractUUIDGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/AbstractUUIDGenerator.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/AbstractUUIDGenerator.java 30 Jul 2014 16:16:19 -0000 1.1.2.1 @@ -23,10 +23,10 @@ * */ package org.hibernate.id; - import java.net.InetAddress; -import org.hibernate.util.BytesHelper; +import org.hibernate.internal.util.BytesHelper; + /** * The base class for identifier generators that use a UUID algorithm. This * class implements the algorithm, subclasses define the identifier Index: 3rdParty_sources/hibernate-core/org/hibernate/id/Assigned.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/Assigned.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/Assigned.java 17 Aug 2012 14:33:50 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/Assigned.java 30 Jul 2014 16:16:18 -0000 1.1.2.1 @@ -23,14 +23,13 @@ * */ package org.hibernate.id; - import java.io.Serializable; import java.util.Properties; import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.type.Type; /** @@ -47,25 +46,20 @@ private String entityName; public Serializable generate(SessionImplementor session, Object obj) throws HibernateException { - - final Serializable id = session.getEntityPersister( entityName, obj ) - //TODO: cache the persister, this shows up in yourkit - .getIdentifier( obj, session.getEntityMode() ); - - if (id==null) { + //TODO: cache the persister, this shows up in yourkit + final Serializable id = session.getEntityPersister( entityName, obj ).getIdentifier( obj, session ); + if ( id == null ) { throw new IdentifierGenerationException( - "ids for this class must be manually assigned before calling save(): " + - entityName + "ids for this class must be manually assigned before calling save(): " + entityName ); } return id; } - public void configure(Type type, Properties params, Dialect d) - throws MappingException { + public void configure(Type type, Properties params, Dialect d) throws MappingException { entityName = params.getProperty(ENTITY_NAME); - if (entityName==null) { + if ( entityName == null ) { throw new MappingException("no entity name"); } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/BulkInsertionCapableIdentifierGenerator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/CompositeNestedGeneratedValueGenerator.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/id/Configurable.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/Configurable.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/Configurable.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/Configurable.java 30 Jul 2014 16:16:19 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.id; - import java.util.Properties; import org.hibernate.MappingException; Index: 3rdParty_sources/hibernate-core/org/hibernate/id/ForeignGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/ForeignGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/ForeignGenerator.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/ForeignGenerator.java 30 Jul 2014 16:16:17 -0000 1.1.2.1 @@ -23,17 +23,17 @@ * */ package org.hibernate.id; - import java.io.Serializable; import java.util.Properties; -import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.Session; import org.hibernate.TransientObjectException; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.ForeignKeys; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.internal.ForeignKeys; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.loader.PropertyPath; +import org.hibernate.persister.entity.EntityPersister; import org.hibernate.type.EntityType; import org.hibernate.type.Type; @@ -48,64 +48,86 @@ * @author Gavin King */ public class ForeignGenerator implements IdentifierGenerator, Configurable { - - private String propertyName; private String entityName; + private String propertyName; /** - * @see org.hibernate.id.IdentifierGenerator#generate(org.hibernate.engine.SessionImplementor, java.lang.Object) + * Getter for property 'entityName'. + * + * @return Value for property 'entityName'. */ - public Serializable generate(SessionImplementor sessionImplementor, Object object) - throws HibernateException { - - Session session = (Session) sessionImplementor; + public String getEntityName() { + return entityName; + } - Object associatedObject = sessionImplementor.getFactory() - .getClassMetadata( entityName ) - .getPropertyValue( object, propertyName, session.getEntityMode() ); - + /** + * Getter for property 'propertyName'. + * + * @return Value for property 'propertyName'. + */ + public String getPropertyName() { + return propertyName; + } + + /** + * Getter for property 'role'. Role is the {@link #getPropertyName property name} qualified by the + * {@link #getEntityName entity name}. + * + * @return Value for property 'role'. + */ + public String getRole() { + return getEntityName() + '.' + getPropertyName(); + } + + @Override + public void configure(Type type, Properties params, Dialect d) { + propertyName = params.getProperty( "property" ); + entityName = params.getProperty( ENTITY_NAME ); + if ( propertyName==null ) { + throw new MappingException( "param named \"property\" is required for foreign id generation strategy" ); + } + } + + @Override + public Serializable generate(SessionImplementor sessionImplementor, Object object) { + Session session = ( Session ) sessionImplementor; + + final EntityPersister persister = sessionImplementor.getFactory().getEntityPersister( entityName ); + Object associatedObject = persister.getPropertyValue( object, propertyName ); if ( associatedObject == null ) { throw new IdentifierGenerationException( - "attempted to assign id from null one-to-one property: " + - propertyName - ); + "attempted to assign id from null one-to-one property [" + getRole() + "]" + ); } - - EntityType type = (EntityType) sessionImplementor.getFactory() - .getClassMetadata( entityName ) - .getPropertyType( propertyName ); + final EntityType foreignValueSourceType; + final Type propertyType = persister.getPropertyType( propertyName ); + if ( propertyType.isEntityType() ) { + // the normal case + foreignValueSourceType = (EntityType) propertyType; + } + else { + // try identifier mapper + foreignValueSourceType = (EntityType) persister.getPropertyType( PropertyPath.IDENTIFIER_MAPPER_PROPERTY + "." + propertyName ); + } + Serializable id; try { id = ForeignKeys.getEntityIdentifierIfNotUnsaved( - type.getAssociatedEntityName(), - associatedObject, + foreignValueSourceType.getAssociatedEntityName(), + associatedObject, sessionImplementor - ); + ); } catch (TransientObjectException toe) { - id = session.save( type.getAssociatedEntityName(), associatedObject ); + id = session.save( foreignValueSourceType.getAssociatedEntityName(), associatedObject ); } if ( session.contains(object) ) { //abort the save (the object is already saved by a circular cascade) - return IdentifierGeneratorFactory.SHORT_CIRCUIT_INDICATOR; + return IdentifierGeneratorHelper.SHORT_CIRCUIT_INDICATOR; //throw new IdentifierGenerationException("save associated object first, or disable cascade for inverse association"); } return id; } - - /** - * @see org.hibernate.id.Configurable#configure(org.hibernate.type.Type, java.util.Properties, org.hibernate.dialect.Dialect) - */ - public void configure(Type type, Properties params, Dialect d) - throws MappingException { - - propertyName = params.getProperty("property"); - entityName = params.getProperty(ENTITY_NAME); - if (propertyName==null) throw new MappingException( - "param named \"property\" is required for foreign id generation strategy" - ); - } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/id/GUIDGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/GUIDGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/GUIDGenerator.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/GUIDGenerator.java 30 Jul 2014 16:16:19 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id; @@ -29,52 +28,57 @@ import java.sql.ResultSet; import java.sql.SQLException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.HibernateException; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.exception.JDBCExceptionHelper; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.CoreLogging; +import org.hibernate.internal.CoreMessageLogger; /** * Generates string values using the SQL Server NEWID() function. * * @author Joseph Fifield */ public class GUIDGenerator implements IdentifierGenerator { + private static final CoreMessageLogger LOG = CoreLogging.messageLogger( GUIDGenerator.class ); - private static final Logger log = LoggerFactory.getLogger(GUIDGenerator.class); + private static boolean WARNED; - public Serializable generate(SessionImplementor session, Object obj) - throws HibernateException { - + public GUIDGenerator() { + if ( !WARNED ) { + WARNED = true; + LOG.deprecatedUuidGenerator( UUIDGenerator.class.getName(), UUIDGenerationStrategy.class.getName() ); + } + } + + public Serializable generate(SessionImplementor session, Object obj) throws HibernateException { final String sql = session.getFactory().getDialect().getSelectGUIDString(); try { - PreparedStatement st = session.getBatcher().prepareSelectStatement(sql); + PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql ); try { - ResultSet rs = st.executeQuery(); + ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st ); final String result; try { - rs.next(); + if ( !rs.next() ) { + throw new HibernateException( "The database returned no GUID identity value" ); + } result = rs.getString(1); } finally { - rs.close(); + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st ); } - log.debug("GUID identifier generated: " + result); + LOG.guidGenerated(result); return result; } finally { - session.getBatcher().closeStatement(st); + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } } catch (SQLException sqle) { - throw JDBCExceptionHelper.convert( - session.getFactory().getSQLExceptionConverter(), + throw session.getFactory().getSQLExceptionHelper().convert( sqle, "could not retrieve GUID", sql ); } } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/id/IdentifierGenerationException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/IdentifierGenerationException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/IdentifierGenerationException.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/IdentifierGenerationException.java 30 Jul 2014 16:16:19 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.id; - import org.hibernate.HibernateException; /** Index: 3rdParty_sources/hibernate-core/org/hibernate/id/IdentifierGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/IdentifierGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/IdentifierGenerator.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/IdentifierGenerator.java 30 Jul 2014 16:16:19 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,15 +20,14 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id; -import org.hibernate.HibernateException; -import org.hibernate.engine.SessionImplementor; - import java.io.Serializable; +import org.hibernate.HibernateException; +import org.hibernate.engine.spi.SessionImplementor; + /** * The general contract between a class that generates unique * identifiers and the Session. It is not intended that @@ -41,28 +40,33 @@ * Implementations that accept configuration parameters should * also implement Configurable. *
    - * Implementors must be threadsafe + * Implementors must be thread-safe * * @author Gavin King + * * @see PersistentIdentifierGenerator * @see Configurable */ public interface IdentifierGenerator { + /** + * The configuration parameter holding the entity name + */ + public static final String ENTITY_NAME = "entity_name"; - /** - * The configuration parameter holding the entity name - */ - public static final String ENTITY_NAME = "entity_name"; - /** + * The configuration parameter holding the JPA entity name + */ + public static final String JPA_ENTITY_NAME = "jpa_entity_name"; + + /** * Generate a new identifier. - * @param session - * @param object the entity or toplevel collection for which the id is being generated * + * @param session The session from which the request originates + * @param object the entity or collection (idbag) for which the id is being generated + * * @return a new identifier - * @throws HibernateException + * + * @throws HibernateException Indicates trouble generating the identifier */ - public Serializable generate(SessionImplementor session, Object object) - throws HibernateException; - + public Serializable generate(SessionImplementor session, Object object) throws HibernateException; } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/IdentifierGeneratorAggregator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/IdentifierGeneratorFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/IdentifierGeneratorHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/id/IdentityGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/IdentityGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/IdentityGenerator.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/IdentityGenerator.java 30 Jul 2014 16:16:17 -0000 1.1.2.1 @@ -23,21 +23,20 @@ * */ package org.hibernate.id; - import java.io.Serializable; +import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.sql.PreparedStatement; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate; -import org.hibernate.id.insert.IdentifierGeneratingInsert; -import org.hibernate.id.insert.AbstractSelectingDelegate; +import org.hibernate.AssertionFailure; +import org.hibernate.HibernateException; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.id.insert.AbstractReturningDelegate; +import org.hibernate.id.insert.AbstractSelectingDelegate; +import org.hibernate.id.insert.IdentifierGeneratingInsert; +import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate; import org.hibernate.id.insert.InsertSelectIdentityInsert; -import org.hibernate.dialect.Dialect; -import org.hibernate.HibernateException; -import org.hibernate.AssertionFailure; /** * A generator for use with ANSI-SQL IDENTITY columns used as the primary key. @@ -87,22 +86,26 @@ } protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException { - return session.getBatcher().prepareStatement( insertSQL, true ); + return session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( insertSQL, PreparedStatement.RETURN_GENERATED_KEYS ); } - public Serializable executeAndExtract(PreparedStatement insert) throws SQLException { - insert.executeUpdate(); + public Serializable executeAndExtract(PreparedStatement insert, SessionImplementor session) throws SQLException { + session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( insert ); ResultSet rs = null; try { rs = insert.getGeneratedKeys(); - return IdentifierGeneratorFactory.getGeneratedIdentity( + return IdentifierGeneratorHelper.getGeneratedIdentity( rs, + persister.getRootTableKeyColumnNames()[0], persister.getIdentifierType() ); } finally { if ( rs != null ) { - rs.close(); + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, insert ); } } } @@ -131,21 +134,23 @@ } protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException { - return session.getBatcher().prepareStatement( insertSQL, false ); + return session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( insertSQL, PreparedStatement.NO_GENERATED_KEYS ); } - public Serializable executeAndExtract(PreparedStatement insert) throws SQLException { - if ( !insert.execute() ) { - while ( !insert.getMoreResults() && insert.getUpdateCount() != -1 ) { - // do nothing until we hit the rsult set containing the generated id - } - } - ResultSet rs = insert.getResultSet(); + public Serializable executeAndExtract(PreparedStatement insert, SessionImplementor session) throws SQLException { + ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().execute( insert ); try { - return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() ); + return IdentifierGeneratorHelper.getGeneratedIdentity( + rs, + persister.getRootTableKeyColumnNames()[0], + persister.getIdentifierType() + ); } finally { - rs.close(); + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, insert ); } } @@ -184,7 +189,7 @@ SessionImplementor session, ResultSet rs, Object object) throws SQLException { - return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() ); + return IdentifierGeneratorHelper.getGeneratedIdentity( rs, persister.getRootTableKeyColumnNames()[0], persister.getIdentifierType() ); } } Index: 3rdParty_sources/hibernate-core/org/hibernate/id/IncrementGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/IncrementGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/IncrementGenerator.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/IncrementGenerator.java 30 Jul 2014 16:16:18 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id; @@ -30,17 +29,18 @@ import java.sql.SQLException; import java.util.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.HibernateException; import org.hibernate.MappingException; +import org.hibernate.cfg.ObjectNameNormalizer; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.exception.JDBCExceptionHelper; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.StringHelper; import org.hibernate.mapping.Table; import org.hibernate.type.Type; -import org.hibernate.util.StringHelper; +import org.jboss.logging.Logger; + /** * increment
    *
    @@ -52,89 +52,106 @@ * (The tables parameter specified a comma-separated list of table names.) * * @author Gavin King + * @author Steve Ebersole + * @author Brett Meyer */ public class IncrementGenerator implements IdentifierGenerator, Configurable { - private static final Logger log = LoggerFactory.getLogger(IncrementGenerator.class); + private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, IncrementGenerator.class.getName()); - private long next; - private String sql; private Class returnClass; + private String sql; - public synchronized Serializable generate(SessionImplementor session, Object object) - throws HibernateException { + private IntegralDataTypeHolder previousValueHolder; - if (sql!=null) { - getNext( session ); + public synchronized Serializable generate(SessionImplementor session, Object object) throws HibernateException { + if ( sql != null ) { + initializePreviousValueHolder( session ); } - return IdentifierGeneratorFactory.createNumber(next++, returnClass); + return previousValueHolder.makeValueThenIncrement(); } - public void configure(Type type, Properties params, Dialect dialect) - throws MappingException { - - String tableList = params.getProperty("tables"); - if (tableList==null) tableList = params.getProperty(PersistentIdentifierGenerator.TABLES); - String[] tables = StringHelper.split(", ", tableList); - String column = params.getProperty("column"); - if (column==null) column = params.getProperty(PersistentIdentifierGenerator.PK); - String schema = params.getProperty(PersistentIdentifierGenerator.SCHEMA); - String catalog = params.getProperty(PersistentIdentifierGenerator.CATALOG); + public void configure(Type type, Properties params, Dialect dialect) throws MappingException { returnClass = type.getReturnedClass(); - - StringBuffer buf = new StringBuffer(); - for ( int i=0; i1) { - buf.append("select ").append(column).append(" from "); + ObjectNameNormalizer normalizer = + ( ObjectNameNormalizer ) params.get( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER ); + + String column = params.getProperty( "column" ); + if ( column == null ) { + column = params.getProperty( PersistentIdentifierGenerator.PK ); + } + column = dialect.quote( normalizer.normalizeIdentifierQuoting( column ) ); + + String tableList = params.getProperty( "tables" ); + if ( tableList == null ) { + tableList = params.getProperty( PersistentIdentifierGenerator.TABLES ); + } + String[] tables = StringHelper.split( ", ", tableList ); + + final String schema = dialect.quote( + normalizer.normalizeIdentifierQuoting( + params.getProperty( PersistentIdentifierGenerator.SCHEMA ) + ) + ); + final String catalog = dialect.quote( + normalizer.normalizeIdentifierQuoting( + params.getProperty( PersistentIdentifierGenerator.CATALOG ) + ) + ); + + StringBuilder buf = new StringBuilder(); + for ( int i=0; i < tables.length; i++ ) { + final String tableName = dialect.quote( normalizer.normalizeIdentifierQuoting( tables[i] ) ); + if ( tables.length > 1 ) { + buf.append( "select max(" ).append( column ).append( ") as mx from " ); } - buf.append( Table.qualify( catalog, schema, tables[i] ) ); - if ( i1) { - buf.insert(0, "( ").append(" ) ids_"); - column = "ids_." + column; + if ( tables.length > 1 ) { + buf.insert( 0, "( " ).append( " ) ids_" ); + column = "ids_.mx"; } - + sql = "select max(" + column + ") from " + buf.toString(); } - private void getNext( SessionImplementor session ) { + private void initializePreviousValueHolder(SessionImplementor session) { + previousValueHolder = IdentifierGeneratorHelper.getIntegralDataTypeHolder( returnClass ); - log.debug("fetching initial value: " + sql); - + final boolean debugEnabled = LOG.isDebugEnabled(); + if ( debugEnabled ) { + LOG.debugf( "Fetching initial value: %s", sql ); + } try { - PreparedStatement st = session.getBatcher().prepareSelectStatement(sql); + PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql ); try { - ResultSet rs = st.executeQuery(); + ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st ); try { - if ( rs.next() ) { - next = rs.getLong(1) + 1; - if ( rs.wasNull() ) next = 1; + if (rs.next()) previousValueHolder.initialize(rs, 0L).increment(); + else previousValueHolder.initialize(1L); + sql = null; + if ( debugEnabled ) { + LOG.debugf( "First free id: %s", previousValueHolder.makeValue() ); } - else { - next = 1; - } - sql=null; - log.debug("first free id: " + next); } finally { - rs.close(); + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st ); } } finally { - session.getBatcher().closeStatement(st); + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } - } catch (SQLException sqle) { - throw JDBCExceptionHelper.convert( - session.getFactory().getSQLExceptionConverter(), + throw session.getFactory().getSQLExceptionHelper().convert( sqle, "could not fetch initial value for increment generator", sql - ); + ); } } - } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/IntegralDataTypeHolder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/id/MultipleHiLoPerTableGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/MultipleHiLoPerTableGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/MultipleHiLoPerTableGenerator.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/MultipleHiLoPerTableGenerator.java 30 Jul 2014 16:16:18 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id; @@ -32,19 +31,27 @@ import java.sql.Types; import java.util.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.HibernateException; import org.hibernate.LockMode; import org.hibernate.MappingException; -import org.hibernate.jdbc.util.FormatStyle; +import org.hibernate.cfg.ObjectNameNormalizer; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.engine.TransactionHelper; +import org.hibernate.engine.jdbc.internal.FormatStyle; +import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.engine.jdbc.spi.SqlStatementLogger; +import org.hibernate.engine.spi.SessionEventListenerManager; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.id.enhanced.AccessCallback; +import org.hibernate.id.enhanced.LegacyHiLoAlgorithmOptimizer; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.jdbc.AbstractReturningWork; +import org.hibernate.jdbc.WorkExecutorVisitable; import org.hibernate.mapping.Table; import org.hibernate.type.Type; -import org.hibernate.util.PropertiesHelper; +import org.jboss.logging.Logger; + /** * * A hilo IdentifierGenerator that returns a Long, constructed using @@ -62,7 +69,7 @@ *

    *

    This implementation is not compliant with a user connection

    *

    - * + * *

    Allowed parameters (all of them are optional):

    *
      *
    • table: table name (default hibernate_sequences)
    • @@ -76,12 +83,11 @@ * @author Emmanuel Bernard * @author Klaus Richarz. */ -public class MultipleHiLoPerTableGenerator - extends TransactionHelper - implements PersistentIdentifierGenerator, Configurable { - - private static final Logger log = LoggerFactory.getLogger(MultipleHiLoPerTableGenerator.class); - +public class MultipleHiLoPerTableGenerator implements PersistentIdentifierGenerator, Configurable { + + private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, + MultipleHiLoPerTableGenerator.class.getName()); + public static final String ID_TABLE = "table"; public static final String PK_COLUMN_NAME = "primary_key_column"; public static final String PK_VALUE_NAME = "primary_key_value"; @@ -92,7 +98,7 @@ public static final String DEFAULT_TABLE = "hibernate_sequences"; private static final String DEFAULT_PK_COLUMN = "sequence_name"; private static final String DEFAULT_VALUE_COLUMN = "sequence_next_hi_value"; - + private String tableName; private String pkColumnName; private String valueColumnName; @@ -103,16 +109,16 @@ //hilo params public static final String MAX_LO = "max_lo"; - private long hi; - private int lo; private int maxLo; + private LegacyHiLoAlgorithmOptimizer hiloOptimizer; + private Class returnClass; private int keySize; public String[] sqlCreateStrings(Dialect dialect) throws HibernateException { return new String[] { - new StringBuffer( dialect.getCreateTableString() ) + new StringBuilder( dialect.getCreateTableString() ) .append( ' ' ) .append( tableName ) .append( " ( " ) @@ -123,120 +129,181 @@ .append( valueColumnName ) .append( ' ' ) .append( dialect.getTypeName( Types.INTEGER ) ) - .append( " ) " ) + .append( " )" ) + .append( dialect.getTableTypeString() ) .toString() }; } public String[] sqlDropStrings(Dialect dialect) throws HibernateException { - StringBuffer sqlDropString = new StringBuffer( "drop table " ); - if ( dialect.supportsIfExistsBeforeTableName() ) { - sqlDropString.append( "if exists " ); - } - sqlDropString.append( tableName ).append( dialect.getCascadeConstraintsString() ); - if ( dialect.supportsIfExistsAfterTableName() ) { - sqlDropString.append( " if exists" ); - } - return new String[] { sqlDropString.toString() }; + return new String[] { dialect.getDropTableString( tableName ) }; } public Object generatorKey() { return tableName; } - public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException { - int result; - int rows; - do { - // The loop ensures atomicity of the - // select + update even for no transaction - // or read committed isolation level + public synchronized Serializable generate(final SessionImplementor session, Object obj) { + final SqlStatementLogger statementLogger = session.getFactory().getServiceRegistry() + .getService( JdbcServices.class ) + .getSqlStatementLogger(); + final SessionEventListenerManager statsCollector = session.getEventListenerManager(); - //sql = query; - SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC ); - PreparedStatement qps = conn.prepareStatement(query); - PreparedStatement ips = null; - try { - //qps.setString(1, key); - ResultSet rs = qps.executeQuery(); - boolean isInitialized = rs.next(); - if ( !isInitialized ) { - result = 0; - ips = conn.prepareStatement(insert); - //ips.setString(1, key); - ips.setInt(1, result); - ips.execute(); - } - else { - result = rs.getInt(1); - } - rs.close(); + final WorkExecutorVisitable work = new AbstractReturningWork() { + @Override + public IntegralDataTypeHolder execute(Connection connection) throws SQLException { + IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( returnClass ); + + int rows; + do { + final PreparedStatement queryPreparedStatement = prepareStatement( connection, query, statementLogger, statsCollector ); + try { + final ResultSet rs = executeQuery( queryPreparedStatement, statsCollector ); + boolean isInitialized = rs.next(); + if ( !isInitialized ) { + value.initialize( 0 ); + final PreparedStatement insertPreparedStatement = prepareStatement( connection, insert, statementLogger, statsCollector ); + try { + value.bind( insertPreparedStatement, 1 ); + executeUpdate( insertPreparedStatement, statsCollector ); + } + finally { + insertPreparedStatement.close(); + } + } + else { + value.initialize( rs, 0 ); + } + rs.close(); + } + catch (SQLException sqle) { + LOG.unableToReadOrInitHiValue( sqle ); + throw sqle; + } + finally { + queryPreparedStatement.close(); + } + + + final PreparedStatement updatePreparedStatement = prepareStatement( connection, update, statementLogger, statsCollector ); + try { + value.copy().increment().bind( updatePreparedStatement, 1 ); + value.bind( updatePreparedStatement, 2 ); + + rows = executeUpdate( updatePreparedStatement, statsCollector ); + } + catch (SQLException sqle) { + LOG.error( LOG.unableToUpdateHiValue( tableName ), sqle ); + throw sqle; + } + finally { + updatePreparedStatement.close(); + } + } while ( rows==0 ); + + return value; } - catch (SQLException sqle) { - log.error("could not read or init a hi value", sqle); - throw sqle; + }; + + // maxLo < 1 indicates a hilo generator with no hilo :? + if ( maxLo < 1 ) { + //keep the behavior consistent even for boundary usages + IntegralDataTypeHolder value = null; + while ( value == null || value.lt( 1 ) ) { + value = session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork( work, true ); } - finally { - if (ips != null) { - ips.close(); + return value.makeValue(); + } + + return hiloOptimizer.generate( + new AccessCallback() { + public IntegralDataTypeHolder getNextValue() { + return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork( + work, + true + ); + } + + @Override + public String getTenantIdentifier() { + return session.getTenantIdentifier(); + } } - qps.close(); - } + ); + } - //sql = update; - PreparedStatement ups = conn.prepareStatement(update); - try { - ups.setInt( 1, result + 1 ); - ups.setInt( 2, result ); - //ups.setString( 3, key ); - rows = ups.executeUpdate(); - } - catch (SQLException sqle) { - log.error("could not update hi value in: " + tableName, sqle); - throw sqle; - } - finally { - ups.close(); - } + private PreparedStatement prepareStatement( + Connection connection, + String sql, + SqlStatementLogger statementLogger, + SessionEventListenerManager statsCollector) throws SQLException { + statementLogger.logStatement( sql, FormatStyle.BASIC.getFormatter() ); + try { + statsCollector.jdbcPrepareStatementStart(); + return connection.prepareStatement( sql ); } - while (rows==0); - return new Integer(result); + finally { + statsCollector.jdbcPrepareStatementEnd(); + } } - public synchronized Serializable generate(SessionImplementor session, Object obj) - throws HibernateException { - if (maxLo < 1) { - //keep the behavior consistent even for boundary usages - int val = ( (Integer) doWorkInNewTransaction(session) ).intValue(); - if (val == 0) val = ( (Integer) doWorkInNewTransaction(session) ).intValue(); - return IdentifierGeneratorFactory.createNumber( val, returnClass ); + private int executeUpdate(PreparedStatement ps, SessionEventListenerManager statsCollector) throws SQLException { + try { + statsCollector.jdbcExecuteStatementStart(); + return ps.executeUpdate(); } - if (lo>maxLo) { - int hival = ( (Integer) doWorkInNewTransaction(session) ).intValue(); - lo = (hival == 0) ? 1 : 0; - hi = hival * (maxLo+1); - log.debug("new hi value: " + hival); + finally { + statsCollector.jdbcExecuteStatementEnd(); } - return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass ); + } + private ResultSet executeQuery(PreparedStatement ps, SessionEventListenerManager statsCollector) throws SQLException { + try { + statsCollector.jdbcExecuteStatementStart(); + return ps.executeQuery(); + } + finally { + statsCollector.jdbcExecuteStatementEnd(); + } + } + public void configure(Type type, Properties params, Dialect dialect) throws MappingException { - tableName = PropertiesHelper.getString(ID_TABLE, params, DEFAULT_TABLE); - pkColumnName = PropertiesHelper.getString(PK_COLUMN_NAME, params, DEFAULT_PK_COLUMN); - valueColumnName = PropertiesHelper.getString(VALUE_COLUMN_NAME, params, DEFAULT_VALUE_COLUMN); - String schemaName = params.getProperty(SCHEMA); - String catalogName = params.getProperty(CATALOG); - keySize = PropertiesHelper.getInt(PK_LENGTH_NAME, params, DEFAULT_PK_LENGTH); - String keyValue = PropertiesHelper.getString(PK_VALUE_NAME, params, params.getProperty(TABLE) ); + ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER ); - if ( tableName.indexOf( '.' )<0 ) { + tableName = normalizer.normalizeIdentifierQuoting( ConfigurationHelper.getString( ID_TABLE, params, DEFAULT_TABLE ) ); + if ( tableName.indexOf( '.' ) < 0 ) { + tableName = dialect.quote( tableName ); + final String schemaName = dialect.quote( + normalizer.normalizeIdentifierQuoting( params.getProperty( SCHEMA ) ) + ); + final String catalogName = dialect.quote( + normalizer.normalizeIdentifierQuoting( params.getProperty( CATALOG ) ) + ); tableName = Table.qualify( catalogName, schemaName, tableName ); } + else { + // if already qualified there is not much we can do in a portable manner so we pass it + // through and assume the user has set up the name correctly. + } + pkColumnName = dialect.quote( + normalizer.normalizeIdentifierQuoting( + ConfigurationHelper.getString( PK_COLUMN_NAME, params, DEFAULT_PK_COLUMN ) + ) + ); + valueColumnName = dialect.quote( + normalizer.normalizeIdentifierQuoting( + ConfigurationHelper.getString( VALUE_COLUMN_NAME, params, DEFAULT_VALUE_COLUMN ) + ) + ); + keySize = ConfigurationHelper.getInt(PK_LENGTH_NAME, params, DEFAULT_PK_LENGTH); + String keyValue = ConfigurationHelper.getString(PK_VALUE_NAME, params, params.getProperty(TABLE) ); + query = "select " + valueColumnName + " from " + - dialect.appendLockHint(LockMode.UPGRADE, tableName) + + dialect.appendLockHint( LockMode.PESSIMISTIC_WRITE, tableName ) + " where " + pkColumnName + " = '" + keyValue + "'" + dialect.getForUpdateString(); @@ -248,18 +315,21 @@ valueColumnName + " = ? and " + pkColumnName + - " = '" + - keyValue + " = '" + + keyValue + "'"; - + insert = "insert into " + tableName + "(" + pkColumnName + ", " + valueColumnName + ") " + "values('"+ keyValue +"', ?)"; //hilo config - maxLo = PropertiesHelper.getInt(MAX_LO, params, Short.MAX_VALUE); - lo = maxLo + 1; // so we "clock over" on the first invocation + maxLo = ConfigurationHelper.getInt(MAX_LO, params, Short.MAX_VALUE); returnClass = type.getReturnedClass(); + + if ( maxLo >= 1 ) { + hiloOptimizer = new LegacyHiLoAlgorithmOptimizer( returnClass, maxLo ); + } } } Index: 3rdParty_sources/hibernate-core/org/hibernate/id/PersistentIdentifierGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/PersistentIdentifierGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/PersistentIdentifierGenerator.java 17 Aug 2012 14:33:50 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/PersistentIdentifierGenerator.java 30 Jul 2014 16:16:18 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,13 +20,10 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id; - import org.hibernate.HibernateException; import org.hibernate.dialect.Dialect; -import org.hibernate.jdbc.util.SQLStatementLogger; /** * An IdentifierGenerator that requires creation of database objects. @@ -67,8 +64,13 @@ * The configuration parameter holding the catalog name */ public static final String CATALOG = "catalog"; - + /** + * The key under whcih to find the {@link org.hibernate.cfg.ObjectNameNormalizer} in the config param map. + */ + public static final String IDENTIFIER_NORMALIZER = "identifier_normalizer"; + + /** * The SQL required to create the underlying database objects. * * @param dialect The dialect against which to generate the create command(s) @@ -93,13 +95,4 @@ * @return Object an identifying key for this generator */ public Object generatorKey(); - - static final SQLStatementLogger SQL_STATEMENT_LOGGER = new SQLStatementLogger( false, false ); - } - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/id/PostInsertIdentifierGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/PostInsertIdentifierGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/PostInsertIdentifierGenerator.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/PostInsertIdentifierGenerator.java 30 Jul 2014 16:16:19 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id; Index: 3rdParty_sources/hibernate-core/org/hibernate/id/PostInsertIdentityPersister.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/PostInsertIdentityPersister.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/PostInsertIdentityPersister.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/PostInsertIdentityPersister.java 30 Jul 2014 16:16:18 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.id; - import org.hibernate.persister.entity.EntityPersister; /** @@ -51,6 +50,8 @@ */ public String getIdentitySelectString(); + public String[] getIdentifierColumnNames(); + /** * The names of the primary key columns in the root table. * Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/ResultSetIdentifierConsumer.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/id/SelectGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/SelectGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/SelectGenerator.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/SelectGenerator.java 30 Jul 2014 16:16:19 -0000 1.1.2.1 @@ -30,14 +30,13 @@ import java.sql.SQLException; import java.util.Properties; -import org.hibernate.MappingException; import org.hibernate.HibernateException; -import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate; -import org.hibernate.id.insert.IdentifierGeneratingInsert; -import org.hibernate.id.insert.AbstractSelectingDelegate; +import org.hibernate.MappingException; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.engine.ValueInclusion; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.id.insert.AbstractSelectingDelegate; +import org.hibernate.id.insert.IdentifierGeneratingInsert; +import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate; import org.hibernate.type.Type; /** @@ -81,8 +80,7 @@ "natural-id properties; need to specify [key] in generator parameters" ); } - ValueInclusion inclusion = persister.getPropertyInsertGenerationInclusions() [ naturalIdPropertyIndices[0] ]; - if ( inclusion != ValueInclusion.NONE ) { + if ( persister.getEntityMetamodel().isNaturalIdentifierInsertGenerated() ) { throw new IdentifierGenerationException( "natural-id also defined as insert-generated; need to specify [key] " + "in generator parameters" @@ -136,7 +134,7 @@ SessionImplementor session, PreparedStatement ps, Object entity) throws SQLException { - Object uniqueKeyValue = persister.getPropertyValue( entity, uniqueKeyPropertyName, session.getEntityMode() ); + Object uniqueKeyValue = persister.getPropertyValue( entity, uniqueKeyPropertyName ); uniqueKeyType.nullSafeSet( ps, uniqueKeyValue, 1, session ); } Index: 3rdParty_sources/hibernate-core/org/hibernate/id/SequenceGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/SequenceGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/SequenceGenerator.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/SequenceGenerator.java 30 Jul 2014 16:16:18 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id; @@ -30,17 +29,17 @@ import java.sql.SQLException; import java.util.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.exception.JDBCExceptionHelper; +import org.hibernate.cfg.ObjectNameNormalizer; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.mapping.Table; import org.hibernate.type.Type; -import org.hibernate.util.PropertiesHelper; +import org.jboss.logging.Logger; + /** * sequence
      *
      @@ -50,11 +49,12 @@ * Mapping parameters supported: sequence, parameters. * * @see SequenceHiLoGenerator - * @see TableHiLoGenerator * @author Gavin King */ +public class SequenceGenerator + implements PersistentIdentifierGenerator, BulkInsertionCapableIdentifierGenerator, Configurable { -public class SequenceGenerator implements PersistentIdentifierGenerator, Configurable { + private static final Logger LOG = Logger.getLogger( SequenceGenerator.class.getName() ); /** * The sequence parameter @@ -72,78 +72,105 @@ private Type identifierType; private String sql; - private static final Logger log = LoggerFactory.getLogger(SequenceGenerator.class); + protected Type getIdentifierType() { + return identifierType; + } + public Object generatorKey() { + return getSequenceName(); + } + + public String getSequenceName() { + return sequenceName; + } + + @Override public void configure(Type type, Properties params, Dialect dialect) throws MappingException { - sequenceName = PropertiesHelper.getString(SEQUENCE, params, "hibernate_sequence"); - parameters = params.getProperty(PARAMETERS); - String schemaName = params.getProperty(SCHEMA); - String catalogName = params.getProperty(CATALOG); + ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER ); + sequenceName = normalizer.normalizeIdentifierQuoting( + ConfigurationHelper.getString( SEQUENCE, params, "hibernate_sequence" ) + ); + parameters = params.getProperty( PARAMETERS ); - if (sequenceName.indexOf( '.' ) < 0) { - sequenceName = Table.qualify( catalogName, schemaName, sequenceName ); + if ( sequenceName.indexOf( '.' ) < 0 ) { + final String schemaName = normalizer.normalizeIdentifierQuoting( params.getProperty( SCHEMA ) ); + final String catalogName = normalizer.normalizeIdentifierQuoting( params.getProperty( CATALOG ) ); + sequenceName = Table.qualify( + dialect.quote( catalogName ), + dialect.quote( schemaName ), + dialect.quote( sequenceName ) + ); } + else { + // if already qualified there is not much we can do in a portable manner so we pass it + // through and assume the user has set up the name correctly. + } this.identifierType = type; - sql = dialect.getSequenceNextValString(sequenceName); + sql = dialect.getSequenceNextValString( sequenceName ); } - public Serializable generate(SessionImplementor session, Object obj) - throws HibernateException { - - try { + @Override + public Serializable generate(SessionImplementor session, Object obj) { + return generateHolder( session ).makeValue(); + } - PreparedStatement st = session.getBatcher().prepareSelectStatement(sql); + protected IntegralDataTypeHolder generateHolder(SessionImplementor session) { + try { + PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql ); try { - ResultSet rs = st.executeQuery(); + ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st ); try { rs.next(); - Serializable result = IdentifierGeneratorFactory.get( - rs, identifierType - ); - if ( log.isDebugEnabled() ) { - log.debug("Sequence identifier generated: " + result); - } + IntegralDataTypeHolder result = buildHolder(); + result.initialize( rs, 1 ); + LOG.debugf( "Sequence identifier generated: %s", result ); return result; } finally { - rs.close(); + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st ); } } finally { - session.getBatcher().closeStatement(st); + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } - + } catch (SQLException sqle) { - throw JDBCExceptionHelper.convert( - session.getFactory().getSQLExceptionConverter(), + throw session.getFactory().getSQLExceptionHelper().convert( sqle, "could not get next sequence value", sql - ); + ); } + } + protected IntegralDataTypeHolder buildHolder() { + return IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() ); } + @Override + @SuppressWarnings( {"deprecation"}) public String[] sqlCreateStrings(Dialect dialect) throws HibernateException { - String[] ddl = dialect.getCreateSequenceStrings(sequenceName); + String[] ddl = dialect.getCreateSequenceStrings( sequenceName ); if ( parameters != null ) { ddl[ddl.length - 1] += ' ' + parameters; } return ddl; } + @Override public String[] sqlDropStrings(Dialect dialect) throws HibernateException { return dialect.getDropSequenceStrings(sequenceName); } - public Object generatorKey() { - return sequenceName; + @Override + public boolean supportsBulkInsertionIdentifierGeneration() { + return true; } - public String getSequenceName() { - return sequenceName; + @Override + public String determineBulkInsertionIdentifierGenerationSelectFragment(Dialect dialect) { + return dialect.getSelectSequenceNextValString( getSequenceName() ); } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/id/SequenceHiLoGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/SequenceHiLoGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/SequenceHiLoGenerator.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/SequenceHiLoGenerator.java 30 Jul 2014 16:16:17 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,21 +20,18 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id; - import java.io.Serializable; import java.util.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.id.enhanced.AccessCallback; +import org.hibernate.id.enhanced.LegacyHiLoAlgorithmOptimizer; +import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.type.Type; -import org.hibernate.util.PropertiesHelper; /** * seqhilo
      @@ -43,49 +40,61 @@ * oracle-style sequence that generates hi values. The user may specify a * maximum lo value to determine how often new hi values are fetched.
      *
      - * If sequences are not available, TableHiLoGenerator might be an - * alternative.
      - *
      * Mapping parameters supported: sequence, max_lo, parameters. * - * @see TableHiLoGenerator * @author Gavin King */ public class SequenceHiLoGenerator extends SequenceGenerator { - public static final String MAX_LO = "max_lo"; - private static final Logger log = LoggerFactory.getLogger(SequenceHiLoGenerator.class); - private int maxLo; - private int lo; - private long hi; - private Class returnClass; + private LegacyHiLoAlgorithmOptimizer hiloOptimizer; + public void configure(Type type, Properties params, Dialect d) throws MappingException { super.configure(type, params, d); - maxLo = PropertiesHelper.getInt(MAX_LO, params, 9); - lo = maxLo + 1; // so we "clock over" on the first invocation - returnClass = type.getReturnedClass(); + + maxLo = ConfigurationHelper.getInt( MAX_LO, params, 9 ); + + if ( maxLo >= 1 ) { + hiloOptimizer = new LegacyHiLoAlgorithmOptimizer( + getIdentifierType().getReturnedClass(), + maxLo + ); + } } - public synchronized Serializable generate(SessionImplementor session, Object obj) - throws HibernateException { - if (maxLo < 1) { + public synchronized Serializable generate(final SessionImplementor session, Object obj) { + // maxLo < 1 indicates a hilo generator with no hilo :? + if ( maxLo < 1 ) { //keep the behavior consistent even for boundary usages - long val = ( (Number) super.generate(session, obj) ).longValue(); - if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue(); - return IdentifierGeneratorFactory.createNumber( val, returnClass ); + IntegralDataTypeHolder value = null; + while ( value == null || value.lt( 0 ) ) { + value = super.generateHolder( session ); + } + return value.makeValue(); } - if ( lo>maxLo ) { - long hival = ( (Number) super.generate(session, obj) ).longValue(); - lo = (hival == 0) ? 1 : 0; - hi = hival * ( maxLo+1 ); - if ( log.isDebugEnabled() ) - log.debug("new hi value: " + hival); - } - return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass ); + return hiloOptimizer.generate( + new AccessCallback() { + public IntegralDataTypeHolder getNextValue() { + return generateHolder( session ); + } + + @Override + public String getTenantIdentifier() { + return session.getTenantIdentifier(); + } + } + ); } + /** + * For testing/assertion purposes + * + * @return The optimizer + */ + LegacyHiLoAlgorithmOptimizer getHiloOptimizer() { + return hiloOptimizer; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/id/SequenceIdentityGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/SequenceIdentityGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/SequenceIdentityGenerator.java 17 Aug 2012 14:33:50 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/SequenceIdentityGenerator.java 30 Jul 2014 16:16:18 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,26 +20,26 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id; -import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate; -import org.hibernate.id.insert.AbstractReturningDelegate; -import org.hibernate.id.insert.IdentifierGeneratingInsert; -import org.hibernate.dialect.Dialect; +import java.io.Serializable; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Properties; + import org.hibernate.HibernateException; import org.hibernate.MappingException; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.id.insert.AbstractReturningDelegate; +import org.hibernate.id.insert.IdentifierGeneratingInsert; +import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate; +import org.hibernate.internal.CoreMessageLogger; import org.hibernate.sql.Insert; import org.hibernate.type.Type; -import org.hibernate.engine.SessionImplementor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.Properties; +import org.jboss.logging.Logger; /** * A generator which combines sequence generation with immediate retrieval @@ -54,13 +54,18 @@ * * @author Steve Ebersole */ -public class SequenceIdentityGenerator extends SequenceGenerator +public class SequenceIdentityGenerator + extends SequenceGenerator implements PostInsertIdentifierGenerator { - private static final Logger log = LoggerFactory.getLogger( SequenceIdentityGenerator.class ); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + SequenceIdentityGenerator.class.getName() + ); - public Serializable generate(SessionImplementor s, Object obj) { - return IdentifierGeneratorFactory.POST_INSERT_INDICATOR; + @Override + public Serializable generate(SessionImplementor s, Object obj) { + return IdentifierGeneratorHelper.POST_INSERT_INDICATOR; } public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate( @@ -70,7 +75,8 @@ return new Delegate( persister, dialect, getSequenceName() ); } - public void configure(Type type, Properties params, Dialect dialect) throws MappingException { + @Override + public void configure(Type type, Properties params, Dialect dialect) throws MappingException { super.configure( type, params, dialect ); } @@ -95,15 +101,18 @@ return insert; } - protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException { - return session.getBatcher().prepareStatement( insertSQL, keyColumns ); + @Override + protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException { + return session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( insertSQL, keyColumns ); } - protected Serializable executeAndExtract(PreparedStatement insert) throws SQLException { - insert.executeUpdate(); - return IdentifierGeneratorFactory.getGeneratedIdentity( + @Override + protected Serializable executeAndExtract(PreparedStatement insert, SessionImplementor session) throws SQLException { + session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( insert ); + return IdentifierGeneratorHelper.getGeneratedIdentity( insert.getGeneratedKeys(), - getPersister().getIdentifierType() + getPersister().getRootTableKeyColumnNames()[0], + getPersister().getIdentifierType() ); } } @@ -113,10 +122,11 @@ super( dialect ); } - public Insert setComment(String comment) { + @Override + public Insert setComment(String comment) { // don't allow comments on these insert statements as comments totally // blow up the Oracle getGeneratedKeys "support" :( - log.info( "disallowing insert statement comment for select-identity due to Oracle driver bug" ); + LOG.disallowingInsertStatementComment(); return this; } } Index: 3rdParty_sources/hibernate-core/org/hibernate/id/TableGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/TableGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/TableGenerator.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/TableGenerator.java 30 Jul 2014 16:16:19 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id; @@ -32,163 +31,229 @@ import java.sql.Types; import java.util.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.HibernateException; import org.hibernate.LockMode; -import org.hibernate.jdbc.util.FormatStyle; +import org.hibernate.cfg.ObjectNameNormalizer; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.engine.TransactionHelper; +import org.hibernate.engine.jdbc.internal.FormatStyle; +import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.engine.jdbc.spi.SqlStatementLogger; +import org.hibernate.engine.spi.SessionEventListenerManager; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.id.enhanced.SequenceStyleGenerator; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.jdbc.AbstractReturningWork; import org.hibernate.mapping.Table; import org.hibernate.type.Type; -import org.hibernate.util.PropertiesHelper; +import org.jboss.logging.Logger; + /** * An IdentifierGenerator that uses a database * table to store the last generated value. It is not * intended that applications use this strategy directly. * However, it may be used to build other (efficient) - * strategies. The returned type is Integer.
      - *
      - * The hi value MUST be fetched in a seperate transaction - * to the Session transaction so the generator must - * be able to obtain a new connection and commit it. Hence - * this implementation may not be used when Hibernate is - * fetching connections when the user is supplying - * connections.
      - *
      - * The returned value is of type integer.
      - *
      + * strategies. The returned type is any supported by + * {@link IntegralDataTypeHolder} + *

      + * The value MUST be fetched in a separate transaction + * from that of the main {@link SessionImplementor session} + * transaction so the generator must be able to obtain a new + * connection and commit it. Hence this implementation may only + * be used when Hibernate is fetching connections, not when the + * user is supplying connections. + *

      + * Again, the return types supported here are any of the ones + * supported by {@link IntegralDataTypeHolder}. This is new + * as of 3.5. Prior to that this generator only returned {@link Integer} + * values. + *

      * Mapping parameters supported: table, column * * @see TableHiLoGenerator * @author Gavin King + * + * @deprecated use {@link SequenceStyleGenerator} instead. */ -public class TableGenerator extends TransactionHelper - implements PersistentIdentifierGenerator, Configurable { +@Deprecated +public class TableGenerator implements PersistentIdentifierGenerator, Configurable { /* COLUMN and TABLE should be renamed but it would break the public API */ /** The column parameter */ public static final String COLUMN = "column"; - + /** Default column name */ public static final String DEFAULT_COLUMN_NAME = "next_hi"; - + /** The table parameter */ public static final String TABLE = "table"; - - /** Default table name */ + + /** Default table name */ public static final String DEFAULT_TABLE_NAME = "hibernate_unique_key"; - private static final Logger log = LoggerFactory.getLogger(TableGenerator.class); + private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, TableGenerator.class.getName()); + private Type identifierType; private String tableName; private String columnName; private String query; private String update; public void configure(Type type, Properties params, Dialect dialect) { + identifierType = type; - tableName = PropertiesHelper.getString(TABLE, params, DEFAULT_TABLE_NAME); - columnName = PropertiesHelper.getString(COLUMN, params, DEFAULT_COLUMN_NAME); - String schemaName = params.getProperty(SCHEMA); - String catalogName = params.getProperty(CATALOG); + ObjectNameNormalizer normalizer = ( ObjectNameNormalizer ) params.get( IDENTIFIER_NORMALIZER ); - if ( tableName.indexOf( '.' )<0 ) { - tableName = Table.qualify( catalogName, schemaName, tableName ); + tableName = ConfigurationHelper.getString( TABLE, params, DEFAULT_TABLE_NAME ); + if ( tableName.indexOf( '.' ) < 0 ) { + final String schemaName = normalizer.normalizeIdentifierQuoting( params.getProperty( SCHEMA ) ); + final String catalogName = normalizer.normalizeIdentifierQuoting( params.getProperty( CATALOG ) ); + tableName = Table.qualify( + dialect.quote( catalogName ), + dialect.quote( schemaName ), + dialect.quote( tableName ) + ); } + else { + // if already qualified there is not much we can do in a portable manner so we pass it + // through and assume the user has set up the name correctly. + } - query = "select " + - columnName + - " from " + - dialect.appendLockHint(LockMode.UPGRADE, tableName) + + columnName = dialect.quote( + normalizer.normalizeIdentifierQuoting( + ConfigurationHelper.getString( COLUMN, params, DEFAULT_COLUMN_NAME ) + ) + ); + + query = "select " + + columnName + + " from " + + dialect.appendLockHint(LockMode.PESSIMISTIC_WRITE, tableName) + dialect.getForUpdateString(); - update = "update " + - tableName + - " set " + - columnName + - " = ? where " + - columnName + + update = "update " + + tableName + + " set " + + columnName + + " = ? where " + + columnName + " = ?"; } - public synchronized Serializable generate(SessionImplementor session, Object object) - throws HibernateException { - int result = ( (Integer) doWorkInNewTransaction(session) ).intValue(); - return new Integer(result); + public synchronized Serializable generate(SessionImplementor session, Object object) { + return generateHolder( session ).makeValue(); } + protected IntegralDataTypeHolder generateHolder(final SessionImplementor session) { + final SqlStatementLogger statementLogger = session.getFactory().getServiceRegistry() + .getService( JdbcServices.class ) + .getSqlStatementLogger(); + final SessionEventListenerManager listeners = session.getEventListenerManager(); + return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork( + new AbstractReturningWork() { + @Override + public IntegralDataTypeHolder execute(Connection connection) throws SQLException { + IntegralDataTypeHolder value = buildHolder(); + int rows; + + // The loop ensures atomicity of the select + update even for no transaction or + // read committed isolation level + do { + final PreparedStatement qps = prepareStatement( connection, query, statementLogger, listeners ); + try { + ResultSet rs = executeQuery( qps, listeners ); + if ( !rs.next() ) { + String err = "could not read a hi value - you need to populate the table: " + tableName; + LOG.error(err); + throw new IdentifierGenerationException(err); + } + value.initialize( rs, 1 ); + rs.close(); + } + catch (SQLException e) { + LOG.error("Could not read a hi value", e); + throw e; + } + finally { + qps.close(); + } + + final PreparedStatement ups = prepareStatement( connection, update, statementLogger, listeners ); + try { + value.copy().increment().bind( ups, 1 ); + value.bind( ups, 2 ); + rows = executeUpdate( ups, listeners ); + } + catch (SQLException sqle) { + LOG.error(LOG.unableToUpdateHiValue(tableName), sqle); + throw sqle; + } + finally { + ups.close(); + } + } + while (rows==0); + return value; + } + }, + true + ); + } + + private PreparedStatement prepareStatement( + Connection connection, + String sql, + SqlStatementLogger statementLogger, + SessionEventListenerManager statsCollector) throws SQLException { + statementLogger.logStatement( sql, FormatStyle.BASIC.getFormatter() ); + try { + statsCollector.jdbcPrepareStatementStart(); + return connection.prepareStatement( sql ); + } + finally { + statsCollector.jdbcPrepareStatementEnd(); + } + } + + private int executeUpdate(PreparedStatement ps, SessionEventListenerManager statsCollector) throws SQLException { + try { + statsCollector.jdbcExecuteStatementStart(); + return ps.executeUpdate(); + } + finally { + statsCollector.jdbcExecuteStatementEnd(); + } + + } + + private ResultSet executeQuery(PreparedStatement ps, SessionEventListenerManager statsCollector) throws SQLException { + try { + statsCollector.jdbcExecuteStatementStart(); + return ps.executeQuery(); + } + finally { + statsCollector.jdbcExecuteStatementEnd(); + } + } + public String[] sqlCreateStrings(Dialect dialect) throws HibernateException { return new String[] { - dialect.getCreateTableString() + " " + tableName + " ( " + columnName + " " + dialect.getTypeName(Types.INTEGER) + " )", + dialect.getCreateTableString() + " " + tableName + " ( " + + columnName + " " + dialect.getTypeName(Types.INTEGER) + " )" + dialect.getTableTypeString(), "insert into " + tableName + " values ( 0 )" }; } public String[] sqlDropStrings(Dialect dialect) { - StringBuffer sqlDropString = new StringBuffer( "drop table " ); - if ( dialect.supportsIfExistsBeforeTableName() ) { - sqlDropString.append( "if exists " ); - } - sqlDropString.append( tableName ).append( dialect.getCascadeConstraintsString() ); - if ( dialect.supportsIfExistsAfterTableName() ) { - sqlDropString.append( " if exists" ); - } - return new String[] { sqlDropString.toString() }; + return new String[] { dialect.getDropTableString( tableName ) }; } public Object generatorKey() { return tableName; } - public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException { - int result; - int rows; - do { - // The loop ensures atomicity of the - // select + update even for no transaction - // or read committed isolation level - - sql = query; - SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC ); - PreparedStatement qps = conn.prepareStatement(query); - try { - ResultSet rs = qps.executeQuery(); - if ( !rs.next() ) { - String err = "could not read a hi value - you need to populate the table: " + tableName; - log.error(err); - throw new IdentifierGenerationException(err); - } - result = rs.getInt(1); - rs.close(); - } - catch (SQLException sqle) { - log.error("could not read a hi value", sqle); - throw sqle; - } - finally { - qps.close(); - } - - sql = update; - SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC ); - PreparedStatement ups = conn.prepareStatement(update); - try { - ups.setInt( 1, result + 1 ); - ups.setInt( 2, result ); - rows = ups.executeUpdate(); - } - catch (SQLException sqle) { - log.error("could not update hi value in: " + tableName, sqle); - throw sqle; - } - finally { - ups.close(); - } - } - while (rows==0); - return new Integer(result); + protected IntegralDataTypeHolder buildHolder() { + return IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() ); } } Index: 3rdParty_sources/hibernate-core/org/hibernate/id/TableHiLoGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/TableHiLoGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/TableHiLoGenerator.java 17 Aug 2012 14:33:50 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/TableHiLoGenerator.java 30 Jul 2014 16:16:20 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,26 +20,24 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id; - import java.io.Serializable; import java.util.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.hibernate.HibernateException; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.id.enhanced.AccessCallback; +import org.hibernate.id.enhanced.LegacyHiLoAlgorithmOptimizer; +import org.hibernate.id.enhanced.SequenceStyleGenerator; +import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.type.Type; -import org.hibernate.util.PropertiesHelper; /** * hilo
      *
      * An IdentifierGenerator that returns a Long, constructed using - * a hi/lo algorithm. The hi value MUST be fetched in a seperate transaction + * a hi/lo algorithm. The hi value MUST be fetched in a separate transaction * to the Session transaction so the generator must be able to obtain * a new connection and commit it. Hence this implementation may not * be used when the user is supplying connections. In this @@ -50,45 +48,54 @@ * * @see SequenceHiLoGenerator * @author Gavin King + * + * @deprecated use {@link SequenceStyleGenerator} instead. */ +@Deprecated public class TableHiLoGenerator extends TableGenerator { - /** * The max_lo parameter */ public static final String MAX_LO = "max_lo"; - private long hi; - private int lo; + private LegacyHiLoAlgorithmOptimizer hiloOptimizer; + private int maxLo; - private Class returnClass; - private static final Logger log = LoggerFactory.getLogger(TableHiLoGenerator.class); - + @Override public void configure(Type type, Properties params, Dialect d) { - super.configure(type, params, d); - maxLo = PropertiesHelper.getInt(MAX_LO, params, Short.MAX_VALUE); - lo = maxLo + 1; // so we "clock over" on the first invocation - returnClass = type.getReturnedClass(); + super.configure( type, params, d ); + maxLo = ConfigurationHelper.getInt( MAX_LO, params, Short.MAX_VALUE ); + + if ( maxLo >= 1 ) { + hiloOptimizer = new LegacyHiLoAlgorithmOptimizer( type.getReturnedClass(), maxLo ); + } } - public synchronized Serializable generate(SessionImplementor session, Object obj) - throws HibernateException { - if (maxLo < 1) { + @Override + public synchronized Serializable generate(final SessionImplementor session, Object obj) { + // maxLo < 1 indicates a hilo generator with no hilo :? + if ( maxLo < 1 ) { //keep the behavior consistent even for boundary usages - long val = ( (Number) super.generate(session, obj) ).longValue(); - if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue(); - return IdentifierGeneratorFactory.createNumber( val, returnClass ); + IntegralDataTypeHolder value = null; + while ( value == null || value.lt( 0 ) ) { + value = generateHolder( session ); + } + return value.makeValue(); } - if (lo>maxLo) { - long hival = ( (Number) super.generate(session, obj) ).longValue(); - lo = (hival == 0) ? 1 : 0; - hi = hival * (maxLo+1); - log.debug("new hi value: " + hival); - } - return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass ); + return hiloOptimizer.generate( + new AccessCallback() { + public IntegralDataTypeHolder getNextValue() { + return generateHolder( session ); + } + @Override + public String getTenantIdentifier() { + return session.getTenantIdentifier(); + } + } + ); } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/UUIDGenerationStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/UUIDGenerator.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/id/UUIDHexGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/UUIDHexGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/UUIDHexGenerator.java 17 Aug 2012 14:33:51 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/UUIDHexGenerator.java 30 Jul 2014 16:16:18 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,19 +20,20 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id; import java.io.Serializable; import java.util.Properties; -import org.hibernate.Hibernate; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.type.Type; -import org.hibernate.util.PropertiesHelper; +import org.jboss.logging.Logger; + /** * uuid
      *
      @@ -45,54 +46,45 @@ * * @author Gavin King */ - public class UUIDHexGenerator extends AbstractUUIDGenerator implements Configurable { + private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, UUIDHexGenerator.class.getName()); + private static boolean WARNED; + private String sep = ""; - protected String format(int intval) { - String formatted = Integer.toHexString(intval); - StringBuffer buf = new StringBuffer("00000000"); - buf.replace( 8-formatted.length(), 8, formatted ); - return buf.toString(); + public UUIDHexGenerator() { + if ( !WARNED ) { + WARNED = true; + LOG.usingUuidHexGenerator( this.getClass().getName(), UUIDGenerator.class.getName() ); + } } - protected String format(short shortval) { - String formatted = Integer.toHexString(shortval); - StringBuffer buf = new StringBuffer("0000"); - buf.replace( 4-formatted.length(), 4, formatted ); - return buf.toString(); + @Override + public void configure(Type type, Properties params, Dialect d) { + sep = ConfigurationHelper.getString( "separator", params, "" ); } + @Override public Serializable generate(SessionImplementor session, Object obj) { - return new StringBuffer(36) - .append( format( getIP() ) ).append(sep) - .append( format( getJVM() ) ).append(sep) - .append( format( getHiTime() ) ).append(sep) - .append( format( getLoTime() ) ).append(sep) - .append( format( getCount() ) ) - .toString(); + return format( getIP() ) + sep + + format( getJVM() ) + sep + + format( getHiTime() ) + sep + + format( getLoTime() ) + sep + + format( getCount() ); } - public void configure(Type type, Properties params, Dialect d) { - sep = PropertiesHelper.getString("separator", params, ""); + protected String format(int intValue) { + String formatted = Integer.toHexString( intValue ); + StringBuilder buf = new StringBuilder( "00000000" ); + buf.replace( 8 - formatted.length(), 8, formatted ); + return buf.toString(); } - public static void main( String[] args ) throws Exception { - Properties props = new Properties(); - props.setProperty("separator", "/"); - IdentifierGenerator gen = new UUIDHexGenerator(); - ( (Configurable) gen ).configure(Hibernate.STRING, props, null); - IdentifierGenerator gen2 = new UUIDHexGenerator(); - ( (Configurable) gen2 ).configure(Hibernate.STRING, props, null); - - for ( int i=0; i<10; i++) { - String id = (String) gen.generate(null, null); - System.out.println(id); - String id2 = (String) gen2.generate(null, null); - System.out.println(id2); - } - + protected String format(short shortValue) { + String formatted = Integer.toHexString( shortValue ); + StringBuilder buf = new StringBuilder( "0000" ); + buf.replace( 4 - formatted.length(), 4, formatted ); + return buf.toString(); } - } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/AbstractOptimizer.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/AccessCallback.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/AccessCallback.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/AccessCallback.java 17 Aug 2012 14:33:56 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/AccessCallback.java 30 Jul 2014 16:16:38 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,10 +20,11 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id.enhanced; +import org.hibernate.id.IntegralDataTypeHolder; + /** * Contract for providing callback access to a {@link DatabaseStructure}, * typically from the {@link Optimizer}. @@ -36,5 +37,12 @@ * * @return The next value. */ - public long getNextValue(); + public IntegralDataTypeHolder getNextValue(); + + /** + * Obtain the tenant identifier (multi-tenancy), if one, associated with this callback. + * + * @return The tenant identifier + */ + public String getTenantIdentifier(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/DatabaseStructure.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/DatabaseStructure.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/DatabaseStructure.java 17 Aug 2012 14:33:56 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/DatabaseStructure.java 30 Jul 2014 16:16:38 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,12 +20,11 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id.enhanced; -import org.hibernate.engine.SessionImplementor; import org.hibernate.dialect.Dialect; +import org.hibernate.engine.spi.SessionImplementor; /** * Encapsulates definition of the underlying data structure backing a @@ -47,6 +46,12 @@ public int getTimesAccessed(); /** + * The configured initial value + * @return The configured initial value + */ + public int getInitialValue(); + + /** * The configured increment size * @return The configured increment size */ @@ -82,4 +87,11 @@ * @return The drop commands. */ public String[] sqlDropStrings(Dialect dialect); -} \ No newline at end of file + + /** + * Is the structure physically a sequence? + * + * @return {@code true} if the actual database structure is a sequence; {@code false} otherwise. + */ + public boolean isPhysicalSequence(); +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/HiLoOptimizer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/InitialValueAwareOptimizer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/LegacyHiLoAlgorithmOptimizer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/NoopOptimizer.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/Optimizer.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/Optimizer.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/Optimizer.java 17 Aug 2012 14:33:56 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/Optimizer.java 30 Jul 2014 16:16:38 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,12 +20,13 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id.enhanced; import java.io.Serializable; +import org.hibernate.id.IntegralDataTypeHolder; + /** * Performs optimization on an optimizable identifier generator. Typically * this optimization takes the form of trying to ensure we do not have to @@ -43,6 +44,9 @@ /** * Generate an identifier value accounting for this specific optimization. * + * All known implementors are synchronized. Consider carefully if a new + * implementation could drop this requirement. + * * @param callback Callback to access the underlying value source. * @return The generated identifier value. */ @@ -51,12 +55,12 @@ /** * A common means to access the last value obtained from the underlying * source. This is intended for testing purposes, since accessing the - * unerlying database source directly is much more difficult. + * underlying database source directly is much more difficult. * * @return The last value we obtained from the underlying source; - * -1 indicates we have not yet consulted with the source. + * null indicates we have not yet consulted with the source. */ - public long getLastSourceValue(); + public IntegralDataTypeHolder getLastSourceValue(); /** * Retrieves the defined increment size. Index: 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/OptimizerFactory.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/OptimizerFactory.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/OptimizerFactory.java 17 Aug 2012 14:33:56 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/OptimizerFactory.java 30 Jul 2014 16:16:38 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,286 +20,147 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id.enhanced; -import java.io.Serializable; import java.lang.reflect.Constructor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.ReflectHelper; +import org.jboss.logging.Logger; -import org.hibernate.HibernateException; -import org.hibernate.util.ReflectHelper; -import org.hibernate.id.IdentifierGeneratorFactory; - /** * Factory for {@link Optimizer} instances. * * @author Steve Ebersole */ public class OptimizerFactory { - private static final Logger log = LoggerFactory.getLogger( OptimizerFactory.class ); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + OptimizerFactory.class.getName() + ); - public static final String NONE = "none"; - public static final String HILO = "hilo"; - public static final String POOL = "pooled"; + /** + * Does the given optimizer name represent a pooled strategy? + * + * @param optimizerName The name of the optimizer + * + * @return {@code true} indicates the optimizer is a pooled strategy. + */ + public static boolean isPooledOptimizer(String optimizerName) { + final StandardOptimizerDescriptor standardDescriptor = StandardOptimizerDescriptor.fromExternalName( optimizerName ); + return standardDescriptor != null && standardDescriptor.isPooled(); + } - private static Class[] CTOR_SIG = new Class[] { Class.class, int.class }; + private static final Class[] CTOR_SIG = new Class[] { Class.class, int.class }; + /** + * Builds an optimizer + * + * @param type The optimizer type, either a short-hand name or the {@link Optimizer} class name. + * @param returnClass The generated value java type + * @param incrementSize The increment size. + * + * @return The built optimizer + * + * @deprecated Use {@link #buildOptimizer(String, Class, int, long)} instead + */ + @Deprecated public static Optimizer buildOptimizer(String type, Class returnClass, int incrementSize) { - String optimizerClassName; - if ( NONE.equals( type ) ) { - optimizerClassName = NoopOptimizer.class.getName(); + final Class optimizerClass; + + final StandardOptimizerDescriptor standardDescriptor = StandardOptimizerDescriptor.fromExternalName( type ); + if ( standardDescriptor != null ) { + optimizerClass = standardDescriptor.getOptimizerClass(); } - else if ( HILO.equals( type ) ) { - optimizerClassName = HiLoOptimizer.class.getName(); - } - else if ( POOL.equals( type ) ) { - optimizerClassName = PooledOptimizer.class.getName(); - } else { - optimizerClassName = type; + try { + optimizerClass = ReflectHelper.classForName( type ); + } + catch( Throwable ignore ) { + LOG.unableToLocateCustomOptimizerClass( type ); + return buildFallbackOptimizer( returnClass, incrementSize ); + } } try { - Class optimizerClass = ReflectHelper.classForName( optimizerClassName ); - Constructor ctor = optimizerClass.getConstructor( CTOR_SIG ); - return ( Optimizer ) ctor.newInstance( new Object[] { returnClass, new Integer( incrementSize ) } ); + final Constructor ctor = optimizerClass.getConstructor( CTOR_SIG ); + return (Optimizer) ctor.newInstance( returnClass, incrementSize ); } catch( Throwable ignore ) { - // intentionally empty + LOG.unableToInstantiateOptimizer( type ); } - // the default... + return buildFallbackOptimizer( returnClass, incrementSize ); + } + + private static Optimizer buildFallbackOptimizer(Class returnClass, int incrementSize) { return new NoopOptimizer( returnClass, incrementSize ); } /** - * Common support for optimizer implementations. + * Builds an optimizer + * + * @param type The optimizer type, either a short-hand name or the {@link Optimizer} class name. + * @param returnClass The generated value java type + * @param incrementSize The increment size. + * @param explicitInitialValue The user supplied initial-value (-1 indicates the user did not specify). + * + * @return The built optimizer */ - public static abstract class OptimizerSupport implements Optimizer { - protected final Class returnClass; - protected final int incrementSize; - - /** - * Construct an optimizer - * - * @param returnClass The expected id class. - * @param incrementSize The increment size - */ - protected OptimizerSupport(Class returnClass, int incrementSize) { - if ( returnClass == null ) { - throw new HibernateException( "return class is required" ); - } - this.returnClass = returnClass; - this.incrementSize = incrementSize; + public static Optimizer buildOptimizer(String type, Class returnClass, int incrementSize, long explicitInitialValue) { + final Optimizer optimizer = buildOptimizer( type, returnClass, incrementSize ); + if ( InitialValueAwareOptimizer.class.isInstance( optimizer ) ) { + ( (InitialValueAwareOptimizer) optimizer ).injectInitialValue( explicitInitialValue ); } - - /** - * Take the primitive long value and "make" (or wrap) it into the - * {@link #getReturnClass id type}. - * - * @param value The primitive value to make/wrap. - * @return The wrapped value. - */ - protected final Serializable make(long value) { - return IdentifierGeneratorFactory.createNumber( value, returnClass ); - } - - /** - * Getter for property 'returnClass'. This is the Java - * class which is used to represent the id (e.g. {@link java.lang.Long}). - * - * @return Value for property 'returnClass'. - */ - public final Class getReturnClass() { - return returnClass; - } - - /** - * {@inheritDoc} - */ - public final int getIncrementSize() { - return incrementSize; - } + return optimizer; } /** - * An optimizer that performs no optimization. The database is hit for - * every request. + * Deprecated! + * + * @deprecated Use {@link StandardOptimizerDescriptor#getExternalName()} via {@link StandardOptimizerDescriptor#NONE} */ - public static class NoopOptimizer extends OptimizerSupport { - private long lastSourceValue = -1; + @Deprecated + @SuppressWarnings( {"UnusedDeclaration"}) + public static final String NONE = StandardOptimizerDescriptor.NONE.getExternalName(); - public NoopOptimizer(Class returnClass, int incrementSize) { - super( returnClass, incrementSize ); - } + /** + * Deprecated! + * + * @deprecated Use {@link StandardOptimizerDescriptor#getExternalName()} via {@link StandardOptimizerDescriptor#HILO} + */ + @Deprecated + @SuppressWarnings( {"UnusedDeclaration"}) + public static final String HILO = StandardOptimizerDescriptor.HILO.getExternalName(); - /** - * {@inheritDoc} - */ - public Serializable generate(AccessCallback callback) { - if ( lastSourceValue == -1 ) { - while( lastSourceValue <= 0 ) { - lastSourceValue = callback.getNextValue(); - } - } - else { - lastSourceValue = callback.getNextValue(); - } - return make( lastSourceValue ); - } + /** + * Deprecated! + * + * @deprecated Use {@link StandardOptimizerDescriptor#getExternalName()} via {@link StandardOptimizerDescriptor#LEGACY_HILO} + */ + @Deprecated + @SuppressWarnings( {"UnusedDeclaration"}) + public static final String LEGACY_HILO = "legacy-hilo"; - /** - * {@inheritDoc} - */ - public long getLastSourceValue() { - return lastSourceValue; - } - - /** - * {@inheritDoc} - */ - public boolean applyIncrementSizeToSourceValues() { - return false; - } - } - /** - * Optimizer which applies a 'hilo' algorithm in memory to achieve - * optimization. + * Deprecated! + * + * @deprecated Use {@link StandardOptimizerDescriptor#getExternalName()} via {@link StandardOptimizerDescriptor#POOLED} */ - public static class HiLoOptimizer extends OptimizerSupport { - private long lastSourceValue = -1; - private long value; - private long hiValue; + @Deprecated + @SuppressWarnings( {"UnusedDeclaration"}) + public static final String POOL = "pooled"; - public HiLoOptimizer(Class returnClass, int incrementSize) { - super( returnClass, incrementSize ); - if ( incrementSize < 1 ) { - throw new HibernateException( "increment size cannot be less than 1" ); - } - if ( log.isTraceEnabled() ) { - log.trace( "creating hilo optimizer with [incrementSize=" + incrementSize + "; returnClass=" + returnClass.getName() + "]" ); - } - } - - /** - * {@inheritDoc} - */ - public synchronized Serializable generate(AccessCallback callback) { - if ( lastSourceValue < 0 ) { - lastSourceValue = callback.getNextValue(); - while ( lastSourceValue <= 0 ) { - lastSourceValue = callback.getNextValue(); - } - hiValue = ( lastSourceValue * incrementSize ) + 1; - value = hiValue - incrementSize; - } - else if ( value >= hiValue ) { - lastSourceValue = callback.getNextValue(); - hiValue = ( lastSourceValue * incrementSize ) + 1; - } - return make( value++ ); - } - - - /** - * {@inheritDoc} - */ - public long getLastSourceValue() { - return lastSourceValue; - } - - /** - * {@inheritDoc} - */ - public boolean applyIncrementSizeToSourceValues() { - return false; - } - - /** - * Getter for property 'lastValue'. - * - * @return Value for property 'lastValue'. - */ - public long getLastValue() { - return value - 1; - } - - /** - * Getter for property 'hiValue'. - * - * @return Value for property 'hiValue'. - */ - public long getHiValue() { - return hiValue; - } - } - /** - * Optimizer which uses a pool of values, storing the next low value of the - * range in the database. + * Deprecated! + * + * @deprecated Use {@link StandardOptimizerDescriptor#getExternalName()} via {@link StandardOptimizerDescriptor#POOLED_LO} */ - public static class PooledOptimizer extends OptimizerSupport { - private long value; - private long hiValue = -1; + @Deprecated + @SuppressWarnings( {"UnusedDeclaration"}) + public static final String POOL_LO = "pooled-lo"; - public PooledOptimizer(Class returnClass, int incrementSize) { - super( returnClass, incrementSize ); - if ( incrementSize < 1 ) { - throw new HibernateException( "increment size cannot be less than 1" ); - } - if ( log.isTraceEnabled() ) { - log.trace( "creating pooled optimizer with [incrementSize=" + incrementSize + "; returnClass=" + returnClass.getName() + "]" ); - } - } - - /** - * {@inheritDoc} - */ - public synchronized Serializable generate(AccessCallback callback) { - if ( hiValue < 0 ) { - value = callback.getNextValue(); - if ( value < 1 ) { - // unfortunately not really safe to normalize this - // to 1 as an initial value like we do the others - // because we would not be able to control this if - // we are using a sequence... - log.info( "pooled optimizer source reported [" + value + "] as the initial value; use of 1 or greater highly recommended" ); - } - hiValue = callback.getNextValue(); - } - else if ( value >= hiValue ) { - hiValue = callback.getNextValue(); - value = hiValue - incrementSize; - } - return make( value++ ); - } - - /** - * {@inheritDoc} - */ - public long getLastSourceValue() { - return hiValue; - } - - /** - * {@inheritDoc} - */ - public boolean applyIncrementSizeToSourceValues() { - return true; - } - - /** - * Getter for property 'lastValue'. - * - * @return Value for property 'lastValue'. - */ - public long getLastValue() { - return value - 1; - } + private OptimizerFactory() { } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/PooledLoOptimizer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/PooledOptimizer.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/SequenceStructure.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/SequenceStructure.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/SequenceStructure.java 17 Aug 2012 14:33:56 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/SequenceStructure.java 30 Jul 2014 16:16:38 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,129 +20,141 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id.enhanced; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.exception.JDBCExceptionHelper; import org.hibernate.HibernateException; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.id.IdentifierGeneratorHelper; +import org.hibernate.id.IntegralDataTypeHolder; +import org.hibernate.internal.CoreMessageLogger; +import org.jboss.logging.Logger; + /** * Describes a sequence. * * @author Steve Ebersole */ public class SequenceStructure implements DatabaseStructure { - private static final Logger log = LoggerFactory.getLogger( SequenceStructure.class ); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + SequenceStructure.class.getName() + ); private final String sequenceName; private final int initialValue; private final int incrementSize; + private final Class numberType; private final String sql; private boolean applyIncrementSizeToSourceValues; private int accessCounter; - public SequenceStructure(Dialect dialect, String sequenceName, int initialValue, int incrementSize) { + public SequenceStructure( + Dialect dialect, + String sequenceName, + int initialValue, + int incrementSize, + Class numberType) { this.sequenceName = sequenceName; this.initialValue = initialValue; this.incrementSize = incrementSize; + this.numberType = numberType; sql = dialect.getSequenceNextValString( sequenceName ); } - /** - * {@inheritDoc} - */ + @Override public String getName() { return sequenceName; } - /** - * {@inheritDoc} - */ + @Override public int getIncrementSize() { return incrementSize; } - /** - * {@inheritDoc} - */ + @Override public int getTimesAccessed() { return accessCounter; } - /** - * {@inheritDoc} - */ + @Override + public int getInitialValue() { + return initialValue; + } + + @Override public AccessCallback buildCallback(final SessionImplementor session) { return new AccessCallback() { - public long getNextValue() { + @Override + public IntegralDataTypeHolder getNextValue() { accessCounter++; try { - PreparedStatement st = session.getBatcher().prepareSelectStatement( sql ); + final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql ); try { - ResultSet rs = st.executeQuery(); + final ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st ); try { rs.next(); - long result = rs.getLong( 1 ); - if ( log.isDebugEnabled() ) { - log.debug("Sequence identifier generated: " + result); + final IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType ); + value.initialize( rs, 1 ); + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Sequence value obtained: %s", value.makeValue() ); } - return result; + return value; } finally { try { - rs.close(); + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st ); } catch( Throwable ignore ) { // intentionally empty } } } finally { - session.getBatcher().closeStatement( st ); + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } } catch ( SQLException sqle) { - throw JDBCExceptionHelper.convert( - session.getFactory().getSQLExceptionConverter(), + throw session.getFactory().getSQLExceptionHelper().convert( sqle, "could not get next sequence value", sql ); } } + + @Override + public String getTenantIdentifier() { + return session.getTenantIdentifier(); + } }; } - /** - * {@inheritDoc} - */ + @Override public void prepare(Optimizer optimizer) { applyIncrementSizeToSourceValues = optimizer.applyIncrementSizeToSourceValues(); } - /** - * {@inheritDoc} - */ + @Override public String[] sqlCreateStrings(Dialect dialect) throws HibernateException { - int sourceIncrementSize = applyIncrementSizeToSourceValues ? incrementSize : 1; + final int sourceIncrementSize = applyIncrementSizeToSourceValues ? incrementSize : 1; return dialect.getCreateSequenceStrings( sequenceName, initialValue, sourceIncrementSize ); } - /** - * {@inheritDoc} - */ + @Override public String[] sqlDropStrings(Dialect dialect) throws HibernateException { return dialect.getDropSequenceStrings( sequenceName ); } + + @Override + public boolean isPhysicalSequence() { + return true; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/SequenceStyleGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/SequenceStyleGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/SequenceStyleGenerator.java 17 Aug 2012 14:33:56 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/SequenceStyleGenerator.java 30 Jul 2014 16:16:38 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,32 +20,40 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id.enhanced; -import java.util.Properties; import java.io.Serializable; +import java.util.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.hibernate.id.PersistentIdentifierGenerator; -import org.hibernate.id.Configurable; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.cfg.Environment; +import org.hibernate.cfg.ObjectNameNormalizer; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.id.BulkInsertionCapableIdentifierGenerator; +import org.hibernate.id.Configurable; +import org.hibernate.id.PersistentIdentifierGenerator; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.mapping.Table; -import org.hibernate.util.PropertiesHelper; import org.hibernate.type.Type; -import org.hibernate.dialect.Dialect; +import org.jboss.logging.Logger; + /** * Generates identifier values based on an sequence-style database structure. * Variations range from actually using a sequence to using a table to mimic * a sequence. These variations are encapsulated by the {@link DatabaseStructure} * interface internally. *

      + * NOTE that by default we utilize a single database sequence for all + * generators. The configuration parameter {@link #CONFIG_PREFER_SEQUENCE_PER_ENTITY} + * can be used to create dedicated sequence for each entity based on its name. + * Sequence suffix can be controlled with {@link #CONFIG_SEQUENCE_PER_ENTITY_SUFFIX} + * option. + *

      * General configuration parameters: * * @@ -73,8 +81,9 @@ * * * + * * - * + * * * *
      depends on defined increment sizeAllows explicit definition of which optimization strategy to use
      {@link #FORCE_TBL_PARAM}falsefalseAllows explicit definition of which optimization strategy to use
      @@ -94,27 +103,90 @@ * * * @author Steve Ebersole + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) */ -public class SequenceStyleGenerator implements PersistentIdentifierGenerator, Configurable { - private static final Logger log = LoggerFactory.getLogger( SequenceStyleGenerator.class ); +public class SequenceStyleGenerator + implements PersistentIdentifierGenerator, BulkInsertionCapableIdentifierGenerator, Configurable { + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + SequenceStyleGenerator.class.getName() + ); + + // general purpose parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Indicates the name of the sequence (or table) to use. The default value is {@link #DEF_SEQUENCE_NAME}, + * although {@link #CONFIG_PREFER_SEQUENCE_PER_ENTITY} effects the default as well. + */ public static final String SEQUENCE_PARAM = "sequence_name"; + + /** + * The default value for {@link #SEQUENCE_PARAM}, in the absence of any {@link #CONFIG_PREFER_SEQUENCE_PER_ENTITY} + * setting. + */ public static final String DEF_SEQUENCE_NAME = "hibernate_sequence"; + /** + * Indicates the initial value to use. The default value is {@link #DEFAULT_INITIAL_VALUE} + */ public static final String INITIAL_PARAM = "initial_value"; + + /** + * The default value for {@link #INITIAL_PARAM} + */ public static final int DEFAULT_INITIAL_VALUE = 1; + /** + * Indicates the increment size to use. The default value is {@link #DEFAULT_INCREMENT_SIZE} + */ public static final String INCREMENT_PARAM = "increment_size"; + + /** + * The default value for {@link #INCREMENT_PARAM} + */ public static final int DEFAULT_INCREMENT_SIZE = 1; + /** + * Used to create dedicated sequence for each entity based on the entity name. Sequence suffix can be + * controlled with {@link #CONFIG_SEQUENCE_PER_ENTITY_SUFFIX} option. + */ + public static final String CONFIG_PREFER_SEQUENCE_PER_ENTITY = "prefer_sequence_per_entity"; + + /** + * Indicates the suffix to use in naming the identifier sequence/table name, by appending the suffix to + * the name of the entity. Used in conjunction with {@link #CONFIG_PREFER_SEQUENCE_PER_ENTITY}. + */ + public static final String CONFIG_SEQUENCE_PER_ENTITY_SUFFIX = "sequence_per_entity_suffix"; + + /** + * The default value for {@link #CONFIG_SEQUENCE_PER_ENTITY_SUFFIX} + */ + public static final String DEF_SEQUENCE_SUFFIX = "_SEQ"; + + /** + * Indicates the optimizer to use, either naming a {@link Optimizer} implementation class or naming + * a {@link StandardOptimizerDescriptor} by name + */ public static final String OPT_PARAM = "optimizer"; + /** + * A flag to force using a table as the underlying structure rather than a sequence. + */ public static final String FORCE_TBL_PARAM = "force_table_use"; // table-specific parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Indicates the name of the column holding the identifier values. The default value is {@link #DEF_VALUE_COLUMN} + */ public static final String VALUE_COLUMN_PARAM = "value_column"; + + /** + * The default value for {@link #VALUE_COLUMN_PARAM} + */ public static final String DEF_VALUE_COLUMN = "next_val"; @@ -151,16 +223,15 @@ } + // Configurable implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - /** - * {@inheritDoc} - */ + @Override public void configure(Type type, Properties params, Dialect dialect) throws MappingException { this.identifierType = type; - boolean forceTableUse = PropertiesHelper.getBoolean( FORCE_TBL_PARAM, params, false ); + boolean forceTableUse = ConfigurationHelper.getBoolean( FORCE_TBL_PARAM, params, false ); - final String sequenceName = determineSequenceName( params ); + final String sequenceName = determineSequenceName( params, dialect ); final int initialValue = determineInitialValue( params ); int incrementSize = determineIncrementSize( params ); @@ -169,17 +240,27 @@ incrementSize = determineAdjustedIncrementSize( optimizationStrategy, incrementSize ); if ( dialect.supportsSequences() && !forceTableUse ) { - if ( OptimizerFactory.POOL.equals( optimizationStrategy ) && !dialect.supportsPooledSequences() ) { + if ( !dialect.supportsPooledSequences() && OptimizerFactory.isPooledOptimizer( optimizationStrategy ) ) { forceTableUse = true; - log.info( - "Forcing table use for sequence-style generator due to pooled optimizer selection where db does not support pooled sequences" - ); + LOG.forcingTableUse(); } } - this.databaseStructure = buildDatabaseStructure( params, dialect, forceTableUse, sequenceName, initialValue, incrementSize ); - - this.optimizer = OptimizerFactory.buildOptimizer( optimizationStrategy, identifierType.getReturnedClass(), incrementSize ); + this.databaseStructure = buildDatabaseStructure( + type, + params, + dialect, + forceTableUse, + sequenceName, + initialValue, + incrementSize + ); + this.optimizer = OptimizerFactory.buildOptimizer( + optimizationStrategy, + identifierType.getReturnedClass(), + incrementSize, + ConfigurationHelper.getInt( INITIAL_PARAM, params, -1 ) + ); this.databaseStructure.prepare( optimizer ); } @@ -190,15 +271,30 @@ * Called during {@link #configure configuration}. * * @param params The params supplied in the generator config (plus some standard useful extras). + * @param dialect The dialect in effect * @return The sequence name */ - protected String determineSequenceName(Properties params) { - String sequenceName = PropertiesHelper.getString( SEQUENCE_PARAM, params, DEF_SEQUENCE_NAME ); + protected String determineSequenceName(Properties params, Dialect dialect) { + final String sequencePerEntitySuffix = ConfigurationHelper.getString( CONFIG_SEQUENCE_PER_ENTITY_SUFFIX, params, DEF_SEQUENCE_SUFFIX ); + // JPA_ENTITY_NAME value honors (HBM) and @Entity#name (JPA) overrides. + String sequenceName = ConfigurationHelper.getBoolean( CONFIG_PREFER_SEQUENCE_PER_ENTITY, params, false ) + ? params.getProperty( JPA_ENTITY_NAME ) + sequencePerEntitySuffix + : DEF_SEQUENCE_NAME; + final ObjectNameNormalizer normalizer = (ObjectNameNormalizer) params.get( IDENTIFIER_NORMALIZER ); + sequenceName = ConfigurationHelper.getString( SEQUENCE_PARAM, params, sequenceName ); if ( sequenceName.indexOf( '.' ) < 0 ) { - String schemaName = params.getProperty( SCHEMA ); - String catalogName = params.getProperty( CATALOG ); - sequenceName = Table.qualify( catalogName, schemaName, sequenceName ); + sequenceName = normalizer.normalizeIdentifierQuoting( sequenceName ); + final String schemaName = params.getProperty( SCHEMA ); + final String catalogName = params.getProperty( CATALOG ); + sequenceName = Table.qualify( + dialect.quote( catalogName ), + dialect.quote( schemaName ), + dialect.quote( sequenceName ) + ); } + // if already qualified there is not much we can do in a portable manner so we pass it + // through and assume the user has set up the name correctly. + return sequenceName; } @@ -210,10 +306,13 @@ * physical table. * * @param params The params supplied in the generator config (plus some standard useful extras). + * @param dialect The dialect in effect. * @return The value column name */ - protected String determineValueColumnName(Properties params) { - return PropertiesHelper.getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN ); + protected String determineValueColumnName(Properties params, Dialect dialect) { + final ObjectNameNormalizer normalizer = (ObjectNameNormalizer) params.get( IDENTIFIER_NORMALIZER ); + final String name = ConfigurationHelper.getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN ); + return dialect.quote( normalizer.normalizeIdentifierQuoting( name ) ); } /** @@ -227,7 +326,7 @@ * @return The initial value */ protected int determineInitialValue(Properties params) { - return PropertiesHelper.getInt( INITIAL_PARAM, params, DEFAULT_INITIAL_VALUE ); + return ConfigurationHelper.getInt( INITIAL_PARAM, params, DEFAULT_INITIAL_VALUE ); } /** @@ -240,7 +339,7 @@ * @return The increment size */ protected int determineIncrementSize(Properties params) { - return PropertiesHelper.getInt( INCREMENT_PARAM, params, DEFAULT_INCREMENT_SIZE ); + return ConfigurationHelper.getInt( INCREMENT_PARAM, params, DEFAULT_INCREMENT_SIZE ); } /** @@ -253,8 +352,15 @@ * @return The optimizer strategy (name) */ protected String determineOptimizationStrategy(Properties params, int incrementSize) { - String defOptStrategy = incrementSize <= 1 ? OptimizerFactory.NONE : OptimizerFactory.POOL; - return PropertiesHelper.getString( OPT_PARAM, params, defOptStrategy ); + // if the increment size is greater than one, we prefer pooled optimization; but we first + // need to see if the user prefers POOL or POOL_LO... + final String defaultPooledOptimizerStrategy = ConfigurationHelper.getBoolean( Environment.PREFER_POOLED_VALUES_LO, params, false ) + ? StandardOptimizerDescriptor.POOLED_LO.getExternalName() + : StandardOptimizerDescriptor.POOLED.getExternalName(); + final String defaultOptimizerStrategy = incrementSize <= 1 + ? StandardOptimizerDescriptor.NONE.getExternalName() + : defaultPooledOptimizerStrategy; + return ConfigurationHelper.getString( OPT_PARAM, params, defaultOptimizerStrategy ); } /** @@ -266,8 +372,12 @@ * @return The adjusted increment size. */ protected int determineAdjustedIncrementSize(String optimizationStrategy, int incrementSize) { - if ( OptimizerFactory.NONE.equals( optimizationStrategy ) && incrementSize > 1 ) { - log.warn( "config specified explicit optimizer of [" + OptimizerFactory.NONE + "], but [" + INCREMENT_PARAM + "=" + incrementSize + "; honoring optimizer setting" ); + if ( incrementSize > 1 && StandardOptimizerDescriptor.NONE.getExternalName().equals( optimizationStrategy ) ) { + LOG.honoringOptimizerSetting( + StandardOptimizerDescriptor.NONE.getExternalName(), + INCREMENT_PARAM, + incrementSize + ); incrementSize = 1; } return incrementSize; @@ -276,62 +386,74 @@ /** * Build the database structure. * + * @param type The Hibernate type of the identifier property * @param params The params supplied in the generator config (plus some standard useful extras). * @param dialect The dialect being used. * @param forceTableUse Should a table be used even if the dialect supports sequences? * @param sequenceName The name to use for the sequence or table. * @param initialValue The initial value. * @param incrementSize the increment size to use (after any adjustments). - * @return The db structure representation + * + * @return An abstraction for the actual database structure in use (table vs. sequence). */ protected DatabaseStructure buildDatabaseStructure( + Type type, Properties params, Dialect dialect, boolean forceTableUse, String sequenceName, int initialValue, int incrementSize) { - boolean useSequence = dialect.supportsSequences() && !forceTableUse; + final boolean useSequence = dialect.supportsSequences() && !forceTableUse; if ( useSequence ) { - return new SequenceStructure( dialect, sequenceName, initialValue, incrementSize ); + return new SequenceStructure( dialect, sequenceName, initialValue, incrementSize, type.getReturnedClass() ); } else { - String valueColumnName = determineValueColumnName( params ); - return new TableStructure( dialect, sequenceName, valueColumnName, initialValue, incrementSize ); + final String valueColumnName = determineValueColumnName( params, dialect ); + return new TableStructure( dialect, sequenceName, valueColumnName, initialValue, incrementSize, type.getReturnedClass() ); } } // IdentifierGenerator implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - /** - * {@inheritDoc} - */ + @Override public Serializable generate(SessionImplementor session, Object object) throws HibernateException { return optimizer.generate( databaseStructure.buildCallback( session ) ); } // PersistentIdentifierGenerator implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - /** - * {@inheritDoc} - */ + @Override public Object generatorKey() { return databaseStructure.getName(); } - /** - * {@inheritDoc} - */ + @Override public String[] sqlCreateStrings(Dialect dialect) throws HibernateException { return databaseStructure.sqlCreateStrings( dialect ); } - /** - * {@inheritDoc} - */ + @Override public String[] sqlDropStrings(Dialect dialect) throws HibernateException { return databaseStructure.sqlDropStrings( dialect ); } + + + // BulkInsertionCapableIdentifierGenerator implementation ~~~~~~~~~~~~~~~~~ + + @Override + public boolean supportsBulkInsertionIdentifierGeneration() { + // it does, as long as + // 1) there is no (non-noop) optimizer in use + // 2) the underlying structure is a sequence + return NoopOptimizer.class.isInstance( getOptimizer() ) + && getDatabaseStructure().isPhysicalSequence(); + } + + @Override + public String determineBulkInsertionIdentifierGenerationSelectFragment(Dialect dialect) { + return dialect.getSelectSequenceNextValString( getDatabaseStructure().getName() ); + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/StandardOptimizerDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/TableGenerator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/TableGenerator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/TableGenerator.java 17 Aug 2012 14:33:56 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/TableGenerator.java 30 Jul 2014 16:16:38 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,38 +20,44 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id.enhanced; -import java.sql.Types; +import java.io.Serializable; import java.sql.Connection; -import java.sql.SQLException; import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.util.Properties; -import java.util.HashMap; +import java.sql.SQLException; +import java.sql.Types; import java.util.Collections; import java.util.Map; -import java.io.Serializable; +import java.util.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.hibernate.engine.TransactionHelper; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.id.PersistentIdentifierGenerator; -import org.hibernate.id.Configurable; -import org.hibernate.type.Type; -import org.hibernate.dialect.Dialect; import org.hibernate.HibernateException; -import org.hibernate.MappingException; import org.hibernate.LockMode; -import org.hibernate.jdbc.util.FormatStyle; +import org.hibernate.LockOptions; +import org.hibernate.MappingException; +import org.hibernate.cfg.Environment; +import org.hibernate.cfg.ObjectNameNormalizer; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.jdbc.internal.FormatStyle; +import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.engine.jdbc.spi.SqlStatementLogger; +import org.hibernate.engine.spi.SessionEventListenerManager; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.id.Configurable; +import org.hibernate.id.IdentifierGeneratorHelper; +import org.hibernate.id.IntegralDataTypeHolder; +import org.hibernate.id.PersistentIdentifierGenerator; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.jdbc.AbstractReturningWork; import org.hibernate.mapping.Table; -import org.hibernate.util.PropertiesHelper; -import org.hibernate.util.StringHelper; +import org.hibernate.type.Type; +import org.jboss.logging.Logger; + /** * An enhanced version of table-based id generation. *

      @@ -62,14 +68,14 @@ * performing generation, which would mean that we would have a row in the generator * table for each entity name. Or any configuration really; the setup is very flexible. *

      - * In this respect it is very simliar to the legacy + * In this respect it is very similar to the legacy * {@link org.hibernate.id.MultipleHiLoPerTableGenerator} in terms of the * underlying storage structure (namely a single table capable of holding * multiple generator values). The differentiator is, as with * {@link SequenceStyleGenerator} as well, the externalized notion * of an optimizer. *

      - * NOTE that by default we use a single row for all genertators (based + * NOTE that by default we use a single row for all generators (based * on {@link #DEF_SEGMENT_VALUE}). The configuration parameter * {@link #CONFIG_PREFER_SEGMENT_PER_ENTITY} can be used to change that to * instead default to using a row for each entity name. @@ -125,32 +131,96 @@ * * @author Steve Ebersole */ -public class TableGenerator extends TransactionHelper implements PersistentIdentifierGenerator, Configurable { - private static final Logger log = LoggerFactory.getLogger( TableGenerator.class ); +public class TableGenerator implements PersistentIdentifierGenerator, Configurable { + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + TableGenerator.class.getName() + ); + /** + * By default (in the absence of a {@link #SEGMENT_VALUE_PARAM} setting) we use a single row for all + * generators. This setting can be used to change that to instead default to using a row for each entity name. + */ public static final String CONFIG_PREFER_SEGMENT_PER_ENTITY = "prefer_entity_table_as_segment_value"; + /** + * Configures the name of the table to use. The default value is {@link #DEF_TABLE} + */ public static final String TABLE_PARAM = "table_name"; + + /** + * The default {@link #TABLE_PARAM} value + */ public static final String DEF_TABLE = "hibernate_sequences"; + /** + * The name of column which holds the sequence value. The default value is {@link #DEF_VALUE_COLUMN} + */ public static final String VALUE_COLUMN_PARAM = "value_column_name"; + + /** + * The default {@link #VALUE_COLUMN_PARAM} value + */ public static final String DEF_VALUE_COLUMN = "next_val"; + /** + * The name of the column which holds the segment key. The segment defines the different buckets (segments) + * of values currently tracked in the table. The default value is {@link #DEF_SEGMENT_COLUMN} + */ public static final String SEGMENT_COLUMN_PARAM = "segment_column_name"; + + /** + * The default {@link #SEGMENT_COLUMN_PARAM} value + */ public static final String DEF_SEGMENT_COLUMN = "sequence_name"; + /** + * The value indicating which segment is used by this generator, as indicated by the actual value stored in the + * column indicated by {@link #SEGMENT_COLUMN_PARAM}. The default value for setting is {@link #DEF_SEGMENT_VALUE}, + * although {@link #CONFIG_PREFER_SEGMENT_PER_ENTITY} effects the default as well. + */ public static final String SEGMENT_VALUE_PARAM = "segment_value"; + + /** + * The default {@link #SEGMENT_VALUE_PARAM} value, unless {@link #CONFIG_PREFER_SEGMENT_PER_ENTITY} is specified + */ public static final String DEF_SEGMENT_VALUE = "default"; + /** + * Indicates the length of the column defined by {@link #SEGMENT_COLUMN_PARAM}. Used in schema export. The + * default value is {@link #DEF_SEGMENT_LENGTH} + */ public static final String SEGMENT_LENGTH_PARAM = "segment_value_length"; + + /** + * The default {@link #SEGMENT_LENGTH_PARAM} value + */ public static final int DEF_SEGMENT_LENGTH = 255; + /** + * Indicates the initial value to use. The default value is {@link #DEFAULT_INITIAL_VALUE} + */ public static final String INITIAL_PARAM = "initial_value"; + + /** + * The default {@link #INITIAL_PARAM} value + */ public static final int DEFAULT_INITIAL_VALUE = 1; + /** + * Indicates the increment size to use. The default value is {@link #DEFAULT_INCREMENT_SIZE} + */ public static final String INCREMENT_PARAM = "increment_size"; + + /** + * The default {@link #INCREMENT_PARAM} value + */ public static final int DEFAULT_INCREMENT_SIZE = 1; + /** + * Indicates the optimizer to use, either naming a {@link Optimizer} implementation class or by naming + * a {@link StandardOptimizerDescriptor} by name + */ public static final String OPT_PARAM = "optimizer"; @@ -171,8 +241,13 @@ private String updateQuery; private Optimizer optimizer; - private long accessCount = 0; + private long accessCount; + @Override + public Object generatorKey() { + return tableName; + } + /** * Type mapping for the identifier. * @@ -273,15 +348,13 @@ return accessCount; } - /** - * {@inheritDoc} - */ + @Override public void configure(Type type, Properties params, Dialect dialect) throws MappingException { identifierType = type; - tableName = determneGeneratorTableName( params ); - segmentColumnName = determineSegmentColumnName( params ); - valueColumnName = determineValueColumnName( params ); + tableName = determineGeneratorTableName( params, dialect ); + segmentColumnName = determineSegmentColumnName( params, dialect ); + valueColumnName = determineValueColumnName( params, dialect ); segmentValue = determineSegmentValue( params ); @@ -293,9 +366,21 @@ this.updateQuery = buildUpdateQuery(); this.insertQuery = buildInsertQuery(); - String defOptStrategy = incrementSize <= 1 ? OptimizerFactory.NONE : OptimizerFactory.POOL; - String optimizationStrategy = PropertiesHelper.getString( OPT_PARAM, params, defOptStrategy ); - optimizer = OptimizerFactory.buildOptimizer( optimizationStrategy, identifierType.getReturnedClass(), incrementSize ); + // if the increment size is greater than one, we prefer pooled optimization; but we + // need to see if the user prefers POOL or POOL_LO... + final String defaultPooledOptimizerStrategy = ConfigurationHelper.getBoolean( Environment.PREFER_POOLED_VALUES_LO, params, false ) + ? StandardOptimizerDescriptor.POOLED_LO.getExternalName() + : StandardOptimizerDescriptor.POOLED.getExternalName(); + final String defaultOptimizerStrategy = incrementSize <= 1 + ? StandardOptimizerDescriptor.NONE.getExternalName() + : defaultPooledOptimizerStrategy; + final String optimizationStrategy = ConfigurationHelper.getString( OPT_PARAM, params, defaultOptimizerStrategy ); + optimizer = OptimizerFactory.buildOptimizer( + optimizationStrategy, + identifierType.getReturnedClass(), + incrementSize, + ConfigurationHelper.getInt( INITIAL_PARAM, params, -1 ) + ); } /** @@ -305,17 +390,27 @@ * * @see #getTableName() * @param params The params supplied in the generator config (plus some standard useful extras). + * @param dialect The dialect in effect * @return The table name to use. */ - protected String determneGeneratorTableName(Properties params) { - String name = PropertiesHelper.getString( TABLE_PARAM, params, DEF_TABLE ); - boolean isGivenNameUnqualified = name.indexOf( '.' ) < 0; + protected String determineGeneratorTableName(Properties params, Dialect dialect) { + String name = ConfigurationHelper.getString( TABLE_PARAM, params, DEF_TABLE ); + final boolean isGivenNameUnqualified = name.indexOf( '.' ) < 0; if ( isGivenNameUnqualified ) { + final ObjectNameNormalizer normalizer = (ObjectNameNormalizer) params.get( IDENTIFIER_NORMALIZER ); + name = normalizer.normalizeIdentifierQuoting( name ); // if the given name is un-qualified we may neen to qualify it - String schemaName = params.getProperty( SCHEMA ); - String catalogName = params.getProperty( CATALOG ); - name = Table.qualify( catalogName, schemaName, name ); + final String schemaName = normalizer.normalizeIdentifierQuoting( params.getProperty( SCHEMA ) ); + final String catalogName = normalizer.normalizeIdentifierQuoting( params.getProperty( CATALOG ) ); + name = Table.qualify( + dialect.quote( catalogName ), + dialect.quote( schemaName ), + dialect.quote( name) + ); } + // if already qualified there is not much we can do in a portable manner so we pass it + // through and assume the user has set up the name correctly. + return name; } @@ -327,10 +422,13 @@ * * @see #getSegmentColumnName() * @param params The params supplied in the generator config (plus some standard useful extras). + * @param dialect The dialect in effect * @return The name of the segment column */ - protected String determineSegmentColumnName(Properties params) { - return PropertiesHelper.getString( SEGMENT_COLUMN_PARAM, params, DEF_SEGMENT_COLUMN ); + protected String determineSegmentColumnName(Properties params, Dialect dialect) { + final ObjectNameNormalizer normalizer = (ObjectNameNormalizer) params.get( IDENTIFIER_NORMALIZER ); + final String name = ConfigurationHelper.getString( SEGMENT_COLUMN_PARAM, params, DEF_SEGMENT_COLUMN ); + return dialect.quote( normalizer.normalizeIdentifierQuoting( name ) ); } /** @@ -340,10 +438,13 @@ * * @see #getValueColumnName() * @param params The params supplied in the generator config (plus some standard useful extras). + * @param dialect The dialect in effect * @return The name of the value column */ - protected String determineValueColumnName(Properties params) { - return PropertiesHelper.getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN ); + protected String determineValueColumnName(Properties params, Dialect dialect) { + final ObjectNameNormalizer normalizer = (ObjectNameNormalizer) params.get( IDENTIFIER_NORMALIZER ); + final String name = ConfigurationHelper.getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN ); + return dialect.quote( normalizer.normalizeIdentifierQuoting( name ) ); } /** @@ -371,9 +472,9 @@ * @return The default segment value to use. */ protected String determineDefaultSegmentValue(Properties params) { - boolean preferSegmentPerEntity = PropertiesHelper.getBoolean( CONFIG_PREFER_SEGMENT_PER_ENTITY, params, false ); - String defaultToUse = preferSegmentPerEntity ? params.getProperty( TABLE ) : DEF_SEGMENT_VALUE; - log.info( "explicit segment value for id generator [" + tableName + '.' + segmentColumnName + "] suggested; using default [" + defaultToUse + "]" ); + final boolean preferSegmentPerEntity = ConfigurationHelper.getBoolean( CONFIG_PREFER_SEGMENT_PER_ENTITY, params, false ); + final String defaultToUse = preferSegmentPerEntity ? params.getProperty( TABLE ) : DEF_SEGMENT_VALUE; + LOG.usingDefaultIdGeneratorSegmentValue( tableName, segmentColumnName, defaultToUse ); return defaultToUse; } @@ -387,26 +488,26 @@ * @return The size of the segment column */ protected int determineSegmentColumnSize(Properties params) { - return PropertiesHelper.getInt( SEGMENT_LENGTH_PARAM, params, DEF_SEGMENT_LENGTH ); + return ConfigurationHelper.getInt( SEGMENT_LENGTH_PARAM, params, DEF_SEGMENT_LENGTH ); } protected int determineInitialValue(Properties params) { - return PropertiesHelper.getInt( INITIAL_PARAM, params, DEFAULT_INITIAL_VALUE ); + return ConfigurationHelper.getInt( INITIAL_PARAM, params, DEFAULT_INITIAL_VALUE ); } protected int determineIncrementSize(Properties params) { - return PropertiesHelper.getInt( INCREMENT_PARAM, params, DEFAULT_INCREMENT_SIZE ); + return ConfigurationHelper.getInt( INCREMENT_PARAM, params, DEFAULT_INCREMENT_SIZE ); } protected String buildSelectQuery(Dialect dialect) { final String alias = "tbl"; - String query = "select " + StringHelper.qualify( alias, valueColumnName ) + + final String query = "select " + StringHelper.qualify( alias, valueColumnName ) + " from " + tableName + ' ' + alias + " where " + StringHelper.qualify( alias, segmentColumnName ) + "=?"; - HashMap lockMap = new HashMap(); - lockMap.put( alias, LockMode.UPGRADE ); - Map updateTargetColumnsMap = Collections.singletonMap( alias, new String[] { valueColumnName } ); - return dialect.applyLocksToSql( query, lockMap, updateTargetColumnsMap ); + final LockOptions lockOptions = new LockOptions( LockMode.PESSIMISTIC_WRITE ); + lockOptions.setAliasSpecificLockMode( alias, LockMode.PESSIMISTIC_WRITE ); + final Map updateTargetColumnsMap = Collections.singletonMap( alias, new String[] { valueColumnName } ); + return dialect.applyLocksToSql( query, lockOptions, updateTargetColumnsMap ); } protected String buildUpdateQuery() { @@ -419,128 +520,149 @@ return "insert into " + tableName + " (" + segmentColumnName + ", " + valueColumnName + ") " + " values (?,?)"; } - /** - * {@inheritDoc} - */ - public synchronized Serializable generate(final SessionImplementor session, Object obj) { + private IntegralDataTypeHolder makeValue() { + return IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() ); + } + + @Override + public Serializable generate(final SessionImplementor session, final Object obj) { + final SqlStatementLogger statementLogger = session.getFactory().getServiceRegistry() + .getService( JdbcServices.class ) + .getSqlStatementLogger(); + final SessionEventListenerManager statsCollector = session.getEventListenerManager(); + return optimizer.generate( new AccessCallback() { - public long getNextValue() { - return ( ( Number ) doWorkInNewTransaction( session ) ).longValue(); + @Override + public IntegralDataTypeHolder getNextValue() { + return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork( + new AbstractReturningWork() { + @Override + public IntegralDataTypeHolder execute(Connection connection) throws SQLException { + final IntegralDataTypeHolder value = makeValue(); + int rows; + do { + final PreparedStatement selectPS = prepareStatement( connection, selectQuery, statementLogger, statsCollector ); + + try { + selectPS.setString( 1, segmentValue ); + final ResultSet selectRS = executeQuery( selectPS, statsCollector ); + if ( !selectRS.next() ) { + value.initialize( initialValue ); + + final PreparedStatement insertPS = prepareStatement( connection, insertQuery, statementLogger, statsCollector ); + try { + insertPS.setString( 1, segmentValue ); + value.bind( insertPS, 2 ); + executeUpdate( insertPS, statsCollector ); + } + finally { + insertPS.close(); + } + } + else { + value.initialize( selectRS, 1 ); + } + selectRS.close(); + } + catch (SQLException e) { + LOG.unableToReadOrInitHiValue( e ); + throw e; + } + finally { + selectPS.close(); + } + + + final PreparedStatement updatePS = prepareStatement( connection, updateQuery, statementLogger, statsCollector ); + try { + final IntegralDataTypeHolder updateValue = value.copy(); + if ( optimizer.applyIncrementSizeToSourceValues() ) { + updateValue.add( incrementSize ); + } + else { + updateValue.increment(); + } + updateValue.bind( updatePS, 1 ); + value.bind( updatePS, 2 ); + updatePS.setString( 3, segmentValue ); + rows = executeUpdate( updatePS, statsCollector ); + } + catch (SQLException e) { + LOG.unableToUpdateQueryHiValue( tableName, e ); + throw e; + } + finally { + updatePS.close(); + } + } + while ( rows == 0 ); + + accessCount++; + + return value; + } + }, + true + ); } + + @Override + public String getTenantIdentifier() { + return session.getTenantIdentifier(); + } } ); } - /** - * {@inheritDoc} - */ - public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException { - int result; - int rows; - do { - SQL_STATEMENT_LOGGER.logStatement( selectQuery, FormatStyle.BASIC ); - PreparedStatement selectPS = conn.prepareStatement( selectQuery ); - try { - selectPS.setString( 1, segmentValue ); - ResultSet selectRS = selectPS.executeQuery(); - if ( !selectRS.next() ) { - PreparedStatement insertPS = null; - try { - result = initialValue; - SQL_STATEMENT_LOGGER.logStatement( insertQuery, FormatStyle.BASIC ); - insertPS = conn.prepareStatement( insertQuery ); - insertPS.setString( 1, segmentValue ); - insertPS.setLong( 2, result ); - insertPS.execute(); - } - finally { - if ( insertPS != null ) { - insertPS.close(); - } - } - } - else { - result = selectRS.getInt( 1 ); - } - selectRS.close(); - } - catch ( SQLException sqle ) { - log.error( "could not read or init a hi value", sqle ); - throw sqle; - } - finally { - selectPS.close(); - } + private PreparedStatement prepareStatement( + Connection connection, + String sql, + SqlStatementLogger statementLogger, + SessionEventListenerManager statsCollector) throws SQLException { + statementLogger.logStatement( sql, FormatStyle.BASIC.getFormatter() ); + try { + statsCollector.jdbcPrepareStatementStart(); + return connection.prepareStatement( sql ); + } + finally { + statsCollector.jdbcPrepareStatementEnd(); + } + } - SQL_STATEMENT_LOGGER.logStatement( updateQuery, FormatStyle.BASIC ); - PreparedStatement updatePS = conn.prepareStatement( updateQuery ); - try { - long newValue = optimizer.applyIncrementSizeToSourceValues() - ? result + incrementSize : result + 1; - updatePS.setLong( 1, newValue ); - updatePS.setLong( 2, result ); - updatePS.setString( 3, segmentValue ); - rows = updatePS.executeUpdate(); - } - catch ( SQLException sqle ) { - log.error( "could not updateQuery hi value in: " + tableName, sqle ); - throw sqle; - } - finally { - updatePS.close(); - } + private int executeUpdate(PreparedStatement ps, SessionEventListenerManager statsCollector) throws SQLException { + try { + statsCollector.jdbcExecuteStatementStart(); + return ps.executeUpdate(); } - while ( rows == 0 ); + finally { + statsCollector.jdbcExecuteStatementEnd(); + } - accessCount++; + } - return new Integer( result ); + private ResultSet executeQuery(PreparedStatement ps, SessionEventListenerManager statsCollector) throws SQLException { + try { + statsCollector.jdbcExecuteStatementStart(); + return ps.executeQuery(); + } + finally { + statsCollector.jdbcExecuteStatementEnd(); + } } - /** - * {@inheritDoc} - */ + @Override public String[] sqlCreateStrings(Dialect dialect) throws HibernateException { return new String[] { - new StringBuffer() - .append( dialect.getCreateTableString() ) - .append( ' ' ) - .append( tableName ) - .append( " ( " ) - .append( segmentColumnName ) - .append( ' ' ) - .append( dialect.getTypeName( Types.VARCHAR, segmentValueLength, 0, 0 ) ) - .append( ", " ) - .append( valueColumnName ) - .append( ' ' ) - .append( dialect.getTypeName( Types.BIGINT ) ) - .append( ", primary key ( " ) - .append( segmentColumnName ) - .append( " ) ) " ) - .toString() + dialect.getCreateTableString() + ' ' + tableName + " ( " + + segmentColumnName + ' ' + dialect.getTypeName( Types.VARCHAR, segmentValueLength, 0, 0 ) + " not null " + + ", " + valueColumnName + ' ' + dialect.getTypeName( Types.BIGINT ) + + ", primary key ( " + segmentColumnName + " ) )" + dialect.getTableTypeString() }; } - /** - * {@inheritDoc} - */ + @Override public String[] sqlDropStrings(Dialect dialect) throws HibernateException { - StringBuffer sqlDropString = new StringBuffer().append( "drop table " ); - if ( dialect.supportsIfExistsBeforeTableName() ) { - sqlDropString.append( "if exists " ); - } - sqlDropString.append( tableName ).append( dialect.getCascadeConstraintsString() ); - if ( dialect.supportsIfExistsAfterTableName() ) { - sqlDropString.append( " if exists" ); - } - return new String[] { sqlDropString.toString() }; + return new String[] { dialect.getDropTableString( tableName ) }; } - - /** - * {@inheritDoc} - */ - public Object generatorKey() { - return tableName; - } } Index: 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/TableStructure.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/TableStructure.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/TableStructure.java 17 Aug 2012 14:33:56 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/TableStructure.java 30 Jul 2014 16:16:38 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,174 +20,225 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.id.enhanced; -import java.io.Serializable; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import org.hibernate.HibernateException; import org.hibernate.LockMode; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.engine.TransactionHelper; +import org.hibernate.engine.jdbc.internal.FormatStyle; +import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.engine.jdbc.spi.SqlStatementLogger; +import org.hibernate.engine.spi.SessionEventListenerManager; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.id.IdentifierGenerationException; -import org.hibernate.jdbc.util.FormatStyle; -import org.hibernate.jdbc.util.SQLStatementLogger; +import org.hibernate.id.IdentifierGeneratorHelper; +import org.hibernate.id.IntegralDataTypeHolder; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.jdbc.AbstractReturningWork; +import org.jboss.logging.Logger; + /** * Describes a table used to mimic sequence behavior * * @author Steve Ebersole */ -public class TableStructure extends TransactionHelper implements DatabaseStructure { - private static final Logger log = LoggerFactory.getLogger( TableStructure.class ); - private static final SQLStatementLogger SQL_STATEMENT_LOGGER = new SQLStatementLogger( false, false ); +public class TableStructure implements DatabaseStructure { + private static final CoreMessageLogger LOG = Logger.getMessageLogger( + CoreMessageLogger.class, + TableStructure.class.getName() + ); private final String tableName; private final String valueColumnName; private final int initialValue; private final int incrementSize; + private final Class numberType; private final String selectQuery; private final String updateQuery; private boolean applyIncrementSizeToSourceValues; private int accessCounter; - public TableStructure(Dialect dialect, String tableName, String valueColumnName, int initialValue, int incrementSize) { + public TableStructure( + Dialect dialect, + String tableName, + String valueColumnName, + int initialValue, + int incrementSize, + Class numberType) { this.tableName = tableName; this.initialValue = initialValue; this.incrementSize = incrementSize; this.valueColumnName = valueColumnName; + this.numberType = numberType; - selectQuery = "select " + valueColumnName + " id_val" + - " from " + dialect.appendLockHint( LockMode.UPGRADE, tableName ) + + selectQuery = "select " + valueColumnName + " as id_val" + + " from " + dialect.appendLockHint( LockMode.PESSIMISTIC_WRITE, tableName ) + dialect.getForUpdateString(); updateQuery = "update " + tableName + " set " + valueColumnName + "= ?" + " where " + valueColumnName + "=?"; } - /** - * {@inheritDoc} - */ + @Override public String getName() { return tableName; } - /** - * {@inheritDoc} - */ + @Override + public int getInitialValue() { + return initialValue; + } + + @Override public int getIncrementSize() { return incrementSize; } - /** - * {@inheritDoc} - */ + @Override public int getTimesAccessed() { return accessCounter; } - /** - * {@inheritDoc} - */ + @Override public void prepare(Optimizer optimizer) { applyIncrementSizeToSourceValues = optimizer.applyIncrementSizeToSourceValues(); } - /** - * {@inheritDoc} - */ + private IntegralDataTypeHolder makeValue() { + return IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType ); + } + + @Override public AccessCallback buildCallback(final SessionImplementor session) { + final SqlStatementLogger statementLogger = session.getFactory().getServiceRegistry() + .getService( JdbcServices.class ) + .getSqlStatementLogger(); + final SessionEventListenerManager statsCollector = session.getEventListenerManager(); + return new AccessCallback() { - public long getNextValue() { - return ( ( Number ) doWorkInNewTransaction( session ) ).longValue(); + @Override + public IntegralDataTypeHolder getNextValue() { + return session.getTransactionCoordinator().getTransaction().createIsolationDelegate().delegateWork( + new AbstractReturningWork() { + @Override + public IntegralDataTypeHolder execute(Connection connection) throws SQLException { + final IntegralDataTypeHolder value = makeValue(); + int rows; + do { + final PreparedStatement selectStatement = prepareStatement( connection, selectQuery, statementLogger, statsCollector ); + try { + final ResultSet selectRS = executeQuery( selectStatement, statsCollector ); + if ( !selectRS.next() ) { + final String err = "could not read a hi value - you need to populate the table: " + tableName; + LOG.error( err ); + throw new IdentifierGenerationException( err ); + } + value.initialize( selectRS, 1 ); + selectRS.close(); + } + catch (SQLException sqle) { + LOG.error( "could not read a hi value", sqle ); + throw sqle; + } + finally { + selectStatement.close(); + } + + + final PreparedStatement updatePS = prepareStatement( connection, updateQuery, statementLogger, statsCollector ); + try { + final int increment = applyIncrementSizeToSourceValues ? incrementSize : 1; + final IntegralDataTypeHolder updateValue = value.copy().add( increment ); + updateValue.bind( updatePS, 1 ); + value.bind( updatePS, 2 ); + rows = executeUpdate( updatePS, statsCollector ); + } + catch (SQLException e) { + LOG.unableToUpdateQueryHiValue( tableName, e ); + throw e; + } + finally { + updatePS.close(); + } + } while ( rows == 0 ); + + accessCounter++; + + return value; + } + }, + true + ); } + + @Override + public String getTenantIdentifier() { + return session.getTenantIdentifier(); + } }; } - /** - * {@inheritDoc} - */ + private PreparedStatement prepareStatement( + Connection connection, + String sql, + SqlStatementLogger statementLogger, + SessionEventListenerManager statsCollector) throws SQLException { + statementLogger.logStatement( sql, FormatStyle.BASIC.getFormatter() ); + try { + statsCollector.jdbcPrepareStatementStart(); + return connection.prepareStatement( sql ); + } + finally { + statsCollector.jdbcPrepareStatementEnd(); + } + } + + private int executeUpdate(PreparedStatement ps, SessionEventListenerManager statsCollector) throws SQLException { + try { + statsCollector.jdbcExecuteStatementStart(); + return ps.executeUpdate(); + } + finally { + statsCollector.jdbcExecuteStatementEnd(); + } + + } + + private ResultSet executeQuery(PreparedStatement ps, SessionEventListenerManager statsCollector) throws SQLException { + try { + statsCollector.jdbcExecuteStatementStart(); + return ps.executeQuery(); + } + finally { + statsCollector.jdbcExecuteStatementEnd(); + } + } + + @Override public String[] sqlCreateStrings(Dialect dialect) throws HibernateException { return new String[] { dialect.getCreateTableString() + " " + tableName + " ( " + valueColumnName + " " + dialect.getTypeName( Types.BIGINT ) + " )", "insert into " + tableName + " values ( " + initialValue + " )" }; } - /** - * {@inheritDoc} - */ + @Override public String[] sqlDropStrings(Dialect dialect) throws HibernateException { - StringBuffer sqlDropString = new StringBuffer().append( "drop table " ); - if ( dialect.supportsIfExistsBeforeTableName() ) { - sqlDropString.append( "if exists " ); - } - sqlDropString.append( tableName ).append( dialect.getCascadeConstraintsString() ); - if ( dialect.supportsIfExistsAfterTableName() ) { - sqlDropString.append( " if exists" ); - } - return new String[] { sqlDropString.toString() }; + return new String[] { dialect.getDropTableString( tableName ) }; } - /** - * {@inheritDoc} - */ - protected Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException { - long result; - int rows; - do { - SQL_STATEMENT_LOGGER.logStatement( selectQuery, FormatStyle.BASIC ); - PreparedStatement selectPS = conn.prepareStatement( selectQuery ); - try { - ResultSet selectRS = selectPS.executeQuery(); - if ( !selectRS.next() ) { - String err = "could not read a hi value - you need to populate the table: " + tableName; - log.error( err ); - throw new IdentifierGenerationException( err ); - } - result = selectRS.getLong( 1 ); - selectRS.close(); - } - catch ( SQLException sqle ) { - log.error( "could not read a hi value", sqle ); - throw sqle; - } - finally { - selectPS.close(); - } - - SQL_STATEMENT_LOGGER.logStatement( updateQuery, FormatStyle.BASIC ); - PreparedStatement updatePS = conn.prepareStatement( updateQuery ); - try { - int increment = applyIncrementSizeToSourceValues ? incrementSize : 1; - updatePS.setLong( 1, result + increment ); - updatePS.setLong( 2, result ); - rows = updatePS.executeUpdate(); - } - catch ( SQLException sqle ) { - log.error( "could not updateQuery hi value in: " + tableName, sqle ); - throw sqle; - } - finally { - updatePS.close(); - } - } while ( rows == 0 ); - - accessCounter++; - - return new Long( result ); + @Override + public boolean isPhysicalSequence() { + return false; } - } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/enhanced/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/factory/IdentifierGeneratorFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/factory/internal/DefaultIdentifierGeneratorFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/factory/internal/MutableIdentifierGeneratorFactoryInitiator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/factory/spi/MutableIdentifierGeneratorFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/id/insert/AbstractReturningDelegate.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/insert/AbstractReturningDelegate.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/insert/AbstractReturningDelegate.java 17 Aug 2012 14:33:57 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/insert/AbstractReturningDelegate.java 30 Jul 2014 16:16:33 -0000 1.1.2.1 @@ -23,16 +23,14 @@ * */ package org.hibernate.id.insert; - -import org.hibernate.id.PostInsertIdentityPersister; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.exception.JDBCExceptionHelper; -import org.hibernate.pretty.MessageHelper; - import java.io.Serializable; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.id.PostInsertIdentityPersister; +import org.hibernate.pretty.MessageHelper; + /** * Abstract InsertGeneratedIdentifierDelegate implementation where the * underlying strategy causes the enerated identitifer to be returned as an @@ -48,21 +46,23 @@ this.persister = persister; } - public final Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder) { + public final Serializable performInsert( + String insertSQL, + SessionImplementor session, + Binder binder) { try { // prepare and execute the insert PreparedStatement insert = prepare( insertSQL, session ); try { binder.bindValues( insert ); - return executeAndExtract( insert ); + return executeAndExtract( insert, session ); } finally { releaseStatement( insert, session ); } } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - session.getFactory().getSQLExceptionConverter(), + throw session.getFactory().getSQLExceptionHelper().convert( sqle, "could not insert: " + MessageHelper.infoString( persister ), insertSQL @@ -76,9 +76,9 @@ protected abstract PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException; - protected abstract Serializable executeAndExtract(PreparedStatement insert) throws SQLException; + protected abstract Serializable executeAndExtract(PreparedStatement insert, SessionImplementor session) throws SQLException; protected void releaseStatement(PreparedStatement insert, SessionImplementor session) throws SQLException { - session.getBatcher().closeStatement( insert ); + session.getTransactionCoordinator().getJdbcCoordinator().release( insert ); } } Index: 3rdParty_sources/hibernate-core/org/hibernate/id/insert/AbstractSelectingDelegate.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/insert/AbstractSelectingDelegate.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/insert/AbstractSelectingDelegate.java 17 Aug 2012 14:33:57 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/insert/AbstractSelectingDelegate.java 30 Jul 2014 16:16:33 -0000 1.1.2.1 @@ -23,17 +23,15 @@ * */ package org.hibernate.id.insert; - -import org.hibernate.exception.JDBCExceptionHelper; -import org.hibernate.pretty.MessageHelper; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.id.PostInsertIdentityPersister; - +import java.io.Serializable; import java.sql.PreparedStatement; -import java.sql.SQLException; import java.sql.ResultSet; -import java.io.Serializable; +import java.sql.SQLException; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.id.PostInsertIdentityPersister; +import org.hibernate.pretty.MessageHelper; + /** * Abstract InsertGeneratedIdentifierDelegate implementation where the * underlying strategy requires an subsequent select after the insert @@ -48,21 +46,26 @@ this.persister = persister; } - public final Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder) { + public final Serializable performInsert( + String insertSQL, + SessionImplementor session, + Binder binder) { try { // prepare and execute the insert - PreparedStatement insert = session.getBatcher().prepareStatement( insertSQL, false ); + PreparedStatement insert = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( insertSQL, PreparedStatement.NO_GENERATED_KEYS ); try { binder.bindValues( insert ); - insert.executeUpdate(); + session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( insert ); } finally { - session.getBatcher().closeStatement( insert ); + session.getTransactionCoordinator().getJdbcCoordinator().release( insert ); } } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - session.getFactory().getSQLExceptionConverter(), + throw session.getFactory().getSQLExceptionHelper().convert( sqle, "could not insert: " + MessageHelper.infoString( persister ), insertSQL @@ -73,25 +76,27 @@ try { //fetch the generated id in a separate query - PreparedStatement idSelect = session.getBatcher().prepareStatement( selectSQL ); + PreparedStatement idSelect = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( selectSQL, false ); try { bindParameters( session, idSelect, binder.getEntity() ); - ResultSet rs = idSelect.executeQuery(); + ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( idSelect ); try { return getResult( session, rs, binder.getEntity() ); } finally { - rs.close(); + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, idSelect ); } } finally { - session.getBatcher().closeStatement( idSelect ); + session.getTransactionCoordinator().getJdbcCoordinator().release( idSelect ); } } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - session.getFactory().getSQLExceptionConverter(), + throw session.getFactory().getSQLExceptionHelper().convert( sqle, "could not retrieve generated id after insert: " + MessageHelper.infoString( persister ), insertSQL Index: 3rdParty_sources/hibernate-core/org/hibernate/id/insert/Binder.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/insert/Binder.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/insert/Binder.java 17 Aug 2012 14:33:57 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/insert/Binder.java 30 Jul 2014 16:16:33 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.id.insert; - import java.sql.PreparedStatement; import java.sql.SQLException; Index: 3rdParty_sources/hibernate-core/org/hibernate/id/insert/IdentifierGeneratingInsert.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/insert/IdentifierGeneratingInsert.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/insert/IdentifierGeneratingInsert.java 17 Aug 2012 14:33:56 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/insert/IdentifierGeneratingInsert.java 30 Jul 2014 16:16:33 -0000 1.1.2.1 @@ -23,9 +23,8 @@ * */ package org.hibernate.id.insert; - -import org.hibernate.sql.Insert; import org.hibernate.dialect.Dialect; +import org.hibernate.sql.Insert; /** * Nothing more than a distinguishing subclass of Insert used to indicate Index: 3rdParty_sources/hibernate-core/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java 17 Aug 2012 14:33:56 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java 30 Jul 2014 16:16:33 -0000 1.1.2.1 @@ -23,11 +23,10 @@ * */ package org.hibernate.id.insert; - -import org.hibernate.engine.SessionImplementor; - import java.io.Serializable; +import org.hibernate.engine.spi.SessionImplementor; + /** * Responsible for handling delegation relating to variants in how * insert-generated-identifier generator strategies dictate processing:

        @@ -51,9 +50,11 @@ * Perform the indicated insert SQL statement and determine the identifier value * generated. * + * * @param insertSQL The INSERT statement string * @param session The session in which we are operating * @param binder The param binder + * * @return The generated identifier value. */ public Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder); Index: 3rdParty_sources/hibernate-core/org/hibernate/id/insert/InsertSelectIdentityInsert.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/id/insert/InsertSelectIdentityInsert.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/id/insert/InsertSelectIdentityInsert.java 17 Aug 2012 14:33:57 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/id/insert/InsertSelectIdentityInsert.java 30 Jul 2014 16:16:33 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.id.insert; - import org.hibernate.dialect.Dialect; /** Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/uuid/CustomVersionOneStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/uuid/Helper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/id/uuid/StandardRandomStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/integrator/internal/IntegratorServiceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/integrator/spi/Integrator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/integrator/spi/IntegratorService.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/integrator/spi/ServiceContributingIntegrator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/AbstractBasicQueryContractImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/AbstractQueryImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/AbstractScrollableResults.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/AbstractSessionImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/CacheImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/CollectionFilterImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/ConnectionObserverStatsBridge.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/CoreLogging.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/CoreMessageLogger.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/CriteriaImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/DynamicFilterAliasGenerator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/FetchingScrollableResultsImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/FilterAliasGenerator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/FilterConfiguration.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/FilterHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/FilterImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/IteratorImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/NamedQueryRepository.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/QueryImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/SQLQueryImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/ScrollableResultsImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/SessionFactoryImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/SessionFactoryObserverChain.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/SessionFactoryRegistry.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/SessionImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/StatelessSessionImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/StaticFilterAliasGenerator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/TransactionEnvironmentImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/TypeLocatorImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/package.html'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/jaxb/JaxbRoot.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/jaxb/Origin.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/jaxb/SourceType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/jaxb/mapping/hbm/CustomSqlElement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/jaxb/mapping/hbm/EntityElement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/jaxb/mapping/hbm/IdBagPluralAttributeElementAdapter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/jaxb/mapping/hbm/JoinElementSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/jaxb/mapping/hbm/MetaAttributeContainer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/jaxb/mapping/hbm/PluralAttributeElement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/jaxb/mapping/hbm/SingularAttributeSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/jaxb/mapping/hbm/SubEntityElement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/BytesHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/ClassLoaderHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/Cloneable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/ConfigHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/EntityPrinter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/JdbcExceptionHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/LockModeConverter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/MarkerObject.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/ReflectHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/SerializationHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/StringHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/ValueHolder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/package.html'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/beans/BeanInfoHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/beans/BeanIntrospectionException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/collections/ArrayHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/collections/BoundedConcurrentHashMap.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/collections/CollectionHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/collections/ConcurrentReferenceHashMap.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/collections/EmptyIterator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/collections/IdentityMap.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/collections/IdentitySet.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/collections/JoinedIterable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/collections/JoinedIterator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/collections/LazyIterator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/collections/SingletonIterator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/compare/CalendarComparator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/compare/ComparableComparator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/compare/EqualsHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/config/ConfigurationException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/config/ConfigurationHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/io/StreamCopier.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/jndi/JndiHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/type/PrimitiveWrapperHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/BaseXMLEventReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/BufferedXMLEventReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/DTDEntityResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/ErrorLogger.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/FilteringXMLEventReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/LocalXmlResourceResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/MappingReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/Origin.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/OriginImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/UnsupportedOrmXsdVersionException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/XMLHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/XMLStreamConstantsUtils.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/XmlDocument.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/XmlDocumentImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/internal/util/xml/XmlInfrastructureException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/jmx/internal/DisabledJmxServiceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/jmx/internal/JmxServiceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/jmx/internal/JmxServiceInitiator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/jmx/spi/JmxService.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/AbstractEntityJoinWalker.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/AbstractEntityJoinWalker.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/AbstractEntityJoinWalker.java 17 Aug 2012 14:33:59 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/AbstractEntityJoinWalker.java 30 Jul 2014 16:16:42 -0000 1.1.2.1 @@ -25,20 +25,22 @@ package org.hibernate.loader; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import java.util.Map; import org.hibernate.FetchMode; -import org.hibernate.LockMode; +import org.hibernate.LockOptions; import org.hibernate.MappingException; -import org.hibernate.engine.CascadeStyle; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.profile.Fetch; +import org.hibernate.engine.profile.FetchProfile; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.persister.entity.Loadable; import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.sql.JoinFragment; import org.hibernate.sql.Select; import org.hibernate.type.AssociationType; -import org.hibernate.util.CollectionHelper; /** * Abstract walker for walkers which begin at an entity (criteria @@ -51,79 +53,82 @@ private final OuterJoinLoadable persister; private final String alias; - public AbstractEntityJoinWalker(OuterJoinLoadable persister, SessionFactoryImplementor factory, Map enabledFilters) { - this( persister, factory, enabledFilters, null ); + public AbstractEntityJoinWalker( + OuterJoinLoadable persister, + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) { + this( persister, factory, loadQueryInfluencers, null ); } - public AbstractEntityJoinWalker(OuterJoinLoadable persister, SessionFactoryImplementor factory, Map enabledFilters, String alias) { - super( factory, enabledFilters ); + public AbstractEntityJoinWalker( + OuterJoinLoadable persister, + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers, + String alias) { + super( factory, loadQueryInfluencers ); this.persister = persister; this.alias = ( alias == null ) ? generateRootAlias( persister.getEntityName() ) : alias; } protected final void initAll( - final String whereString, - final String orderByString, - final LockMode lockMode) - throws MappingException { + final String whereString, + final String orderByString, + final LockOptions lockOptions) throws MappingException { + initAll( whereString, orderByString, lockOptions, AssociationInitCallback.NO_CALLBACK ); + } + + protected final void initAll( + final String whereString, + final String orderByString, + final LockOptions lockOptions, + final AssociationInitCallback callback) throws MappingException { walkEntityTree( persister, getAlias() ); List allAssociations = new ArrayList(); - allAssociations.addAll(associations); - allAssociations.add( new OuterJoinableAssociation( - persister.getEntityType(), - null, - null, - alias, - JoinFragment.LEFT_OUTER_JOIN, - getFactory(), - CollectionHelper.EMPTY_MAP - ) ); - - initPersisters(allAssociations, lockMode); - initStatementString( whereString, orderByString, lockMode); + allAssociations.addAll( associations ); + allAssociations.add( OuterJoinableAssociation.createRoot( persister.getEntityType(), alias, getFactory() ) ); + initPersisters( allAssociations, lockOptions, callback ); + initStatementString( whereString, orderByString, lockOptions ); } protected final void initProjection( - final String projectionString, - final String whereString, - final String orderByString, - final String groupByString, - final LockMode lockMode) - throws MappingException { + final String projectionString, + final String whereString, + final String orderByString, + final String groupByString, + final LockOptions lockOptions) throws MappingException { walkEntityTree( persister, getAlias() ); persisters = new Loadable[0]; - initStatementString(projectionString, whereString, orderByString, groupByString, lockMode); + initStatementString(projectionString, whereString, orderByString, groupByString, lockOptions); } private void initStatementString( - final String condition, - final String orderBy, - final LockMode lockMode) - throws MappingException { - initStatementString(null, condition, orderBy, "", lockMode); + final String condition, + final String orderBy, + final LockOptions lockOptions) throws MappingException { + initStatementString(null, condition, orderBy, "", lockOptions); } private void initStatementString( final String projection, final String condition, final String orderBy, final String groupBy, - final LockMode lockMode) throws MappingException { + final LockOptions lockOptions) throws MappingException { final int joins = countEntityPersisters( associations ); suffixes = BasicLoader.generateSuffixes( joins + 1 ); JoinFragment ojf = mergeOuterJoins( associations ); Select select = new Select( getDialect() ) - .setLockMode( lockMode ) + .setLockOptions( lockOptions ) .setSelectClause( projection == null ? persister.selectFragment( alias, suffixes[joins] ) + selectString( associations ) : projection ) .setFromClause( - getDialect().appendLockHint( lockMode, persister.fromTableFragment( alias ) ) + + getDialect().appendLockHint( lockOptions, persister.fromTableFragment( alias ) ) + persister.fromJoinFragment( alias, true, true ) ) .setWhereClause( condition ) @@ -149,18 +154,65 @@ * The superclass deliberately excludes collections */ protected boolean isJoinedFetchEnabled(AssociationType type, FetchMode config, CascadeStyle cascadeStyle) { - return isJoinedFetchEnabledInMapping(config, type); + return isJoinedFetchEnabledInMapping( config, type ); } + protected final boolean isJoinFetchEnabledByProfile(OuterJoinLoadable persister, PropertyPath path, int propertyNumber) { + if ( !getLoadQueryInfluencers().hasEnabledFetchProfiles() ) { + // perf optimization + return false; + } + + // ugh, this stuff has to be made easier... + final String fullPath = path.getFullPath(); + String rootPropertyName = persister.getSubclassPropertyName( propertyNumber ); + int pos = fullPath.lastIndexOf( rootPropertyName ); + String relativePropertyPath = pos >= 0 + ? fullPath.substring( pos ) + : rootPropertyName; + String fetchRole = persister.getEntityName() + "." + relativePropertyPath; + + for ( String profileName : getLoadQueryInfluencers().getEnabledFetchProfileNames() ) { + final FetchProfile profile = getFactory().getFetchProfile( profileName ); + final Fetch fetch = profile.getFetchByRole( fetchRole ); + if ( fetch != null && Fetch.Style.JOIN == fetch.getStyle() ) { + return true; + } + } + return false; + } + public abstract String getComment(); - protected final Loadable getPersister() { + @Override + protected boolean isDuplicateAssociation(final String foreignKeyTable, final String[] foreignKeyColumns) { + //disable a join back to this same association + final boolean isSameJoin = + persister.getTableName().equals( foreignKeyTable ) && + Arrays.equals( foreignKeyColumns, persister.getKeyColumnNames() ); + return isSameJoin || + super.isDuplicateAssociation(foreignKeyTable, foreignKeyColumns); + } + + + + public final Loadable getPersister() { return persister; } - protected final String getAlias() { + public final String getAlias() { return alias; } + + /** + * For entities, orderings added by, for example, Criteria#addOrder need to come before the associations' @OrderBy + * values. However, other sub-classes of JoinWalker (BasicCollectionJoinWalker, OneToManyJoinWalker, etc.) + * still need the other way around. So, override here instead. See HHH-7116. + */ + @Override + protected String orderBy(final List associations, final String orderBy) { + return mergeOrderings( orderBy, orderBy( associations ) ); + } public String toString() { return getClass().getName() + '(' + getPersister().getEntityName() + ')'; Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/BasicLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/BasicLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/BasicLoader.java 17 Aug 2012 14:33:59 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/BasicLoader.java 30 Jul 2014 16:16:43 -0000 1.1.2.1 @@ -23,12 +23,13 @@ * */ package org.hibernate.loader; +import java.util.ArrayList; +import java.util.List; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.persister.entity.Loadable; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.Loadable; import org.hibernate.type.BagType; -import org.hibernate.HibernateException; /** * Uses the default mapping from property to result set column @@ -68,13 +69,16 @@ } CollectionPersister[] collectionPersisters = getCollectionPersisters(); - int bagCount = 0; + List bagRoles = null; if ( collectionPersisters != null ) { String[] collectionSuffixes = getCollectionSuffixes(); collectionDescriptors = new CollectionAliases[collectionPersisters.length]; for ( int i = 0; i < collectionPersisters.length; i++ ) { if ( isBag( collectionPersisters[i] ) ) { - bagCount++; + if ( bagRoles == null ) { + bagRoles = new ArrayList(); + } + bagRoles.add( collectionPersisters[i].getRole() ); } collectionDescriptors[i] = new GeneratedCollectionAliases( collectionPersisters[i], @@ -85,8 +89,8 @@ else { collectionDescriptors = null; } - if ( bagCount > 1 ) { - throw new HibernateException( "cannot simultaneously fetch multiple bags" ); + if ( bagRoles != null && bagRoles.size() > 1 ) { + throw new MultipleBagFetchException( bagRoles ); } } @@ -98,6 +102,10 @@ * Utility method that generates 0_, 1_ suffixes. Subclasses don't * necessarily need to use this algorithm, but it is intended that * they will in most cases. + * + * @param length The number of suffixes to generate + * + * @return The array of generated suffixes (with length=length). */ public static String[] generateSuffixes(int length) { return generateSuffixes( 0, length ); Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/BatchFetchStyle.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/CollectionAliases.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/CollectionAliases.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/CollectionAliases.java 17 Aug 2012 14:33:59 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/CollectionAliases.java 30 Jul 2014 16:16:42 -0000 1.1.2.1 @@ -24,6 +24,7 @@ */ package org.hibernate.loader; + /** * Type definition of CollectionAliases. * Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/ColumnEntityAliases.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/ColumnEntityAliases.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/ColumnEntityAliases.java 17 Aug 2012 14:33:59 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/ColumnEntityAliases.java 30 Jul 2014 16:16:43 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,24 +20,27 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.loader; - import java.util.Map; import org.hibernate.persister.entity.Loadable; /** - * EntityAliases that chooses the column names over the alias names. + * EntityAliases that chooses the column names over the alias names. This strategy is used + * when the result-set mapping did not give specific aliases to use in extracting from the + * result set. We use the column names from the underlying persister. * * @author max - * + * @author Steve Ebersole */ public class ColumnEntityAliases extends DefaultEntityAliases { - public ColumnEntityAliases(Map returnProperties, Loadable persister, String suffix) { - super(returnProperties, persister, suffix); + public ColumnEntityAliases( + Map returnProperties, + Loadable persister, + String suffix) { + super( returnProperties, persister, suffix ); } protected String[] getIdentifierAliases(Loadable persister, String suffix) { @@ -51,6 +54,4 @@ protected String[] getPropertyAliases(Loadable persister, int j) { return persister.getPropertyColumnNames(j); } - - } Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/DefaultEntityAliases.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/DefaultEntityAliases.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/DefaultEntityAliases.java 17 Aug 2012 14:33:59 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/DefaultEntityAliases.java 30 Jul 2014 16:16:43 -0000 1.1.2.1 @@ -24,14 +24,15 @@ */ package org.hibernate.loader; +import java.util.Collections; import java.util.Map; +import org.hibernate.internal.util.StringHelper; import org.hibernate.persister.entity.Loadable; -import org.hibernate.util.CollectionHelper; /** * EntityAliases which handles the logic of selecting user provided aliases (via return-property), - * before using the default aliases. + * before using the default aliases. * * @author max * @@ -44,66 +45,82 @@ private final String suffixedDiscriminatorColumn; private final String suffix; private final String rowIdAlias; - private final Map userProvidedAliases; + private final Map userProvidedAliases; - public DefaultEntityAliases(Loadable persister, String suffix) { - this(CollectionHelper.EMPTY_MAP, persister, suffix); - } - /** - * Calculate and cache select-clause suffixes. - * @param map + * Calculate and cache select-clause aliases + * + * @param userProvidedAliases The explicit aliases provided in a result-set mapping. + * @param persister The persister for which we are generating select aliases + * @param suffix The calculated suffix. */ - public DefaultEntityAliases(Map userProvidedAliases, Loadable persister, String suffix) { + public DefaultEntityAliases( + Map userProvidedAliases, + Loadable persister, + String suffix) { this.suffix = suffix; this.userProvidedAliases = userProvidedAliases; - - String[] keyColumnsCandidates = getUserProvidedAliases( - persister.getIdentifierPropertyName(), - (String[]) null - ); - if (keyColumnsCandidates==null) { - suffixedKeyColumns = getUserProvidedAliases( - "id", + + suffixedKeyColumns = determineKeyAlias( persister, suffix ); + suffixedPropertyColumns = determinePropertyAliases( persister ); + suffixedDiscriminatorColumn = determineDiscriminatorAlias( persister, suffix ); + suffixedVersionColumn = determineVersionAlias( persister ); + rowIdAlias = Loadable.ROWID_ALIAS + suffix; // TODO: not visible to the user! + } + + public DefaultEntityAliases(Loadable persister, String suffix) { + this( Collections.EMPTY_MAP, persister, suffix ); + } + + private String[] determineKeyAlias(Loadable persister, String suffix) { + final String[] aliases; + final String[] keyColumnsCandidates = getUserProvidedAliases( persister.getIdentifierPropertyName(), null ); + if ( keyColumnsCandidates == null ) { + aliases = getUserProvidedAliases( + "id", getIdentifierAliases(persister, suffix) - ); - } - else { - suffixedKeyColumns = keyColumnsCandidates; - } - intern(suffixedKeyColumns); - - suffixedPropertyColumns = getSuffixedPropertyAliases(persister); - suffixedDiscriminatorColumn = getUserProvidedAlias( - "class", - getDiscriminatorAlias(persister, suffix) ); - if ( persister.isVersioned() ) { - suffixedVersionColumn = suffixedPropertyColumns[ persister.getVersionProperty() ]; } else { - suffixedVersionColumn = null; + aliases = keyColumnsCandidates; } - rowIdAlias = Loadable.ROWID_ALIAS + suffix; // TODO: not visible to the user! + final String[] rtn = StringHelper.unquote( aliases, persister.getFactory().getDialect() ); + intern( rtn ); + return rtn; } + private String[][] determinePropertyAliases(Loadable persister) { + return getSuffixedPropertyAliases( persister ); + } + + private String determineDiscriminatorAlias(Loadable persister, String suffix) { + String alias = getUserProvidedAlias( "class", getDiscriminatorAlias( persister, suffix ) ); + return StringHelper.unquote( alias, persister.getFactory().getDialect() ); + } + + private String[] determineVersionAlias(Loadable persister) { + return persister.isVersioned() + ? suffixedPropertyColumns[ persister.getVersionProperty() ] + : null; + } + protected String getDiscriminatorAlias(Loadable persister, String suffix) { return persister.getDiscriminatorAlias(suffix); } protected String[] getIdentifierAliases(Loadable persister, String suffix) { return persister.getIdentifierAliases(suffix); } - + protected String[] getPropertyAliases(Loadable persister, int j) { return persister.getPropertyAliases(suffix, j); } - + private String[] getUserProvidedAliases(String propertyPath, String[] defaultAliases) { String[] result = (String[]) userProvidedAliases.get(propertyPath); if (result==null) { - return defaultAliases; - } + return defaultAliases; + } else { return result; } @@ -113,49 +130,60 @@ String[] columns = (String[]) userProvidedAliases.get(propertyPath); if (columns==null) { return defaultAlias; - } + } else { return columns[0]; } } - + + @Override public String[][] getSuffixedPropertyAliases(Loadable persister) { - int size = persister.getPropertyNames().length; - String[][] suffixedPropertyAliases = new String[size][]; + final int size = persister.getPropertyNames().length; + final String[][] suffixedPropertyAliases = new String[size][]; for ( int j = 0; j < size; j++ ) { suffixedPropertyAliases[j] = getUserProvidedAliases( persister.getPropertyNames()[j], - getPropertyAliases(persister, j) - ); + getPropertyAliases( persister, j ) + ); + suffixedPropertyAliases[j] = StringHelper.unquote( suffixedPropertyAliases[j], persister.getFactory().getDialect() ); intern( suffixedPropertyAliases[j] ); - } + } return suffixedPropertyAliases; } + @Override public String[] getSuffixedVersionAliases() { return suffixedVersionColumn; } + @Override public String[][] getSuffixedPropertyAliases() { return suffixedPropertyColumns; } + @Override public String getSuffixedDiscriminatorAlias() { return suffixedDiscriminatorColumn; } + @Override public String[] getSuffixedKeyAliases() { return suffixedKeyColumns; } + @Override public String getRowIdAlias() { return rowIdAlias; } - + + @Override + public String getSuffix() { + return suffix; + } + private static void intern(String[] strings) { for (int i=0; i=0) { + final AssociationType type, + final String[] aliasedLhsColumns, + final String alias, + final PropertyPath path, + int currentDepth, + final JoinType joinType) throws MappingException { + if ( joinType != JoinType.NONE ) { addAssociationToJoinTree( type, aliasedLhsColumns, alias, path, currentDepth, joinType - ); + ); } + } + protected boolean hasRestriction(PropertyPath path) { + return false; } + protected String getWithClause(PropertyPath path) { + return ""; + } + /** * Add on association (one-to-one, many-to-one, or a collection) to a list * of associations to be fetched by outerjoin */ private void addAssociationToJoinTree( - final AssociationType type, - final String[] aliasedLhsColumns, - final String alias, - final String path, - final int currentDepth, - final int joinType) - throws MappingException { + final AssociationType type, + final String[] aliasedLhsColumns, + final String alias, + final PropertyPath path, + final int currentDepth, + final JoinType joinType) throws MappingException { Joinable joinable = type.getAssociatedJoinable( getFactory() ); - String subalias = generateTableAlias( - associations.size()+1, //before adding to collection! - path, - joinable - ); + // important to generate alias based on size of association collection + // *before* adding this join to that collection + String subalias = generateTableAlias( associations.size() + 1, path, joinable ); + // NOTE : it should be fine to continue to pass only filters below + // (instead of LoadQueryInfluencers) since "from that point on" we + // only need to worry about restrictions (and not say adding more + // joins) OuterJoinableAssociation assoc = new OuterJoinableAssociation( + path, type, alias, aliasedLhsColumns, subalias, joinType, - getFactory(), - enabledFilters - ); - assoc.validateJoin(path); - associations.add(assoc); + getWithClause(path), + hasRestriction( path ), + getFactory(), + loadQueryInfluencers.getEnabledFilters() + ); + assoc.validateJoin( path.getFullPath() ); + associations.add( assoc ); - int nextDepth = currentDepth+1; + int nextDepth = currentDepth + 1; +// path = ""; if ( !joinable.isCollection() ) { if (joinable instanceof OuterJoinLoadable) { walkEntityTree( @@ -263,31 +282,37 @@ } /** - * For an entity class, return a list of associations to be fetched by outerjoin + * Walk the association tree for an entity, adding associations which should + * be join fetched to the {@link #associations} inst var. This form is the + * entry point into the walking for a given entity, starting the recursive + * calls into {@link #walkEntityTree(org.hibernate.persister.entity.OuterJoinLoadable, String, PropertyPath ,int)}. + * + * @param persister The persister representing the entity to be walked. + * @param alias The (root) alias to use for this entity/persister. + * @throws org.hibernate.MappingException ??? */ - protected final void walkEntityTree(OuterJoinLoadable persister, String alias) - throws MappingException { - walkEntityTree(persister, alias, "", 0); + protected final void walkEntityTree( + OuterJoinLoadable persister, + String alias) throws MappingException { + walkEntityTree( persister, alias, new PropertyPath(), 0 ); } /** * For a collection role, return a list of associations to be fetched by outerjoin */ - protected final void walkCollectionTree(QueryableCollection persister, String alias) - throws MappingException { - walkCollectionTree(persister, alias, "", 0); + protected final void walkCollectionTree(QueryableCollection persister, String alias) throws MappingException { + walkCollectionTree( persister, alias, new PropertyPath(), 0 ); //TODO: when this is the entry point, we should use an INNER_JOIN for fetching the many-to-many elements! } /** * For a collection role, return a list of associations to be fetched by outerjoin */ private void walkCollectionTree( - final QueryableCollection persister, - final String alias, - final String path, - final int currentDepth) - throws MappingException { + final QueryableCollection persister, + final String alias, + final PropertyPath path, + final int currentDepth) throws MappingException { if ( persister.isOneToMany() ) { walkEntityTree( @@ -310,7 +335,7 @@ // many-to-many collection itself. Here, it is alright to use // an inner join... boolean useInnerJoin = currentDepth == 0; - final int joinType = getJoinType( + final JoinType joinType = getJoinType( associationType, persister.getFetchMode(), path, @@ -319,7 +344,7 @@ !useInnerJoin, currentDepth - 1, null //operations which cascade as far as the collection also cascade to collection elements - ); + ); addAssociationToJoinTreeIfNecessary( associationType, aliasedLhsColumns, @@ -331,7 +356,7 @@ } else if ( type.isComponentType() ) { walkCompositeElementTree( - (AbstractComponentType) type, + (CompositeType) type, persister.getElementColumnNames(), persister, alias, @@ -344,66 +369,160 @@ } /** - * Walk the tree for a particular entity association + * Process a particular association owned by the entity + * + * @param associationType The type representing the association to be + * processed. + * @param persister The owner of the association to be processed. + * @param propertyNumber The property number for the association + * (relative to the persister). + * @param alias The entity alias + * @param path The path to the association + * @param nullable is the association nullable (which I think is supposed + * to indicate inner/outer join semantics). + * @param currentDepth The current join depth + * @throws org.hibernate.MappingException ??? */ - private final void walkEntityAssociationTree( - final AssociationType associationType, - final OuterJoinLoadable persister, - final int propertyNumber, - final String alias, - final String path, - final boolean nullable, - final int currentDepth) - throws MappingException { - + private void walkEntityAssociationTree( + final AssociationType associationType, + final OuterJoinLoadable persister, + final int propertyNumber, + final String alias, + final PropertyPath path, + final boolean nullable, + final int currentDepth) throws MappingException { String[] aliasedLhsColumns = JoinHelper.getAliasedLHSColumnNames( associationType, alias, propertyNumber, persister, getFactory() - ); - + ); String[] lhsColumns = JoinHelper.getLHSColumnNames( associationType, propertyNumber, persister, getFactory() - ); + ); String lhsTable = JoinHelper.getLHSTableName(associationType, propertyNumber, persister); - String subpath = subPath( path, persister.getSubclassPropertyName(propertyNumber) ); - int joinType = getJoinType( + PropertyPath subPath = path.append( persister.getSubclassPropertyName(propertyNumber) ); + JoinType joinType = getJoinType( + persister, + subPath, + propertyNumber, associationType, - persister.getFetchMode(propertyNumber), - subpath, + persister.getFetchMode( propertyNumber ), + persister.getCascadeStyle( propertyNumber ), lhsTable, lhsColumns, nullable, - currentDepth, - persister.getCascadeStyle(propertyNumber) - ); + currentDepth + ); addAssociationToJoinTreeIfNecessary( associationType, aliasedLhsColumns, alias, - subpath, + subPath, currentDepth, joinType - ); + ); + } + /** + * Determine the appropriate type of join (if any) to use to fetch the + * given association. + * + * @param persister The owner of the association. + * @param path The path to the association + * @param propertyNumber The property number representing the association. + * @param associationType The association type. + * @param metadataFetchMode The metadata-defined fetch mode. + * @param metadataCascadeStyle The metadata-defined cascade style. + * @param lhsTable The owner table + * @param lhsColumns The owner join columns + * @param nullable Is the association nullable. + * @param currentDepth Current join depth + * @return type of join to use ({@link org.hibernate.sql.JoinType#INNER_JOIN}, + * {@link org.hibernate.sql.JoinType#LEFT_OUTER_JOIN}, or -1 to indicate no joining. + * @throws MappingException ?? + */ + protected JoinType getJoinType( + OuterJoinLoadable persister, + final PropertyPath path, + int propertyNumber, + AssociationType associationType, + FetchMode metadataFetchMode, + CascadeStyle metadataCascadeStyle, + String lhsTable, + String[] lhsColumns, + final boolean nullable, + final int currentDepth) throws MappingException { + return getJoinType( + associationType, + metadataFetchMode, + path, + lhsTable, + lhsColumns, + nullable, + currentDepth, + metadataCascadeStyle + ); } /** - * For an entity class, add to a list of associations to be fetched - * by outerjoin + * Determine the appropriate associationType of join (if any) to use to fetch the + * given association. + * + * @param associationType The association associationType. + * @param config The metadata-defined fetch mode. + * @param path The path to the association + * @param lhsTable The owner table + * @param lhsColumns The owner join columns + * @param nullable Is the association nullable. + * @param currentDepth Current join depth + * @param cascadeStyle The metadata-defined cascade style. + * @return type of join to use ({@link org.hibernate.sql.JoinType#INNER_JOIN}, + * {@link org.hibernate.sql.JoinType#LEFT_OUTER_JOIN}, or -1 to indicate no joining. + * @throws MappingException ?? */ - private final void walkEntityTree( - final OuterJoinLoadable persister, - final String alias, - final String path, - final int currentDepth) - throws MappingException { + protected JoinType getJoinType( + AssociationType associationType, + FetchMode config, + PropertyPath path, + String lhsTable, + String[] lhsColumns, + boolean nullable, + int currentDepth, + CascadeStyle cascadeStyle) throws MappingException { + if ( !isJoinedFetchEnabled( associationType, config, cascadeStyle ) ) { + return JoinType.NONE; + } + if ( isTooDeep(currentDepth) || ( associationType.isCollectionType() && isTooManyCollections() ) ) { + return JoinType.NONE; + } + if ( isDuplicateAssociation( lhsTable, lhsColumns, associationType ) ) { + return JoinType.NONE; + } + return getJoinType( nullable, currentDepth ); + } + /** + * Walk the association tree for an entity, adding associations which should + * be join fetched to the {@link #associations} inst var. This form is the + * entry point into the walking for a given entity, starting the recursive + * calls into {@link #walkEntityTree(org.hibernate.persister.entity.OuterJoinLoadable, String, PropertyPath ,int)}. + * + * @param persister The persister representing the entity to be walked. + * @param alias The (root) alias to use for this entity/persister. + * @param path The property path to the entity being walked + * @param currentDepth The current join depth + * @throws org.hibernate.MappingException ??? + */ + private void walkEntityTree( + final OuterJoinLoadable persister, + final String alias, + final PropertyPath path, + final int currentDepth) throws MappingException { int n = persister.countSubclassProperties(); - for ( int i=0; i= maxFetchDepth.intValue(); + return maxFetchDepth!=null && currentDepth >= maxFetchDepth; } protected boolean isTooManyCollections() { @@ -651,11 +768,7 @@ return type.isEntityType() && isJoinedFetchEnabledInMapping(config, type) ; } - protected String generateTableAlias( - final int n, - final String path, - final Joinable joinable - ) { + protected String generateTableAlias(final int n, final PropertyPath path, final Joinable joinable) { return StringHelper.generateAlias( joinable.getName(), n ); } @@ -667,10 +780,7 @@ * Used to detect circularities in the joined graph, note that * this method is side-effecty */ - protected boolean isDuplicateAssociation( - final String foreignKeyTable, - final String[] foreignKeyColumns - ) { + protected boolean isDuplicateAssociation(final String foreignKeyTable, final String[] foreignKeyColumns) { AssociationKey associationKey = new AssociationKey(foreignKeyColumns, foreignKeyTable); return !visitedAssociationKeys.add( associationKey ); } @@ -679,11 +789,7 @@ * Used to detect circularities in the joined graph, note that * this method is side-effecty */ - protected boolean isDuplicateAssociation( - final String lhsTable, - final String[] lhsColumnNames, - final AssociationType type - ) { + protected boolean isDuplicateAssociation(final String lhsTable, final String[] lhsColumnNames, final AssociationType type) { final String foreignKeyTable; final String[] foreignKeyColumns; if ( type.getForeignKeyDirection()==ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT ) { @@ -708,11 +814,13 @@ this.columns = columns; this.table = table; } - public boolean equals(Object other) { + @Override + public boolean equals(Object other) { AssociationKey that = (AssociationKey) other; return that.table.equals(table) && Arrays.equals(columns, that.columns); } - public int hashCode() { + @Override + public int hashCode() { return table.hashCode(); //TODO: inefficient } } @@ -721,20 +829,23 @@ * Should we join this association? */ protected boolean isJoinable( - final int joinType, - final Set visitedAssociationKeys, - final String lhsTable, - final String[] lhsColumnNames, - final AssociationType type, - final int depth - ) { - if (joinType<0) return false; + final JoinType joinType, + final Set visitedAssociationKeys, + final String lhsTable, + final String[] lhsColumnNames, + final AssociationType type, + final int depth) { + + if ( joinType == JoinType.NONE ) { + return false; + } - if (joinType==JoinFragment.INNER_JOIN) return true; - + if ( joinType == JoinType.INNER_JOIN ) { + return true; + } + Integer maxFetchDepth = getFactory().getSettings().getMaximumFetchDepth(); - final boolean tooDeep = maxFetchDepth!=null && - depth >= maxFetchDepth.intValue(); + final boolean tooDeep = maxFetchDepth!=null && depth >= maxFetchDepth; return !tooDeep && !isDuplicateAssociation(lhsTable, lhsColumnNames, type); } @@ -805,7 +916,9 @@ Iterator iter = associations.iterator(); while ( iter.hasNext() ) { OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next(); - if ( oj.getJoinType()==JoinFragment.LEFT_OUTER_JOIN && oj.getJoinable().isCollection() ) { + if ( oj.getJoinType()==JoinType.LEFT_OUTER_JOIN && + oj.getJoinable().isCollection() && + ! oj.hasRestriction() ) { result++; } } @@ -817,12 +930,12 @@ */ protected static final String orderBy(List associations) throws MappingException { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); Iterator iter = associations.iterator(); OuterJoinableAssociation last = null; while ( iter.hasNext() ) { OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next(); - if ( oj.getJoinType() == JoinFragment.LEFT_OUTER_JOIN ) { // why does this matter? + if ( oj.getJoinType() == JoinType.LEFT_OUTER_JOIN ) { // why does this matter? if ( oj.getJoinable().isCollection() ) { final QueryableCollection queryableCollection = (QueryableCollection) oj.getJoinable(); if ( queryableCollection.hasOrdering() ) { @@ -849,25 +962,25 @@ if ( buf.length()>0 ) buf.setLength( buf.length()-2 ); return buf.toString(); } - + /** * Render the where condition for a (batch) load by identifier / collection key */ - protected StringBuffer whereString(String alias, String[] columnNames, int batchSize) { + protected StringBuilder whereString(String alias, String[] columnNames, int batchSize) { if ( columnNames.length==1 ) { // if not a composite key, use "foo in (?, ?, ?)" for batching // if no batch, and not a composite key, use "foo = ?" InFragment in = new InFragment().setColumn( alias, columnNames[0] ); for ( int i=0; i0 - ) { - buf.append(", "); + if (selectFragment.trim().length() > 0) { + buf.append(", ").append(selectFragment); } + if ( joinable.consumesEntityAlias() ) entityAliasCount++; + if ( joinable.consumesCollectionAlias() && join.getJoinType()==JoinType.LEFT_OUTER_JOIN ) collectionAliasCount++; } return buf.toString(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/Loader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/Loader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/Loader.java 17 Aug 2012 14:33:59 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/Loader.java 30 Jul 2014 16:16:42 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.loader; @@ -29,62 +28,75 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.LockMode; +import org.hibernate.LockOptions; import org.hibernate.QueryException; import org.hibernate.ScrollMode; import org.hibernate.ScrollableResults; +import org.hibernate.Session; import org.hibernate.StaleObjectStateException; import org.hibernate.WrongClassException; -import org.hibernate.cache.FilterKey; -import org.hibernate.cache.QueryCache; -import org.hibernate.cache.QueryKey; -import org.hibernate.collection.PersistentCollection; +import org.hibernate.cache.spi.FilterKey; +import org.hibernate.cache.spi.QueryCache; +import org.hibernate.cache.spi.QueryKey; +import org.hibernate.cache.spi.entry.CacheEntry; +import org.hibernate.cache.spi.entry.ReferenceCacheEntryImpl; +import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.EntityKey; -import org.hibernate.engine.EntityUniqueKey; -import org.hibernate.engine.PersistenceContext; -import org.hibernate.engine.QueryParameters; -import org.hibernate.engine.RowSelection; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.engine.SubselectFetch; -import org.hibernate.engine.TwoPhaseLoad; -import org.hibernate.engine.TypedValue; -import org.hibernate.event.EventSource; -import org.hibernate.event.PostLoadEvent; -import org.hibernate.event.PreLoadEvent; -import org.hibernate.exception.JDBCExceptionHelper; -import org.hibernate.hql.HolderInstantiator; -import org.hibernate.impl.FetchingScrollableResultsImpl; -import org.hibernate.impl.ScrollableResultsImpl; -import org.hibernate.jdbc.ColumnNameCache; -import org.hibernate.jdbc.ResultSetWrapper; +import org.hibernate.dialect.pagination.LimitHandler; +import org.hibernate.dialect.pagination.LimitHelper; +import org.hibernate.dialect.pagination.NoopLimitHandler; +import org.hibernate.engine.internal.CacheHelper; +import org.hibernate.engine.internal.TwoPhaseLoad; +import org.hibernate.engine.jdbc.ColumnNameCache; +import org.hibernate.engine.spi.EntityEntry; +import org.hibernate.engine.spi.EntityKey; +import org.hibernate.engine.spi.EntityUniqueKey; +import org.hibernate.engine.spi.PersistenceContext; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.RowSelection; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.engine.spi.SubselectFetch; +import org.hibernate.engine.spi.TypedValue; +import org.hibernate.event.spi.EventSource; +import org.hibernate.event.spi.PostLoadEvent; +import org.hibernate.event.spi.PreLoadEvent; +import org.hibernate.hql.internal.HolderInstantiator; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.FetchingScrollableResultsImpl; +import org.hibernate.internal.ScrollableResultsImpl; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.collections.CollectionHelper; +import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Loadable; import org.hibernate.persister.entity.UniqueKeyLoadable; import org.hibernate.pretty.MessageHelper; import org.hibernate.proxy.HibernateProxy; +import org.hibernate.transform.CacheableResultTransformer; import org.hibernate.transform.ResultTransformer; import org.hibernate.type.AssociationType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; import org.hibernate.type.VersionType; -import org.hibernate.util.StringHelper; +import org.jboss.logging.Logger; + /** * Abstract superclass of object loading (and querying) strategies. This class implements * useful common functionality that concrete loaders delegate to. It is not intended that this @@ -101,21 +113,24 @@ */ public abstract class Loader { - private static final Logger log = LoggerFactory.getLogger( Loader.class ); - + protected static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, Loader.class.getName()); + protected static final boolean DEBUG_ENABLED = LOG.isDebugEnabled(); private final SessionFactoryImplementor factory; - private ColumnNameCache columnNameCache; + private volatile ColumnNameCache columnNameCache; + private final boolean referenceCachingEnabled; + public Loader(SessionFactoryImplementor factory) { this.factory = factory; + this.referenceCachingEnabled = factory.getSettings().isDirectReferenceCacheEntriesEnabled(); } /** * The SQL query string to be called; implemented by all subclasses * * @return The sql command this loader should use to get its {@link ResultSet}. */ - protected abstract String getSQLString(); + public abstract String getSQLString(); /** * An array of persisters of entity classes contained in each row of results; @@ -124,7 +139,7 @@ * @return The entity persisters. */ protected abstract Loadable[] getEntityPersisters(); - + /** * An array indicating whether the entities have eager property fetching * enabled. @@ -158,7 +173,7 @@ } /** - * An (optional) persister for a collection to be initialized; only + * An (optional) persister for a collection to be initialized; only * collection loaders return a non-null value */ protected CollectionPersister[] getCollectionPersisters() { @@ -174,19 +189,28 @@ return null; } + protected int[][] getCompositeKeyManyToOneTargetIndices() { + return null; + } + /** - * What lock mode does this load entities with? + * What lock options does this load entities with? * - * @param lockModes a collection of lock modes specified dynamically via the Query interface + * @param lockOptions a collection of lock options specified dynamically via the Query interface */ - protected abstract LockMode[] getLockModes(Map lockModes); + //protected abstract LockOptions[] getLockOptions(Map lockOptions); + protected abstract LockMode[] getLockModes(LockOptions lockOptions); /** * Append FOR UPDATE OF clause, if necessary. This * empty superclass implementation merely returns its first * argument. */ - protected String applyLocks(String sql, Map lockModes, Dialect dialect) throws HibernateException { + protected String applyLocks( + String sql, + QueryParameters parameters, + Dialect dialect, + List afterLoadActions) throws HibernateException { return sql; } @@ -218,22 +242,68 @@ /** * Modify the SQL, adding lock hints and comments, if necessary */ - protected String preprocessSQL(String sql, QueryParameters parameters, Dialect dialect) - throws HibernateException { + protected String preprocessSQL( + String sql, + QueryParameters parameters, + Dialect dialect, + List afterLoadActions) throws HibernateException { + sql = applyLocks( sql, parameters, dialect, afterLoadActions ); - sql = applyLocks( sql, parameters.getLockModes(), dialect ); + // Keep this here, rather than moving to Select. Some Dialects may need the hint to be appended to the very + // end or beginning of the finalized SQL statement, so wait until everything is processed. + if ( parameters.getQueryHints() != null && parameters.getQueryHints().size() > 0 ) { + sql = dialect.getQueryHintString( sql, parameters.getQueryHints() ); + } - return getFactory().getSettings().isCommentsEnabled() ? - prependComment( sql, parameters ) : sql; + return getFactory().getSettings().isCommentsEnabled() + ? prependComment( sql, parameters ) + : sql; } + protected boolean shouldUseFollowOnLocking( + QueryParameters parameters, + Dialect dialect, + List afterLoadActions) { + if ( dialect.useFollowOnLocking() ) { + // currently only one lock mode is allowed in follow-on locking + final LockMode lockMode = determineFollowOnLockMode( parameters.getLockOptions() ); + final LockOptions lockOptions = new LockOptions( lockMode ); + if ( lockOptions.getLockMode() != LockMode.UPGRADE_SKIPLOCKED ) { + LOG.usingFollowOnLocking(); + lockOptions.setTimeOut( parameters.getLockOptions().getTimeOut() ); + lockOptions.setScope( parameters.getLockOptions().getScope() ); + afterLoadActions.add( + new AfterLoadAction() { + @Override + public void afterLoad(SessionImplementor session, Object entity, Loadable persister) { + ( (Session) session ).buildLockRequest( lockOptions ).lock( persister.getEntityName(), entity ); + } + } + ); + parameters.setLockOptions( new LockOptions() ); + return true; + } + } + return false; + } + + protected LockMode determineFollowOnLockMode(LockOptions lockOptions) { + final LockMode lockModeToUse = lockOptions.findGreatestLockMode(); + + if ( lockOptions.hasAliasSpecificLockModes() ) { + LOG.aliasSpecificLockingWithFollowOnLocking( lockModeToUse ); + } + + return lockModeToUse; + } + private String prependComment(String sql, QueryParameters parameters) { String comment = parameters.getComment(); if ( comment == null ) { return sql; } else { - return new StringBuffer( comment.length() + sql.length() + 5 ) + return new StringBuilder( comment.length() + sql.length() + 5 ) .append( "/* " ) .append( comment ) .append( " */ " ) @@ -247,21 +317,51 @@ * persister from each row of the ResultSet. If an object is supplied, will attempt to * initialize that object. If a collection is supplied, attempt to initialize that collection. */ - private List doQueryAndInitializeNonLazyCollections(final SessionImplementor session, - final QueryParameters queryParameters, - final boolean returnProxies) - throws HibernateException, SQLException { + public List doQueryAndInitializeNonLazyCollections( + final SessionImplementor session, + final QueryParameters queryParameters, + final boolean returnProxies) throws HibernateException, SQLException { + return doQueryAndInitializeNonLazyCollections( + session, + queryParameters, + returnProxies, + null + ); + } + public List doQueryAndInitializeNonLazyCollections( + final SessionImplementor session, + final QueryParameters queryParameters, + final boolean returnProxies, + final ResultTransformer forcedResultTransformer) + throws HibernateException, SQLException { final PersistenceContext persistenceContext = session.getPersistenceContext(); + boolean defaultReadOnlyOrig = persistenceContext.isDefaultReadOnly(); + if ( queryParameters.isReadOnlyInitialized() ) { + // The read-only/modifiable mode for the query was explicitly set. + // Temporarily set the default read-only/modifiable setting to the query's setting. + persistenceContext.setDefaultReadOnly( queryParameters.isReadOnly() ); + } + else { + // The read-only/modifiable setting for the query was not initialized. + // Use the default read-only/modifiable from the persistence context instead. + queryParameters.setReadOnly( persistenceContext.isDefaultReadOnly() ); + } persistenceContext.beforeLoad(); List result; try { - result = doQuery( session, queryParameters, returnProxies ); + try { + result = doQuery( session, queryParameters, returnProxies, forcedResultTransformer ); + } + finally { + persistenceContext.afterLoad(); + } + persistenceContext.initializeNonLazyCollections(); } finally { - persistenceContext.afterLoad(); + // Restore the original default + persistenceContext.setDefaultReadOnly( defaultReadOnlyOrig ); } - persistenceContext.initializeNonLazyCollections(); return result; } @@ -277,56 +377,55 @@ * @throws HibernateException */ public Object loadSingleRow( - final ResultSet resultSet, - final SessionImplementor session, - final QueryParameters queryParameters, - final boolean returnProxies) throws HibernateException { + final ResultSet resultSet, + final SessionImplementor session, + final QueryParameters queryParameters, + final boolean returnProxies) throws HibernateException { final int entitySpan = getEntityPersisters().length; - final List hydratedObjects = entitySpan == 0 ? + final List hydratedObjects = entitySpan == 0 ? null : new ArrayList( entitySpan ); final Object result; try { result = getRowFromResultSet( - resultSet, + resultSet, session, queryParameters, - getLockModes( queryParameters.getLockModes() ), + getLockModes( queryParameters.getLockOptions() ), null, hydratedObjects, new EntityKey[entitySpan], returnProxies ); } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - factory.getSQLExceptionConverter(), - sqle, - "could not read next row of results", - getSQLString() + throw factory.getSQLExceptionHelper().convert( + sqle, + "could not read next row of results", + getSQLString() ); } - initializeEntitiesAndCollections( - hydratedObjects, - resultSet, - session, - queryParameters.isReadOnly() - ); + initializeEntitiesAndCollections( + hydratedObjects, + resultSet, + session, + queryParameters.isReadOnly( session ) + ); session.getPersistenceContext().initializeNonLazyCollections(); return result; } private Object sequentialLoad( - final ResultSet resultSet, - final SessionImplementor session, - final QueryParameters queryParameters, - final boolean returnProxies, - final EntityKey keyToRead) throws HibernateException { + final ResultSet resultSet, + final SessionImplementor session, + final QueryParameters queryParameters, + final boolean returnProxies, + final EntityKey keyToRead) throws HibernateException { final int entitySpan = getEntityPersisters().length; - final List hydratedObjects = entitySpan == 0 ? + final List hydratedObjects = entitySpan == 0 ? null : new ArrayList( entitySpan ); Object result = null; @@ -338,37 +437,56 @@ resultSet, session, queryParameters, - getLockModes( queryParameters.getLockModes() ), + getLockModes( queryParameters.getLockOptions() ), null, hydratedObjects, loadedKeys, returnProxies + ); + if ( ! keyToRead.equals( loadedKeys[0] ) ) { + throw new AssertionFailure( + String.format( + "Unexpected key read for row; expected [%s]; actual [%s]", + keyToRead, + loadedKeys[0] ) ); + } if ( result == null ) { result = loaded; } - } - while ( keyToRead.equals( loadedKeys[0] ) && resultSet.next() ); + } + while ( resultSet.next() && + isCurrentRowForSameEntity( keyToRead, 0, resultSet, session ) ); } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - factory.getSQLExceptionConverter(), - sqle, - "could not perform sequential read of results (forward)", - getSQLString() + throw factory.getSQLExceptionHelper().convert( + sqle, + "could not doAfterTransactionCompletion sequential read of results (forward)", + getSQLString() ); } - initializeEntitiesAndCollections( - hydratedObjects, - resultSet, - session, - queryParameters.isReadOnly() - ); + initializeEntitiesAndCollections( + hydratedObjects, + resultSet, + session, + queryParameters.isReadOnly( session ) + ); session.getPersistenceContext().initializeNonLazyCollections(); return result; } + private boolean isCurrentRowForSameEntity( + final EntityKey keyToRead, + final int persisterIndex, + final ResultSet resultSet, + final SessionImplementor session) throws SQLException { + EntityKey currentRowKey = getKeyFromResultSet( + persisterIndex, getEntityPersisters()[persisterIndex], null, resultSet, session + ); + return keyToRead.equals( currentRowKey ); + } + /** * Loads a single logical row from the result set moving forward. This is the * processing used from the ScrollableResults where there were collection fetches @@ -383,10 +501,10 @@ * @throws HibernateException */ public Object loadSequentialRowsForward( - final ResultSet resultSet, - final SessionImplementor session, - final QueryParameters queryParameters, - final boolean returnProxies) throws HibernateException { + final ResultSet resultSet, + final SessionImplementor session, + final QueryParameters queryParameters, + final boolean returnProxies) throws HibernateException { // note that for sequential scrolling, we make the assumption that // the first persister element is the "root entity" @@ -418,11 +536,10 @@ return sequentialLoad( resultSet, session, queryParameters, returnProxies, currentKey ); } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - factory.getSQLExceptionConverter(), - sqle, - "could not perform sequential read of results (forward)", - getSQLString() + throw factory.getSQLExceptionHelper().convert( + sqle, + "could not perform sequential read of results (forward)", + getSQLString() ); } } @@ -441,11 +558,11 @@ * @throws HibernateException */ public Object loadSequentialRowsReverse( - final ResultSet resultSet, - final SessionImplementor session, - final QueryParameters queryParameters, - final boolean returnProxies, - final boolean isLogicallyAfterLast) throws HibernateException { + final ResultSet resultSet, + final SessionImplementor session, + final QueryParameters queryParameters, + final boolean returnProxies, + final boolean isLogicallyAfterLast) throws HibernateException { // note that for sequential scrolling, we make the assumption that // the first persister element is the "root entity" @@ -540,15 +657,14 @@ // at the first physical row we are interested in loading resultSet.next(); - // and perform the load + // and doAfterTransactionCompletion the load return sequentialLoad( resultSet, session, queryParameters, returnProxies, keyToRead ); } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - factory.getSQLExceptionConverter(), - sqle, - "could not perform sequential read of results (forward)", - getSQLString() + throw factory.getSQLExceptionHelper().convert( + sqle, + "could not doAfterTransactionCompletion sequential read of results (forward)", + getSQLString() ); } } @@ -559,11 +675,7 @@ final String optionalEntityName = queryParameters.getOptionalEntityName(); if ( optionalObject != null && optionalEntityName != null ) { - return new EntityKey( - optionalId, - session.getEntityPersister( optionalEntityName, optionalObject ), - session.getEntityMode() - ); + return session.generateEntityKey( optionalId, session.getEntityPersister( optionalEntityName, optionalObject ) ); } else { return null; @@ -572,41 +684,51 @@ } private Object getRowFromResultSet( - final ResultSet resultSet, - final SessionImplementor session, - final QueryParameters queryParameters, - final LockMode[] lockModeArray, - final EntityKey optionalObjectKey, - final List hydratedObjects, - final EntityKey[] keys, - boolean returnProxies) throws SQLException, HibernateException { + final ResultSet resultSet, + final SessionImplementor session, + final QueryParameters queryParameters, + final LockMode[] lockModesArray, + final EntityKey optionalObjectKey, + final List hydratedObjects, + final EntityKey[] keys, + boolean returnProxies) throws SQLException, HibernateException { + return getRowFromResultSet( + resultSet, + session, + queryParameters, + lockModesArray, + optionalObjectKey, + hydratedObjects, + keys, + returnProxies, + null + ); + } + private Object getRowFromResultSet( + final ResultSet resultSet, + final SessionImplementor session, + final QueryParameters queryParameters, + final LockMode[] lockModesArray, + final EntityKey optionalObjectKey, + final List hydratedObjects, + final EntityKey[] keys, + boolean returnProxies, + ResultTransformer forcedResultTransformer) throws SQLException, HibernateException { final Loadable[] persisters = getEntityPersisters(); final int entitySpan = persisters.length; + extractKeysFromResultSet( persisters, queryParameters, resultSet, session, keys, lockModesArray, hydratedObjects ); - for ( int i = 0; i < entitySpan; i++ ) { - keys[i] = getKeyFromResultSet( - i, - persisters[i], - i == entitySpan - 1 ? - queryParameters.getOptionalId() : - null, - resultSet, - session - ); - //TODO: the i==entitySpan-1 bit depends upon subclass implementation (very bad) - } - registerNonExists( keys, persisters, session ); // this call is side-effecty Object[] row = getRow( - resultSet, + resultSet, persisters, keys, queryParameters.getOptionalObject(), optionalObjectKey, - lockModeArray, + lockModesArray, hydratedObjects, session ); @@ -626,10 +748,101 @@ } } - return getResultColumnOrRow( row, queryParameters.getResultTransformer(), resultSet, session ); + applyPostLoadLocks( row, lockModesArray, session ); + return forcedResultTransformer == null + ? getResultColumnOrRow( row, queryParameters.getResultTransformer(), resultSet, session ) + : forcedResultTransformer.transformTuple( getResultRow( row, resultSet, session ), getResultRowAliases() ) + ; } + protected void extractKeysFromResultSet( + Loadable[] persisters, + QueryParameters queryParameters, + ResultSet resultSet, + SessionImplementor session, + EntityKey[] keys, + LockMode[] lockModes, + List hydratedObjects) throws SQLException { + final int entitySpan = persisters.length; + + final int numberOfPersistersToProcess; + final Serializable optionalId = queryParameters.getOptionalId(); + if ( isSingleRowLoader() && optionalId != null ) { + keys[ entitySpan - 1 ] = session.generateEntityKey( optionalId, persisters[ entitySpan - 1 ] ); + // skip the last persister below... + numberOfPersistersToProcess = entitySpan - 1; + } + else { + numberOfPersistersToProcess = entitySpan; + } + + final Object[] hydratedKeyState = new Object[numberOfPersistersToProcess]; + + for ( int i = 0; i < numberOfPersistersToProcess; i++ ) { + final Type idType = persisters[i].getIdentifierType(); + hydratedKeyState[i] = idType.hydrate( resultSet, getEntityAliases()[i].getSuffixedKeyAliases(), session, null ); + } + + for ( int i = 0; i < numberOfPersistersToProcess; i++ ) { + final Type idType = persisters[i].getIdentifierType(); + if ( idType.isComponentType() && getCompositeKeyManyToOneTargetIndices() != null ) { + // we may need to force resolve any key-many-to-one(s) + int[] keyManyToOneTargetIndices = getCompositeKeyManyToOneTargetIndices()[i]; + // todo : better solution is to order the index processing based on target indices + // that would account for multiple levels whereas this scheme does not + if ( keyManyToOneTargetIndices != null ) { + for ( int targetIndex : keyManyToOneTargetIndices ) { + if ( targetIndex < numberOfPersistersToProcess ) { + final Type targetIdType = persisters[targetIndex].getIdentifierType(); + final Serializable targetId = (Serializable) targetIdType.resolve( + hydratedKeyState[targetIndex], + session, + null + ); + // todo : need a way to signal that this key is resolved and its data resolved + keys[targetIndex] = session.generateEntityKey( targetId, persisters[targetIndex] ); + } + + // this part copied from #getRow, this section could be refactored out + Object object = session.getEntityUsingInterceptor( keys[targetIndex] ); + if ( object != null ) { + //its already loaded so don't need to hydrate it + instanceAlreadyLoaded( + resultSet, + targetIndex, + persisters[targetIndex], + keys[targetIndex], + object, + lockModes[targetIndex], + session + ); + } + else { + instanceNotYetLoaded( + resultSet, + targetIndex, + persisters[targetIndex], + getEntityAliases()[targetIndex].getRowIdAlias(), + keys[targetIndex], + lockModes[targetIndex], + getOptionalObjectKey( queryParameters, session ), + queryParameters.getOptionalObject(), + hydratedObjects, + session + ); + } + } + } + } + final Serializable resolvedId = (Serializable) idType.resolve( hydratedKeyState[i], session, null ); + keys[i] = resolvedId == null ? null : session.generateEntityKey( resolvedId, persisters[i] ); + } + } + + protected void applyPostLoadLocks(Object[] row, LockMode[] lockModesArray, SessionImplementor session) { + } + /** * Read any collection elements contained in a single row of the result set */ @@ -646,11 +859,11 @@ for ( int i=0; i -1; //true if this is a query and we are loading multiple instances of the same collection role //otherwise this is a CollectionInitializer and we are loading up a single collection or batch - + final Object owner = hasCollectionOwners ? row[ collectionOwners[i] ] : null; //if null, owner will be retrieved from session @@ -665,16 +878,16 @@ //TODO: old version did not require hashmap lookup: //keys[collectionOwner].getIdentifier() } - - readCollectionElement( - owner, - key, - collectionPersister, - descriptors[i], - resultSet, - session + + readCollectionElement( + owner, + key, + collectionPersister, + descriptors[i], + resultSet, + session ); - + } } @@ -683,150 +896,162 @@ private List doQuery( final SessionImplementor session, final QueryParameters queryParameters, - final boolean returnProxies) throws SQLException, HibernateException { + final boolean returnProxies, + final ResultTransformer forcedResultTransformer) throws SQLException, HibernateException { final RowSelection selection = queryParameters.getRowSelection(); - final int maxRows = hasMaxRows( selection ) ? - selection.getMaxRows().intValue() : + final int maxRows = LimitHelper.hasMaxRows( selection ) ? + selection.getMaxRows() : Integer.MAX_VALUE; - final int entitySpan = getEntityPersisters().length; + final List afterLoadActions = new ArrayList(); - final ArrayList hydratedObjects = entitySpan == 0 ? null : new ArrayList( entitySpan * 10 ); - final PreparedStatement st = prepareQueryStatement( queryParameters, false, session ); - final ResultSet rs = getResultSet( st, queryParameters.hasAutoDiscoverScalarTypes(), queryParameters.isCallable(), selection, session ); + final SqlStatementWrapper wrapper = executeQueryStatement( queryParameters, false, afterLoadActions, session ); + final ResultSet rs = wrapper.getResultSet(); + final Statement st = wrapper.getStatement(); // would be great to move all this below here into another method that could also be used // from the new scrolling stuff. // // Would need to change the way the max-row stuff is handled (i.e. behind an interface) so // that I could do the control breaking at the means to know when to stop - final LockMode[] lockModeArray = getLockModes( queryParameters.getLockModes() ); - final EntityKey optionalObjectKey = getOptionalObjectKey( queryParameters, session ); + try { + return processResultSet( rs, queryParameters, session, returnProxies, forcedResultTransformer, maxRows, afterLoadActions ); + } + finally { + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); + } + + } + + protected List processResultSet( + ResultSet rs, + QueryParameters queryParameters, + SessionImplementor session, + boolean returnProxies, + ResultTransformer forcedResultTransformer, + int maxRows, + List afterLoadActions) throws SQLException { + final int entitySpan = getEntityPersisters().length; + final EntityKey optionalObjectKey = getOptionalObjectKey( queryParameters, session ); + final LockMode[] lockModesArray = getLockModes( queryParameters.getLockOptions() ); final boolean createSubselects = isSubselectLoadingEnabled(); final List subselectResultKeys = createSubselects ? new ArrayList() : null; + final ArrayList hydratedObjects = entitySpan == 0 ? null : new ArrayList( entitySpan * 10 ); final List results = new ArrayList(); - try { + handleEmptyCollections( queryParameters.getCollectionKeys(), rs, session ); + EntityKey[] keys = new EntityKey[entitySpan]; //we can reuse it for each row + LOG.trace( "Processing result set" ); + int count; - handleEmptyCollections( queryParameters.getCollectionKeys(), rs, session ); - - EntityKey[] keys = new EntityKey[entitySpan]; //we can reuse it for each row - - if ( log.isTraceEnabled() ) log.trace( "processing result set" ); - - int count; - for ( count = 0; count < maxRows && rs.next(); count++ ) { - - if ( log.isTraceEnabled() ) log.debug("result set row: " + count); - - Object result = getRowFromResultSet( - rs, - session, - queryParameters, - lockModeArray, - optionalObjectKey, - hydratedObjects, - keys, - returnProxies - ); - results.add( result ); - - if ( createSubselects ) { - subselectResultKeys.add(keys); - keys = new EntityKey[entitySpan]; //can't reuse in this case - } - + for ( count = 0; count < maxRows && rs.next(); count++ ) { + if ( DEBUG_ENABLED ) + LOG.debugf( "Result set row: %s", count ); + Object result = getRowFromResultSet( + rs, + session, + queryParameters, + lockModesArray, + optionalObjectKey, + hydratedObjects, + keys, + returnProxies, + forcedResultTransformer + ); + results.add( result ); + if ( createSubselects ) { + subselectResultKeys.add(keys); + keys = new EntityKey[entitySpan]; //can't reuse in this case } - - if ( log.isTraceEnabled() ) { - log.trace( "done processing result set (" + count + " rows)" ); - } - } - finally { - session.getBatcher().closeQueryStatement( st, rs ); - } - initializeEntitiesAndCollections( hydratedObjects, rs, session, queryParameters.isReadOnly() ); + LOG.tracev( "Done processing result set ({0} rows)", count ); - if ( createSubselects ) createSubselects( subselectResultKeys, queryParameters, session ); - - return results; //getResultList(results); - + initializeEntitiesAndCollections( + hydratedObjects, + rs, + session, + queryParameters.isReadOnly( session ), + afterLoadActions + ); + if ( createSubselects ) { + createSubselects( subselectResultKeys, queryParameters, session ); + } + return results; } protected boolean isSubselectLoadingEnabled() { return false; } - + protected boolean hasSubselectLoadableCollections() { final Loadable[] loadables = getEntityPersisters(); - for (int i=0; i 1 ) { //if we only returned one entity, query by key is more efficient - + Set[] keySets = transpose(keys); - + Map namedParameterLocMap = buildNamedParameterLocMap( queryParameters ); - + final Loadable[] loadables = getEntityPersisters(); final String[] aliases = getAliases(); final Iterator iter = keys.iterator(); while ( iter.hasNext() ) { - + final EntityKey[] rowKeys = (EntityKey[]) iter.next(); for ( int i=0; iemptyList() + ); + } + + private void initializeEntitiesAndCollections( + final List hydratedObjects, + final Object resultSetId, + final SessionImplementor session, + final boolean readOnly, + List afterLoadActions) throws HibernateException { + final CollectionPersister[] collectionPersisters = getCollectionPersisters(); if ( collectionPersisters != null ) { for ( int i=0; i -1 ) { EntityKey ownerKey = keys[owner]; if ( keys[i] == null && ownerKey != null ) { - + final PersistenceContext persistenceContext = session.getPersistenceContext(); - + /*final boolean isPrimaryKey; final boolean isSpecialOneToOne; if ( ownerAssociationTypes == null || ownerAssociationTypes[i] == null ) { @@ -950,24 +1247,24 @@ isPrimaryKey = ownerAssociationTypes[i].getRHSUniqueKeyPropertyName()==null; isSpecialOneToOne = ownerAssociationTypes[i].getLHSPropertyName()!=null; }*/ - + //TODO: can we *always* use the "null property" approach for everything? /*if ( isPrimaryKey && !isSpecialOneToOne ) { - persistenceContext.addNonExistantEntityKey( - new EntityKey( ownerKey.getIdentifier(), persisters[i], session.getEntityMode() ) + persistenceContext.addNonExistantEntityKey( + new EntityKey( ownerKey.getIdentifier(), persisters[i], session.getEntityMode() ) ); } else if ( isSpecialOneToOne ) {*/ - boolean isOneToOneAssociation = ownerAssociationTypes!=null && - ownerAssociationTypes[i]!=null && + boolean isOneToOneAssociation = ownerAssociationTypes!=null && + ownerAssociationTypes[i]!=null && ownerAssociationTypes[i].isOneToOne(); if ( isOneToOneAssociation ) { - persistenceContext.addNullProperty( ownerKey, + persistenceContext.addNullProperty( ownerKey, ownerAssociationTypes[i].getPropertyName() ); } /*} else { - persistenceContext.addNonExistantEntityUniqueKey( new EntityUniqueKey( + persistenceContext.addNonExistantEntityUniqueKey( new EntityUniqueKey( persisters[i].getEntityName(), ownerAssociationTypes[i].getRHSUniqueKeyPropertyName(), ownerKey.getIdentifier(), @@ -985,30 +1282,28 @@ * Read one collection element from the current row of the JDBC result set */ private void readCollectionElement( - final Object optionalOwner, - final Serializable optionalKey, - final CollectionPersister persister, - final CollectionAliases descriptor, - final ResultSet rs, - final SessionImplementor session) + final Object optionalOwner, + final Serializable optionalKey, + final CollectionPersister persister, + final CollectionAliases descriptor, + final ResultSet rs, + final SessionImplementor session) throws HibernateException, SQLException { final PersistenceContext persistenceContext = session.getPersistenceContext(); - final Serializable collectionRowKey = (Serializable) persister.readKey( - rs, - descriptor.getSuffixedKeyAliases(), - session + final Serializable collectionRowKey = (Serializable) persister.readKey( + rs, + descriptor.getSuffixedKeyAliases(), + session ); - + if ( collectionRowKey != null ) { // we found a collection element in the result set - if ( log.isDebugEnabled() ) { - log.debug( - "found row of collection: " + - MessageHelper.collectionInfoString( persister, collectionRowKey, getFactory() ) - ); + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Found row of collection: %s", + MessageHelper.collectionInfoString( persister, collectionRowKey, getFactory() ) ); } Object owner = optionalOwner; @@ -1037,11 +1332,9 @@ // ensure that a collection is created with the owner's identifier, // since what we have is an empty collection - if ( log.isDebugEnabled() ) { - log.debug( - "result set contains (possibly empty) collection: " + - MessageHelper.collectionInfoString( persister, optionalKey, getFactory() ) - ); + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Result set contains (possibly empty) collection: %s", + MessageHelper.collectionInfoString( persister, optionalKey, getFactory() ) ); } persistenceContext.getLoadContexts() @@ -1056,29 +1349,27 @@ /** * If this is a collection initializer, we need to tell the session that a collection - * is being initilized, to account for the possibility of the collection having + * is being initialized, to account for the possibility of the collection having * no elements (hence no rows in the result set). */ private void handleEmptyCollections( - final Serializable[] keys, - final Object resultSetId, - final SessionImplementor session) { + final Serializable[] keys, + final Object resultSetId, + final SessionImplementor session) { if ( keys != null ) { + final boolean debugEnabled = LOG.isDebugEnabled(); // this is a collection initializer, so we must create a collection // for each of the passed-in keys, to account for the possibility // that the collection is empty and has no rows in the result set - CollectionPersister[] collectionPersisters = getCollectionPersisters(); for ( int j=0; jid is given, don't bother going to the ResultSet. */ private EntityKey getKeyFromResultSet( - final int i, - final Loadable persister, - final Serializable id, - final ResultSet rs, - final SessionImplementor session) throws HibernateException, SQLException { + final int i, + final Loadable persister, + final Serializable id, + final ResultSet rs, + final SessionImplementor session) throws HibernateException, SQLException { Serializable resultId; @@ -1116,25 +1407,23 @@ resultId = id; } else { - + Type idType = persister.getIdentifierType(); resultId = (Serializable) idType.nullSafeGet( rs, getEntityAliases()[i].getSuffixedKeyAliases(), session, null //problematic for ! ); - - final boolean idIsResultId = id != null && - resultId != null && - idType.isEqual( id, resultId, session.getEntityMode(), factory ); - + + final boolean idIsResultId = id != null && + resultId != null && + idType.isEqual( id, resultId, factory ); + if ( idIsResultId ) resultId = id; //use the id passed in } - return resultId == null ? - null : - new EntityKey( resultId, persister, session.getEntityMode() ); + return resultId == null ? null : session.generateEntityKey( resultId, persister ); } /** @@ -1143,12 +1432,12 @@ * if the version numbers are different */ private void checkVersion( - final int i, - final Loadable persister, - final Serializable id, - final Object entity, - final ResultSet rs, - final SessionImplementor session) + final int i, + final Loadable persister, + final Serializable id, + final Object entity, + final ResultSet rs, + final SessionImplementor session) throws HibernateException, SQLException { Object version = session.getPersistenceContext().getEntry( entity ).getVersion(); @@ -1173,32 +1462,27 @@ } /** - * Resolve any ids for currently loaded objects, duplications within the + * Resolve any IDs for currently loaded objects, duplications within the * ResultSet, etc. Instantiate empty objects to be initialized from the * ResultSet. Return an array of objects (a row of results) and an * array of booleans (by side-effect) that determine whether the corresponding * object should be initialized. */ private Object[] getRow( - final ResultSet rs, - final Loadable[] persisters, - final EntityKey[] keys, - final Object optionalObject, - final EntityKey optionalObjectKey, - final LockMode[] lockModes, - final List hydratedObjects, - final SessionImplementor session) + final ResultSet rs, + final Loadable[] persisters, + final EntityKey[] keys, + final Object optionalObject, + final EntityKey optionalObjectKey, + final LockMode[] lockModes, + final List hydratedObjects, + final SessionImplementor session) throws HibernateException, SQLException { final int cols = persisters.length; final EntityAliases[] descriptors = getEntityAliases(); - if ( log.isDebugEnabled() ) { - log.debug( - "result row: " + - StringHelper.toString( keys ) - ); - } + if ( LOG.isDebugEnabled() ) LOG.debugf( "Result row: %s", StringHelper.toString( keys ) ); final Object[] rowResults = new Object[cols]; @@ -1216,18 +1500,18 @@ object = session.getEntityUsingInterceptor( key ); if ( object != null ) { //its already loaded so don't need to hydrate it - instanceAlreadyLoaded( + instanceAlreadyLoaded( rs, i, persisters[i], key, object, lockModes[i], - session + session ); } else { - object = instanceNotYetLoaded( + object = instanceNotYetLoaded( rs, i, persisters[i], @@ -1237,7 +1521,7 @@ optionalObjectKey, optionalObject, hydratedObjects, - session + session ); } @@ -1254,64 +1538,75 @@ * The entity instance is already in the session cache */ private void instanceAlreadyLoaded( - final ResultSet rs, - final int i, - final Loadable persister, - final EntityKey key, - final Object object, - final LockMode lockMode, - final SessionImplementor session) - throws HibernateException, SQLException { - - if ( !persister.isInstance( object, session.getEntityMode() ) ) { - throw new WrongClassException( - "loaded object was of wrong class " + object.getClass(), - key.getIdentifier(), - persister.getEntityName() - ); + final ResultSet rs, + final int i, + final Loadable persister, + final EntityKey key, + final Object object, + final LockMode requestedLockMode, + final SessionImplementor session) + throws HibernateException, SQLException { + if ( !persister.isInstance( object ) ) { + throw new WrongClassException( + "loaded object was of wrong class " + object.getClass(), + key.getIdentifier(), + persister.getEntityName() + ); } - if ( LockMode.NONE != lockMode && upgradeLocks() ) { //no point doing this if NONE was requested - - final boolean isVersionCheckNeeded = persister.isVersioned() && - session.getPersistenceContext().getEntry(object) - .getLockMode().lessThan( lockMode ); - // we don't need to worry about existing version being uninitialized - // because this block isn't called by a re-entrant load (re-entrant - // loads _always_ have lock mode NONE) - if (isVersionCheckNeeded) { + if ( LockMode.NONE != requestedLockMode && upgradeLocks() ) { //no point doing this if NONE was requested + final EntityEntry entry = session.getPersistenceContext().getEntry( object ); + if ( entry.getLockMode().lessThan( requestedLockMode ) ) { //we only check the version when _upgrading_ lock modes - checkVersion( i, persister, key.getIdentifier(), object, rs, session ); + if ( persister.isVersioned() ) { + checkVersion( i, persister, key.getIdentifier(), object, rs, session ); + } //we need to upgrade the lock mode to the mode requested - session.getPersistenceContext().getEntry(object) - .setLockMode(lockMode); + entry.setLockMode( requestedLockMode ); } } } + /** * The entity instance is not in the session cache */ private Object instanceNotYetLoaded( - final ResultSet rs, - final int i, - final Loadable persister, - final String rowIdAlias, - final EntityKey key, - final LockMode lockMode, - final EntityKey optionalObjectKey, - final Object optionalObject, - final List hydratedObjects, - final SessionImplementor session) + final ResultSet rs, + final int i, + final Loadable persister, + final String rowIdAlias, + final EntityKey key, + final LockMode lockMode, + final EntityKey optionalObjectKey, + final Object optionalObject, + final List hydratedObjects, + final SessionImplementor session) throws HibernateException, SQLException { + final String instanceClass = getInstanceClass( + rs, + i, + persister, + key.getIdentifier(), + session + ); - final String instanceClass = getInstanceClass( - rs, - i, - persister, - key.getIdentifier(), - session + // see if the entity defines reference caching, and if so use the cached reference (if one). + if ( persister.canUseReferenceCacheEntries() ) { + final Object cachedEntry = CacheHelper.fromSharedCache( + session, + session.generateCacheKey( + key.getIdentifier(), + persister.getEntityMetamodel().getEntityType(), + key.getEntityName() + ), + persister.getCacheAccessStrategy() ); + if ( cachedEntry != null ) { + CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure( cachedEntry, factory ); + return ( (ReferenceCacheEntryImpl) entry ).getReference(); + } + } final Object object; if ( optionalObjectKey != null && key.equals( optionalObjectKey ) ) { @@ -1329,24 +1624,24 @@ // (but don't yet initialize the object itself) // note that we acquire LockMode.READ even if it was not requested LockMode acquiredLockMode = lockMode == LockMode.NONE ? LockMode.READ : lockMode; - loadFromResultSet( - rs, - i, - object, - instanceClass, - key, - rowIdAlias, - acquiredLockMode, - persister, - session + loadFromResultSet( + rs, + i, + object, + instanceClass, + key, + rowIdAlias, + acquiredLockMode, + persister, + session ); //materialize associations (and initialize the object) later hydratedObjects.add( object ); return object; } - + private boolean isEagerPropertyFetchEnabled(int i) { boolean[] array = getEntityEagerPropertyFetches(); return array!=null && array[i]; @@ -1359,56 +1654,52 @@ * and pass the hydrates state to the session. */ private void loadFromResultSet( - final ResultSet rs, - final int i, - final Object object, - final String instanceEntityName, - final EntityKey key, - final String rowIdAlias, - final LockMode lockMode, - final Loadable rootPersister, - final SessionImplementor session) + final ResultSet rs, + final int i, + final Object object, + final String instanceEntityName, + final EntityKey key, + final String rowIdAlias, + final LockMode lockMode, + final Loadable rootPersister, + final SessionImplementor session) throws SQLException, HibernateException { final Serializable id = key.getIdentifier(); // Get the persister for the _subclass_ final Loadable persister = (Loadable) getFactory().getEntityPersister( instanceEntityName ); - if ( log.isTraceEnabled() ) { - log.trace( - "Initializing object from ResultSet: " + - MessageHelper.infoString( persister, id, getFactory() ) - ); - } - + if ( LOG.isTraceEnabled() ) + LOG.tracev( "Initializing object from ResultSet: {0}", MessageHelper.infoString( persister, id, getFactory() ) ); + boolean eagerPropertyFetch = isEagerPropertyFetchEnabled(i); // add temp entry so that the next step is circular-reference // safe - only needed because some types don't take proper // advantage of two-phase-load (esp. components) - TwoPhaseLoad.addUninitializedEntity( - key, - object, - persister, - lockMode, - !eagerPropertyFetch, - session + TwoPhaseLoad.addUninitializedEntity( + key, + object, + persister, + lockMode, + !eagerPropertyFetch, + session ); //This is not very nice (and quite slow): final String[][] cols = persister == rootPersister ? getEntityAliases()[i].getSuffixedPropertyAliases() : getEntityAliases()[i].getSuffixedPropertyAliases(persister); - final Object[] values = persister.hydrate( - rs, - id, - object, - rootPersister, - cols, - eagerPropertyFetch, - session + final Object[] values = persister.hydrate( + rs, + id, + object, + rootPersister, + cols, + eagerPropertyFetch, + session ); final Object rowId = persister.hasRowId() ? rs.getObject(rowIdAlias) : null; @@ -1419,33 +1710,34 @@ if (ukName!=null) { final int index = ( (UniqueKeyLoadable) persister ).getPropertyIndex(ukName); final Type type = persister.getPropertyTypes()[index]; - + // polymorphism not really handled completely correctly, // perhaps...well, actually its ok, assuming that the // entity name used in the lookup is the same as the // the one used here, which it will be - - EntityUniqueKey euk = new EntityUniqueKey( + + EntityUniqueKey euk = new EntityUniqueKey( rootPersister.getEntityName(), //polymorphism comment above ukName, type.semiResolve( values[index], session, object ), type, - session.getEntityMode(), session.getFactory() - ); + persister.getEntityMode(), + session.getFactory() + ); session.getPersistenceContext().addEntity( euk, object ); } } - TwoPhaseLoad.postHydrate( - persister, - id, - values, - rowId, - object, - lockMode, - !eagerPropertyFetch, - session - ); + TwoPhaseLoad.postHydrate( + persister, + id, + values, + rowId, + object, + lockMode, + !eagerPropertyFetch, + session + ); } @@ -1457,7 +1749,7 @@ final int i, final Loadable persister, final Serializable id, - final SessionImplementor session) + final SessionImplementor session) throws HibernateException, SQLException { if ( persister.hasSubclasses() ) { @@ -1474,10 +1766,10 @@ if ( result == null ) { //woops we got an instance of another class hierarchy branch - throw new WrongClassException( + throw new WrongClassException( "Discriminator: " + discriminatorValue, id, - persister.getEntityName() + persister.getEntityName() ); } @@ -1495,7 +1787,7 @@ private void advance(final ResultSet rs, final RowSelection selection) throws SQLException { - final int firstRow = getFirstRow( selection ); + final int firstRow = LimitHelper.getFirstRow( selection ); if ( firstRow != 0 ) { if ( getFactory().getSettings().isScrollableResultSetsEnabled() ) { // we can go straight to the first required row @@ -1508,178 +1800,152 @@ } } - private static boolean hasMaxRows(RowSelection selection) { - return selection != null && selection.getMaxRows() != null; + /** + * Build LIMIT clause handler applicable for given selection criteria. Returns {@link NoopLimitHandler} delegate + * if dialect does not support LIMIT expression or processed query does not use pagination. + * + * @param sql Query string. + * @param selection Selection criteria. + * @return LIMIT clause delegate. + */ + protected LimitHandler getLimitHandler(String sql, RowSelection selection) { + final LimitHandler limitHandler = getFactory().getDialect().buildLimitHandler( sql, selection ); + return LimitHelper.useLimit( limitHandler, selection ) ? limitHandler : new NoopLimitHandler( sql, selection ); } - private static int getFirstRow(RowSelection selection) { - if ( selection == null || selection.getFirstRow() == null ) { - return 0; + private ScrollMode getScrollMode(boolean scroll, boolean hasFirstRow, boolean useLimitOffSet, QueryParameters queryParameters) { + final boolean canScroll = getFactory().getSettings().isScrollableResultSetsEnabled(); + if ( canScroll ) { + if ( scroll ) { + return queryParameters.getScrollMode(); + } + if ( hasFirstRow && !useLimitOffSet ) { + return ScrollMode.SCROLL_INSENSITIVE; + } } - else { - return selection.getFirstRow().intValue(); - } + return null; } /** - * Should we pre-process the SQL string, adding a dialect-specific - * LIMIT clause. + * Process query string by applying filters, LIMIT clause, locks and comments if necessary. + * Finally execute SQL statement and advance to the first row. */ - private static boolean useLimit(final RowSelection selection, final Dialect dialect) { - return dialect.supportsLimit() && hasMaxRows( selection ); + protected SqlStatementWrapper executeQueryStatement( + final QueryParameters queryParameters, + final boolean scroll, + List afterLoadActions, + final SessionImplementor session) throws SQLException { + return executeQueryStatement( getSQLString(), queryParameters, scroll, afterLoadActions, session ); } + protected SqlStatementWrapper executeQueryStatement( + String sqlStatement, + QueryParameters queryParameters, + boolean scroll, + List afterLoadActions, + SessionImplementor session) throws SQLException { + + // Processing query filters. + queryParameters.processFilters( sqlStatement, session ); + + // Applying LIMIT clause. + final LimitHandler limitHandler = getLimitHandler( + queryParameters.getFilteredSQL(), + queryParameters.getRowSelection() + ); + String sql = limitHandler.getProcessedSql(); + + // Adding locks and comments. + sql = preprocessSQL( sql, queryParameters, getFactory().getDialect(), afterLoadActions ); + + final PreparedStatement st = prepareQueryStatement( sql, queryParameters, limitHandler, scroll, session ); + return new SqlStatementWrapper( st, getResultSet( st, queryParameters.getRowSelection(), limitHandler, queryParameters.hasAutoDiscoverScalarTypes(), session ) ); + } + /** * Obtain a PreparedStatement with all parameters pre-bound. * Bind JDBC-style ? parameters, named parameters, and * limit parameters. */ protected final PreparedStatement prepareQueryStatement( + String sql, final QueryParameters queryParameters, + final LimitHandler limitHandler, final boolean scroll, final SessionImplementor session) throws SQLException, HibernateException { - - queryParameters.processFilters( getSQLString(), session ); - String sql = queryParameters.getFilteredSQL(); final Dialect dialect = getFactory().getDialect(); final RowSelection selection = queryParameters.getRowSelection(); - boolean useLimit = useLimit( selection, dialect ); - boolean hasFirstRow = getFirstRow( selection ) > 0; - boolean useOffset = hasFirstRow && useLimit && dialect.supportsLimitOffset(); + boolean useLimit = LimitHelper.useLimit( limitHandler, selection ); + boolean hasFirstRow = LimitHelper.hasFirstRow( selection ); + boolean useLimitOffset = hasFirstRow && useLimit && limitHandler.supportsLimitOffset(); boolean callable = queryParameters.isCallable(); + final ScrollMode scrollMode = getScrollMode( scroll, hasFirstRow, useLimitOffset, queryParameters ); - boolean useScrollableResultSetToSkip = hasFirstRow && - !useOffset && - getFactory().getSettings().isScrollableResultSetsEnabled(); - ScrollMode scrollMode = scroll ? queryParameters.getScrollMode() : ScrollMode.SCROLL_INSENSITIVE; + PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareQueryStatement( + sql, + callable, + scrollMode + ); - if ( useLimit ) { - sql = dialect.getLimitString( - sql.trim(), //use of trim() here is ugly? - useOffset ? getFirstRow(selection) : 0, - getMaxOrLimit(selection, dialect) - ); - } - - sql = preprocessSQL( sql, queryParameters, dialect ); - - PreparedStatement st = null; - - if (callable) { - st = session.getBatcher() - .prepareCallableQueryStatement( sql, scroll || useScrollableResultSetToSkip, scrollMode ); - } - else { - st = session.getBatcher() - .prepareQueryStatement( sql, scroll || useScrollableResultSetToSkip, scrollMode ); - } - - try { int col = 1; //TODO: can we limit stored procedures ?! - if ( useLimit && dialect.bindLimitParametersFirst() ) { - col += bindLimitParameters( st, col, selection ); - } + col += limitHandler.bindLimitParametersAtStartOfQuery( st, col ); + if (callable) { col = dialect.registerResultSetOutParameter( (CallableStatement)st, col ); } col += bindParameterValues( st, queryParameters, col, session ); - if ( useLimit && !dialect.bindLimitParametersFirst() ) { - col += bindLimitParameters( st, col, selection ); - } + col += limitHandler.bindLimitParametersAtEndOfQuery( st, col ); - if ( !useLimit ) { - setMaxRows( st, selection ); - } + limitHandler.setMaxRows( st ); if ( selection != null ) { if ( selection.getTimeout() != null ) { - st.setQueryTimeout( selection.getTimeout().intValue() ); + st.setQueryTimeout( selection.getTimeout() ); } if ( selection.getFetchSize() != null ) { - st.setFetchSize( selection.getFetchSize().intValue() ); + st.setFetchSize( selection.getFetchSize() ); } } + + // handle lock timeout... + LockOptions lockOptions = queryParameters.getLockOptions(); + if ( lockOptions != null ) { + if ( lockOptions.getTimeOut() != LockOptions.WAIT_FOREVER ) { + if ( !dialect.supportsLockTimeouts() ) { + if ( LOG.isDebugEnabled() ) { + LOG.debugf( + "Lock timeout [%s] requested but dialect reported to not support lock timeouts", + lockOptions.getTimeOut() + ); + } + } + else if ( dialect.isLockTimeoutParameterized() ) { + st.setInt( col++, lockOptions.getTimeOut() ); + } + } + } + + if ( LOG.isTraceEnabled() ) + LOG.tracev( "Bound [{0}] parameters total", col ); } catch ( SQLException sqle ) { - session.getBatcher().closeQueryStatement( st, null ); + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); throw sqle; } catch ( HibernateException he ) { - session.getBatcher().closeQueryStatement( st, null ); + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); throw he; } return st; } /** - * Some dialect-specific LIMIT clauses require the maximium last row number - * (aka, first_row_number + total_row_count), while others require the maximum - * returned row count (the total maximum number of rows to return). - * - * @param selection The selection criteria - * @param dialect The dialect - * @return The appropriate value to bind into the limit clause. - */ - private static int getMaxOrLimit(final RowSelection selection, final Dialect dialect) { - final int firstRow = getFirstRow( selection ); - final int lastRow = selection.getMaxRows().intValue(); - if ( dialect.useMaxForLimit() ) { - return lastRow + firstRow; - } - else { - return lastRow; - } - } - - /** - * Bind parameter values needed by the dialect-specific LIMIT clause. - * - * @param statement The statement to which to bind limit param values. - * @param index The bind position from which to start binding - * @param selection The selection object containing the limit information. - * @return The number of parameter values bound. - * @throws java.sql.SQLException Indicates problems binding parameter values. - */ - private int bindLimitParameters( - final PreparedStatement statement, - final int index, - final RowSelection selection) throws SQLException { - Dialect dialect = getFactory().getDialect(); - if ( !dialect.supportsVariableLimit() ) { - return 0; - } - if ( !hasMaxRows( selection ) ) { - throw new AssertionFailure( "no max results set" ); - } - int firstRow = getFirstRow( selection ); - int lastRow = getMaxOrLimit( selection, dialect ); - boolean hasFirstRow = firstRow > 0 && dialect.supportsLimitOffset(); - boolean reverse = dialect.bindLimitParametersInReverseOrder(); - if ( hasFirstRow ) { - statement.setInt( index + ( reverse ? 1 : 0 ), firstRow ); - } - statement.setInt( index + ( reverse || !hasFirstRow ? 0 : 1 ), lastRow ); - return hasFirstRow ? 2 : 1; - } - - /** - * Use JDBC API to limit the number of rows returned by the SQL query if necessary - */ - private void setMaxRows( - final PreparedStatement st, - final RowSelection selection) throws SQLException { - if ( hasMaxRows( selection ) ) { - st.setMaxRows( selection.getMaxRows().intValue() + getFirstRow( selection ) ); - } - } - - /** * Bind all parameter values into the prepared statement in preparation * for execution. * @@ -1704,7 +1970,7 @@ /** * Bind positional parameter values to the JDBC prepared statement. *

        - * Postional parameters are those specified by JDBC-style ? parameters + * Positional parameters are those specified by JDBC-style ? parameters * in the source query. It is (currently) expected that these come * before any named parameters in the source query. * @@ -1717,10 +1983,10 @@ * @throws org.hibernate.HibernateException Indicates problems delegating binding to the types. */ protected int bindPositionalParameters( - final PreparedStatement statement, - final QueryParameters queryParameters, - final int startIndex, - final SessionImplementor session) throws SQLException, HibernateException { + final PreparedStatement statement, + final QueryParameters queryParameters, + final int startIndex, + final SessionImplementor session) throws SQLException, HibernateException { final Object[] values = queryParameters.getFilteredPositionalParameterValues(); final Type[] types = queryParameters.getFilteredPositionalParameterTypes(); int span = 0; @@ -1751,94 +2017,84 @@ */ protected int bindNamedParameters( final PreparedStatement statement, - final Map namedParams, + final Map namedParams, final int startIndex, final SessionImplementor session) throws SQLException, HibernateException { - if ( namedParams != null ) { - // assumes that types are all of span 1 - Iterator iter = namedParams.entrySet().iterator(); - 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] + startIndex ) + "]" - ); - } - typedval.getType().nullSafeSet( statement, typedval.getValue(), locs[i] + startIndex, session ); + int result = 0; + if ( CollectionHelper.isEmpty( namedParams ) ) { + return result; + } + + for ( String name : namedParams.keySet() ) { + TypedValue typedValue = namedParams.get( name ); + int columnSpan = typedValue.getType().getColumnSpan( getFactory() ); + int[] locs = getNamedParameterLocs( name ); + for ( int loc : locs ) { + if ( DEBUG_ENABLED ) { + LOG.debugf( + "bindNamedParameters() %s -> %s [%s]", + typedValue.getValue(), + name, + loc + startIndex + ); } - result += locs.length; + int start = loc * columnSpan + startIndex; + typedValue.getType().nullSafeSet( statement, typedValue.getValue(), start, session ); } - return result; + result += locs.length; } - else { - return 0; - } + return result; } public int[] getNamedParameterLocs(String name) { throw new AssertionFailure("no named parameters"); } /** - * Fetch a PreparedStatement, call setMaxRows and then execute it, - * advance to the first result and return an SQL ResultSet + * Execute given PreparedStatement, advance to the first result and return SQL ResultSet. */ protected final ResultSet getResultSet( - final PreparedStatement st, - final boolean autodiscovertypes, - final boolean callable, - final RowSelection selection, - final SessionImplementor session) + final PreparedStatement st, + final RowSelection selection, + final LimitHandler limitHandler, + final boolean autodiscovertypes, + final SessionImplementor session) throws SQLException, HibernateException { - - ResultSet rs = null; + try { - Dialect dialect = getFactory().getDialect(); - if (callable) { - rs = session.getBatcher().getResultSet( (CallableStatement) st, dialect ); - } - else { - rs = session.getBatcher().getResultSet( st ); - } + ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st ); rs = wrapResultSetIfEnabled( rs , session ); - - if ( !dialect.supportsLimitOffset() || !useLimit( selection, dialect ) ) { + + if ( !limitHandler.supportsLimitOffset() || !LimitHelper.useLimit( limitHandler, selection ) ) { advance( rs, selection ); } - + if ( autodiscovertypes ) { autoDiscoverTypes( rs ); } return rs; } catch ( SQLException sqle ) { - session.getBatcher().closeQueryStatement( st, rs ); + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); throw sqle; } } protected void autoDiscoverTypes(ResultSet rs) { throw new AssertionFailure("Auto discover types not supported in this loader"); - + } - private synchronized ResultSet wrapResultSetIfEnabled(final ResultSet rs, final SessionImplementor session) { - // synchronized to avoid multi-thread access issues; defined as method synch to avoid - // potential deadlock issues due to nature of code. + private ResultSet wrapResultSetIfEnabled(final ResultSet rs, final SessionImplementor session) { if ( session.getFactory().getSettings().isWrapResultSetsEnabled() ) { try { - log.debug("Wrapping result set [" + rs + "]"); - return new ResultSetWrapper( rs, retreiveColumnNameToIndexCache( rs ) ); + LOG.debugf( "Wrapping result set [%s]", rs ); + return session.getFactory() + .getJdbcServices() + .getResultSetWrapper().wrap( rs, retreiveColumnNameToIndexCache( rs ) ); } catch(SQLException e) { - log.info("Error wrapping result set", e); + LOG.unableToWrapResultSet( e ); return rs; } } @@ -1847,64 +2103,64 @@ } } - private ColumnNameCache retreiveColumnNameToIndexCache(ResultSet rs) throws SQLException { - if ( columnNameCache == null ) { - log.trace("Building columnName->columnIndex cache"); + private ColumnNameCache retreiveColumnNameToIndexCache(final ResultSet rs) throws SQLException { + final ColumnNameCache cache = columnNameCache; + if ( cache == null ) { + //there is no need for a synchronized second check, as in worst case + //we'll have allocated an unnecessary ColumnNameCache + LOG.trace( "Building columnName -> columnIndex cache" ); columnNameCache = new ColumnNameCache( rs.getMetaData().getColumnCount() ); + return columnNameCache; } - - return columnNameCache; + else { + return cache; + } } /** * Called by subclasses that load entities * @param persister only needed for logging + * @param lockOptions */ protected final List loadEntity( - final SessionImplementor session, - final Object id, - final Type identifierType, - final Object optionalObject, - final String optionalEntityName, - final Serializable optionalIdentifier, - final EntityPersister persister) throws HibernateException { - - if ( log.isDebugEnabled() ) { - log.debug( - "loading entity: " + - MessageHelper.infoString( persister, id, identifierType, getFactory() ) - ); + final SessionImplementor session, + final Object id, + final Type identifierType, + final Object optionalObject, + final String optionalEntityName, + final Serializable optionalIdentifier, + final EntityPersister persister, + LockOptions lockOptions) throws HibernateException { + + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Loading entity: %s", MessageHelper.infoString( persister, id, identifierType, getFactory() ) ); } List result; try { - result = doQueryAndInitializeNonLazyCollections( - session, - new QueryParameters( - new Type[] { identifierType }, - new Object[] { id }, - optionalObject, - optionalEntityName, - optionalIdentifier - ), - false - ); + QueryParameters qp = new QueryParameters(); + qp.setPositionalParameterTypes( new Type[] { identifierType } ); + qp.setPositionalParameterValues( new Object[] { id } ); + qp.setOptionalObject( optionalObject ); + qp.setOptionalEntityName( optionalEntityName ); + qp.setOptionalId( optionalIdentifier ); + qp.setLockOptions( lockOptions ); + result = doQueryAndInitializeNonLazyCollections( session, qp, false ); } catch ( SQLException sqle ) { final Loadable[] persisters = getEntityPersisters(); - throw JDBCExceptionHelper.convert( - factory.getSQLExceptionConverter(), + throw factory.getSQLExceptionHelper().convert( sqle, - "could not load an entity: " + + "could not load an entity: " + MessageHelper.infoString( persisters[persisters.length-1], id, identifierType, getFactory() ), getSQLString() ); } - log.debug("done entity load"); - + LOG.debug( "Done entity load" ); + return result; - + } /** @@ -1918,79 +2174,76 @@ final Type keyType, final Type indexType, final EntityPersister persister) throws HibernateException { - - if ( log.isDebugEnabled() ) { - log.debug( "loading collection element by index" ); - } + LOG.debug( "Loading collection element by index" ); + List result; try { - result = doQueryAndInitializeNonLazyCollections( + result = doQueryAndInitializeNonLazyCollections( session, - new QueryParameters( + new QueryParameters( new Type[] { keyType, indexType }, new Object[] { key, index } - ), - false - ); + ), + false + ); } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - factory.getSQLExceptionConverter(), + throw factory.getSQLExceptionHelper().convert( sqle, - "could not collection element by index", + "could not load collection element by index", getSQLString() ); } - log.debug("done entity load"); - + LOG.debug( "Done entity load" ); + return result; - + } /** * Called by wrappers that batch load entities * @param persister only needed for logging + * @param lockOptions */ public final List loadEntityBatch( - final SessionImplementor session, - final Serializable[] ids, - final Type idType, - final Object optionalObject, - final String optionalEntityName, - final Serializable optionalId, - final EntityPersister persister) throws HibernateException { + final SessionImplementor session, + final Serializable[] ids, + final Type idType, + final Object optionalObject, + final String optionalEntityName, + final Serializable optionalId, + final EntityPersister persister, + LockOptions lockOptions) throws HibernateException { - if ( log.isDebugEnabled() ) { - log.debug( - "batch loading entity: " + - MessageHelper.infoString(persister, ids, getFactory() ) - ); - } + if ( LOG.isDebugEnabled() ) + LOG.debugf( "Batch loading entity: %s", MessageHelper.infoString( persister, ids, getFactory() ) ); Type[] types = new Type[ids.length]; Arrays.fill( types, idType ); List result; try { - result = doQueryAndInitializeNonLazyCollections( - session, - new QueryParameters( types, ids, optionalObject, optionalEntityName, optionalId ), - false - ); + QueryParameters qp = new QueryParameters(); + qp.setPositionalParameterTypes( types ); + qp.setPositionalParameterValues( ids ); + qp.setOptionalObject( optionalObject ); + qp.setOptionalEntityName( optionalEntityName ); + qp.setOptionalId( optionalId ); + qp.setLockOptions( lockOptions ); + result = doQueryAndInitializeNonLazyCollections( session, qp, false ); } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - factory.getSQLExceptionConverter(), + throw factory.getSQLExceptionHelper().convert( sqle, - "could not load an entity batch: " + + "could not load an entity batch: " + MessageHelper.infoString( getEntityPersisters()[0], ids, getFactory() ), getSQLString() ); } - log.debug("done entity batch load"); - + LOG.debug( "Done entity batch load" ); + return result; } @@ -2003,99 +2256,90 @@ final Serializable id, final Type type) throws HibernateException { - if ( log.isDebugEnabled() ) { - log.debug( - "loading collection: "+ - MessageHelper.collectionInfoString( getCollectionPersisters()[0], id, getFactory() ) - ); - } + if ( LOG.isDebugEnabled() ) + LOG.debugf( "Loading collection: %s", + MessageHelper.collectionInfoString( getCollectionPersisters()[0], id, getFactory() ) ); Serializable[] ids = new Serializable[]{id}; try { - doQueryAndInitializeNonLazyCollections( + doQueryAndInitializeNonLazyCollections( session, new QueryParameters( new Type[]{type}, ids, ids ), - true + true ); } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - factory.getSQLExceptionConverter(), + throw factory.getSQLExceptionHelper().convert( sqle, - "could not initialize a collection: " + + "could not initialize a collection: " + MessageHelper.collectionInfoString( getCollectionPersisters()[0], id, getFactory() ), getSQLString() ); } - - log.debug("done loading collection"); + LOG.debug( "Done loading collection" ); + } /** * Called by wrappers that batch initialize collections */ public final void loadCollectionBatch( - final SessionImplementor session, - final Serializable[] ids, - final Type type) throws HibernateException { + final SessionImplementor session, + final Serializable[] ids, + final Type type) throws HibernateException { - if ( log.isDebugEnabled() ) { - log.debug( - "batch loading collection: "+ - MessageHelper.collectionInfoString( getCollectionPersisters()[0], ids, getFactory() ) - ); - } + if ( LOG.isDebugEnabled() ) + LOG.debugf( "Batch loading collection: %s", + MessageHelper.collectionInfoString( getCollectionPersisters()[0], ids, getFactory() ) ); Type[] idTypes = new Type[ids.length]; Arrays.fill( idTypes, type ); try { - doQueryAndInitializeNonLazyCollections( + doQueryAndInitializeNonLazyCollections( session, new QueryParameters( idTypes, ids, ids ), - true + true ); } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - factory.getSQLExceptionConverter(), - sqle, - "could not initialize a collection batch: " + - MessageHelper.collectionInfoString( getCollectionPersisters()[0], ids, getFactory() ), - getSQLString() + throw factory.getSQLExceptionHelper().convert( + sqle, + "could not initialize a collection batch: " + + MessageHelper.collectionInfoString( getCollectionPersisters()[0], ids, getFactory() ), + getSQLString() ); } - - log.debug("done batch load"); + LOG.debug( "Done batch load" ); + } /** * Called by subclasses that batch initialize collections */ protected final void loadCollectionSubselect( - final SessionImplementor session, - final Serializable[] ids, - final Object[] parameterValues, - final Type[] parameterTypes, - final Map namedParameters, - final Type type) throws HibernateException { + final SessionImplementor session, + final Serializable[] ids, + final Object[] parameterValues, + final Type[] parameterTypes, + final Map namedParameters, + final Type type) throws HibernateException { Type[] idTypes = new Type[ids.length]; Arrays.fill( idTypes, type ); try { doQueryAndInitializeNonLazyCollections( session, new QueryParameters( parameterTypes, parameterValues, namedParameters, ids ), - true + true ); } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - factory.getSQLExceptionConverter(), - sqle, - "could not load collection by subselect: " + - MessageHelper.collectionInfoString( getCollectionPersisters()[0], ids, getFactory() ), - getSQLString() + throw factory.getSQLExceptionHelper().convert( + sqle, + "could not load collection by subselect: " + + MessageHelper.collectionInfoString( getCollectionPersisters()[0], ids, getFactory() ), + getSQLString() ); } } @@ -2105,12 +2349,12 @@ * by subclasses that implement cacheable queries */ protected List list( - final SessionImplementor session, - final QueryParameters queryParameters, - final Set querySpaces, - final Type[] resultTypes) throws HibernateException { + final SessionImplementor session, + final QueryParameters queryParameters, + final Set querySpaces, + final Type[] resultTypes) throws HibernateException { - final boolean cacheable = factory.getSettings().isQueryCacheEnabled() && + final boolean cacheable = factory.getSettings().isQueryCacheEnabled() && queryParameters.isCacheable(); if ( cacheable ) { @@ -2126,62 +2370,125 @@ } private List listUsingQueryCache( - final SessionImplementor session, - final QueryParameters queryParameters, - final Set querySpaces, + final SessionImplementor session, + final QueryParameters queryParameters, + final Set querySpaces, final Type[] resultTypes) { - + QueryCache queryCache = factory.getQueryCache( queryParameters.getCacheRegion() ); - - Set filterKeys = FilterKey.createFilterKeys( - session.getEnabledFilters(), - session.getEntityMode() + + QueryKey key = generateQueryKey( session, queryParameters ); + + if ( querySpaces == null || querySpaces.size() == 0 ) + LOG.tracev( "Unexpected querySpaces is {0}", ( querySpaces == null ? querySpaces : "empty" ) ); + else { + LOG.tracev( "querySpaces is {0}", querySpaces ); + } + + List result = getResultFromQueryCache( + session, + queryParameters, + querySpaces, + resultTypes, + queryCache, + key ); - QueryKey key = new QueryKey( - getSQLString(), - queryParameters, - filterKeys, - session.getEntityMode() - ); - - List result = getResultFromQueryCache( - session, - queryParameters, - querySpaces, - resultTypes, - queryCache, - key - ); if ( result == null ) { - result = doList( session, queryParameters ); + result = doList( session, queryParameters, key.getResultTransformer() ); - putResultInQueryCache( - session, - queryParameters, + putResultInQueryCache( + session, + queryParameters, resultTypes, - queryCache, - key, - result - ); + queryCache, + key, + result + ); } + ResultTransformer resolvedTransformer = resolveResultTransformer( queryParameters.getResultTransformer() ); + if ( resolvedTransformer != null ) { + result = ( + areResultSetRowsTransformedImmediately() ? + key.getResultTransformer().retransformResults( + result, + getResultRowAliases(), + queryParameters.getResultTransformer(), + includeInResultRow() + ) : + key.getResultTransformer().untransformToTuples( + result + ) + ); + } + return getResultList( result, queryParameters.getResultTransformer() ); } + private QueryKey generateQueryKey( + SessionImplementor session, + QueryParameters queryParameters) { + return QueryKey.generateQueryKey( + getSQLString(), + queryParameters, + FilterKey.createFilterKeys( session.getLoadQueryInfluencers().getEnabledFilters() ), + session, + createCacheableResultTransformer( queryParameters ) + ); + } + + private CacheableResultTransformer createCacheableResultTransformer(QueryParameters queryParameters) { + return CacheableResultTransformer.create( + queryParameters.getResultTransformer(), + getResultRowAliases(), + includeInResultRow() + ); + } + private List getResultFromQueryCache( final SessionImplementor session, final QueryParameters queryParameters, - final Set querySpaces, + final Set querySpaces, final Type[] resultTypes, final QueryCache queryCache, final QueryKey key) { List result = null; if ( session.getCacheMode().isGetEnabled() ) { - boolean isImmutableNaturalKeyLookup = queryParameters.isNaturalKeyLookup() - && getEntityPersisters()[0].getEntityMetamodel().hasImmutableNaturalId(); - result = queryCache.get( key, resultTypes, isImmutableNaturalKeyLookup, querySpaces, session ); + boolean isImmutableNaturalKeyLookup = + queryParameters.isNaturalKeyLookup() && + resultTypes.length == 1 && + resultTypes[0].isEntityType() && + getEntityPersister( EntityType.class.cast( resultTypes[0] ) ) + .getEntityMetamodel() + .hasImmutableNaturalId(); + + final PersistenceContext persistenceContext = session.getPersistenceContext(); + boolean defaultReadOnlyOrig = persistenceContext.isDefaultReadOnly(); + if ( queryParameters.isReadOnlyInitialized() ) { + // The read-only/modifiable mode for the query was explicitly set. + // Temporarily set the default read-only/modifiable setting to the query's setting. + persistenceContext.setDefaultReadOnly( queryParameters.isReadOnly() ); + } + else { + // The read-only/modifiable setting for the query was not initialized. + // Use the default read-only/modifiable from the persistence context instead. + queryParameters.setReadOnly( persistenceContext.isDefaultReadOnly() ); + } + try { + result = queryCache.get( + key, + key.getResultTransformer().getCachedResultTypes( resultTypes ), + isImmutableNaturalKeyLookup, + querySpaces, + session + ); + } + finally { + persistenceContext.setDefaultReadOnly( defaultReadOnlyOrig ); + } + if ( factory.getStatistics().isStatisticsEnabled() ) { if ( result == null ) { factory.getStatisticsImplementor() @@ -2197,15 +2504,25 @@ return result; } - private void putResultInQueryCache( + private EntityPersister getEntityPersister(EntityType entityType) { + return factory.getEntityPersister( entityType.getAssociatedEntityName() ); + } + + protected void putResultInQueryCache( final SessionImplementor session, final QueryParameters queryParameters, final Type[] resultTypes, final QueryCache queryCache, final QueryKey key, final List result) { if ( session.getCacheMode().isPutEnabled() ) { - boolean put = queryCache.put( key, resultTypes, result, queryParameters.isNaturalKeyLookup(), session ); + boolean put = queryCache.put( + key, + key.getResultTransformer().getCachedResultTypes( resultTypes ), + result, + queryParameters.isNaturalKeyLookup(), + session + ); if ( put && factory.getStatistics().isStatisticsEnabled() ) { factory.getStatisticsImplementor() .queryCachePut( getQueryIdentifier(), queryCache.getRegion().getName() ); @@ -2216,23 +2533,30 @@ /** * Actually execute a query, ignoring the query cache */ + protected List doList(final SessionImplementor session, final QueryParameters queryParameters) throws HibernateException { + return doList( session, queryParameters, null); + } + private List doList(final SessionImplementor session, + final QueryParameters queryParameters, + final ResultTransformer forcedResultTransformer) + throws HibernateException { + final boolean stats = getFactory().getStatistics().isStatisticsEnabled(); long startTime = 0; if ( stats ) startTime = System.currentTimeMillis(); List result; try { - result = doQueryAndInitializeNonLazyCollections( session, queryParameters, true ); + result = doQueryAndInitializeNonLazyCollections( session, queryParameters, true, forcedResultTransformer ); } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - factory.getSQLExceptionConverter(), - sqle, - "could not execute query", - getSQLString() + throw factory.getSQLExceptionHelper().convert( + sqle, + "could not execute query", + getSQLString() ); } @@ -2257,7 +2581,6 @@ // whether scrolling of their result set should be allowed. // // By default it is allowed. - return; } /** @@ -2283,10 +2606,10 @@ * the ScrollableResults. */ protected ScrollableResults scroll( - final QueryParameters queryParameters, - final Type[] returnTypes, - final HolderInstantiator holderInstantiator, - final SessionImplementor session) throws HibernateException { + final QueryParameters queryParameters, + final Type[] returnTypes, + final HolderInstantiator holderInstantiator, + final SessionImplementor session) throws HibernateException { checkScrollability(); @@ -2296,10 +2619,12 @@ if ( stats ) startTime = System.currentTimeMillis(); try { + // Don't use Collections#emptyList() here -- follow on locking potentially adds AfterLoadActions, + // so the list cannot be immutable. + final SqlStatementWrapper wrapper = executeQueryStatement( queryParameters, true, new ArrayList(), session ); + final ResultSet rs = wrapper.getResultSet(); + final PreparedStatement st = (PreparedStatement) wrapper.getStatement(); - PreparedStatement st = prepareQueryStatement( queryParameters, true, session ); - ResultSet rs = getResultSet(st, queryParameters.hasAutoDiscoverScalarTypes(), queryParameters.isCallable(), queryParameters.getRowSelection(), session); - if ( stats ) { getFactory().getStatisticsImplementor().queryExecuted( getQueryIdentifier(), @@ -2333,11 +2658,10 @@ } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - factory.getSQLExceptionConverter(), - sqle, - "could not execute query using scroll", - getSQLString() + throw factory.getSQLExceptionHelper().convert( + sqle, + "could not execute query using scroll", + getSQLString() ); } @@ -2368,8 +2692,29 @@ return factory; } + @Override public String toString() { return getClass().getName() + '(' + getSQLString() + ')'; } + /** + * Wrapper class for {@link Statement} and associated {@link ResultSet}. + */ + protected static class SqlStatementWrapper { + private final Statement statement; + private final ResultSet resultSet; + + private SqlStatementWrapper(Statement statement, ResultSet resultSet) { + this.resultSet = resultSet; + this.statement = statement; + } + + public ResultSet getResultSet() { + return resultSet; + } + + public Statement getStatement() { + return statement; + } + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/MultipleBagFetchException.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/OuterJoinLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/OuterJoinLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/OuterJoinLoader.java 17 Aug 2012 14:33:59 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/OuterJoinLoader.java 30 Jul 2014 16:16:43 -0000 1.1.2.1 @@ -23,12 +23,11 @@ * */ package org.hibernate.loader; - -import java.util.Map; - import org.hibernate.LockMode; +import org.hibernate.LockOptions; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.Loadable; import org.hibernate.type.EntityType; @@ -47,22 +46,25 @@ protected CollectionPersister[] collectionPersisters; protected int[] collectionOwners; protected String[] aliases; + private LockOptions lockOptions; protected LockMode[] lockModeArray; protected int[] owners; protected EntityType[] ownerAssociationTypes; protected String sql; protected String[] suffixes; protected String[] collectionSuffixes; - private Map enabledFilters; - - protected final Dialect getDialect() { + private LoadQueryInfluencers loadQueryInfluencers; + + protected final Dialect getDialect() { return getFactory().getDialect(); } - public OuterJoinLoader(SessionFactoryImplementor factory, Map enabledFilters) { - super(factory); - this.enabledFilters = enabledFilters; + public OuterJoinLoader( + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) { + super( factory ); + this.loadQueryInfluencers = loadQueryInfluencers; } protected String[] getSuffixes() { @@ -73,7 +75,8 @@ return collectionSuffixes; } - protected final String getSQLString() { + @Override + public final String getSQLString() { return sql; } @@ -89,14 +92,18 @@ return ownerAssociationTypes; } - protected LockMode[] getLockModes(Map lockModes) { + protected LockMode[] getLockModes(LockOptions lockOptions) { return lockModeArray; } - - public Map getEnabledFilters() { - return enabledFilters; + + protected LockOptions getLockOptions() { + return lockOptions; } + public LoadQueryInfluencers getLoadQueryInfluencers() { + return loadQueryInfluencers; + } + protected final String[] getAliases() { return aliases; } @@ -113,6 +120,7 @@ persisters = walker.getPersisters(); collectionPersisters = walker.getCollectionPersisters(); ownerAssociationTypes = walker.getOwnerAssociationTypes(); + lockOptions = walker.getLockModeOptions(); lockModeArray = walker.getLockModeArray(); suffixes = walker.getSuffixes(); collectionSuffixes = walker.getCollectionSuffixes(); Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/OuterJoinableAssociation.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/OuterJoinableAssociation.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/OuterJoinableAssociation.java 17 Aug 2012 14:33:59 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/OuterJoinableAssociation.java 30 Jul 2014 16:16:43 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,61 +20,104 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.loader; - +import java.util.Collections; import java.util.List; import java.util.Map; import org.hibernate.MappingException; -import org.hibernate.engine.JoinHelper; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.internal.JoinHelper; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.persister.collection.QueryableCollection; import org.hibernate.persister.entity.Joinable; import org.hibernate.sql.JoinFragment; +import org.hibernate.sql.JoinType; import org.hibernate.type.AssociationType; import org.hibernate.type.EntityType; +/** + * Part of the Hibernate SQL rendering internals. This class represents + * a joinable association. + * + * @author Gavin King + */ public final class OuterJoinableAssociation { + private final PropertyPath propertyPath; private final AssociationType joinableType; private final Joinable joinable; private final String lhsAlias; // belong to other persister private final String[] lhsColumns; // belong to other persister private final String rhsAlias; private final String[] rhsColumns; - private final int joinType; + private final JoinType joinType; private final String on; private final Map enabledFilters; + private final boolean hasRestriction; + public static OuterJoinableAssociation createRoot( + AssociationType joinableType, + String alias, + SessionFactoryImplementor factory) { + return new OuterJoinableAssociation( + new PropertyPath(), + joinableType, + null, + null, + alias, + JoinType.LEFT_OUTER_JOIN, + null, + false, + factory, + Collections.EMPTY_MAP + ); + } + public OuterJoinableAssociation( - AssociationType joinableType, - String lhsAlias, - String[] lhsColumns, - String rhsAlias, - int joinType, - SessionFactoryImplementor factory, - Map enabledFilters) - throws MappingException { + PropertyPath propertyPath, + AssociationType joinableType, + String lhsAlias, + String[] lhsColumns, + String rhsAlias, + JoinType joinType, + String withClause, + boolean hasRestriction, + SessionFactoryImplementor factory, + Map enabledFilters) throws MappingException { + this.propertyPath = propertyPath; this.joinableType = joinableType; this.lhsAlias = lhsAlias; this.lhsColumns = lhsColumns; this.rhsAlias = rhsAlias; this.joinType = joinType; this.joinable = joinableType.getAssociatedJoinable(factory); this.rhsColumns = JoinHelper.getRHSColumnNames(joinableType, factory); - this.on = joinableType.getOnCondition(rhsAlias, factory, enabledFilters); + this.on = joinableType.getOnCondition(rhsAlias, factory, enabledFilters) + + ( withClause == null || withClause.trim().length() == 0 ? "" : " and ( " + withClause + " )" ); + this.hasRestriction = hasRestriction; this.enabledFilters = enabledFilters; // needed later for many-to-many/filter application } - public int getJoinType() { + public PropertyPath getPropertyPath() { + return propertyPath; + } + + public JoinType getJoinType() { return joinType; } + public String getLhsAlias() { + return lhsAlias; + } + public String getRHSAlias() { return rhsAlias; } + public String getRhsAlias() { + return rhsAlias; + } + private boolean isOneToOne() { if ( joinableType.isEntityType() ) { EntityType etype = (EntityType) joinableType; @@ -83,7 +126,6 @@ else { return false; } - } public AssociationType getJoinableType() { @@ -102,6 +144,10 @@ return joinable; } + public boolean hasRestriction() { + return hasRestriction; + } + public int getOwner(final List associations) { if ( isOneToOne() || isCollection() ) { return getPosition(lhsAlias, associations); @@ -143,12 +189,8 @@ } public void validateJoin(String path) throws MappingException { - if ( - rhsColumns==null || - lhsColumns==null || - lhsColumns.length!=rhsColumns.length || - lhsColumns.length==0 - ) { + if ( rhsColumns==null || lhsColumns==null + || lhsColumns.length!=rhsColumns.length || lhsColumns.length==0 ) { throw new MappingException("invalid join columns for association: " + path); } } @@ -183,4 +225,4 @@ joinable.whereJoinFragment(rhsAlias, false, true) ); } -} \ No newline at end of file +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/PropertyPath.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/BasicCollectionJoinWalker.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/collection/BasicCollectionJoinWalker.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/BasicCollectionJoinWalker.java 17 Aug 2012 14:34:00 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/BasicCollectionJoinWalker.java 30 Jul 2014 16:16:44 -0000 1.1.2.1 @@ -23,25 +23,26 @@ * */ package org.hibernate.loader.collection; - import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.Set; import org.hibernate.FetchMode; import org.hibernate.LockMode; import org.hibernate.MappingException; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.util.StringHelper; import org.hibernate.loader.BasicLoader; import org.hibernate.loader.OuterJoinableAssociation; +import org.hibernate.loader.PropertyPath; import org.hibernate.persister.collection.QueryableCollection; +import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.sql.JoinFragment; +import org.hibernate.sql.JoinType; import org.hibernate.sql.Select; import org.hibernate.type.AssociationType; -import org.hibernate.util.CollectionHelper; -import org.hibernate.util.StringHelper; /** * Walker for collections of values and many-to-many associations @@ -58,10 +59,9 @@ int batchSize, String subquery, SessionFactoryImplementor factory, - Map enabledFilters) - throws MappingException { + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { - super(factory, enabledFilters); + super( factory, loadQueryInfluencers ); this.collectionPersister = collectionPersister; @@ -71,42 +71,31 @@ List allAssociations = new ArrayList(); allAssociations.addAll(associations); - allAssociations.add( new OuterJoinableAssociation( - collectionPersister.getCollectionType(), - null, - null, - alias, - JoinFragment.LEFT_OUTER_JOIN, - getFactory(), - CollectionHelper.EMPTY_MAP - ) ); - + allAssociations.add( OuterJoinableAssociation.createRoot( collectionPersister.getCollectionType(), alias, getFactory() ) ); initPersisters(allAssociations, LockMode.NONE); initStatementString(alias, batchSize, subquery); - } private void initStatementString( final String alias, final int batchSize, - final String subquery) - throws MappingException { + final String subquery) throws MappingException { final int joins = countEntityPersisters( associations ); final int collectionJoins = countCollectionPersisters( associations ) + 1; suffixes = BasicLoader.generateSuffixes( joins ); collectionSuffixes = BasicLoader.generateSuffixes( joins, collectionJoins ); - StringBuffer whereString = whereString( + StringBuilder whereString = whereString( alias, collectionPersister.getKeyColumnNames(), subquery, batchSize ); String manyToManyOrderBy = ""; - String filter = collectionPersister.filterFragment( alias, getEnabledFilters() ); + String filter = collectionPersister.filterFragment( alias, getLoadQueryInfluencers().getEnabledFilters() ); if ( collectionPersister.isManyToMany() ) { // from the collection of associations, locate OJA for the // ManyToOne corresponding to this persister to fully @@ -121,9 +110,9 @@ // we found it filter += collectionPersister.getManyToManyFilterFragment( oja.getRHSAlias(), - getEnabledFilters() + getLoadQueryInfluencers().getEnabledFilters() ); - manyToManyOrderBy += collectionPersister.getManyToManyOrderByString( oja.getRHSAlias() ); + manyToManyOrderBy += collectionPersister.getManyToManyOrderByString( oja.getRHSAlias() ); } } } @@ -151,37 +140,36 @@ sql = select.toStatementString(); } - /** - * We can use an inner join for first many-to-many association - */ - protected int getJoinType( - AssociationType type, - FetchMode config, - String path, - Set visitedAssociations, + protected JoinType getJoinType( + OuterJoinLoadable persister, + PropertyPath path, + int propertyNumber, + AssociationType associationType, + FetchMode metadataFetchMode, + CascadeStyle metadataCascadeStyle, String lhsTable, String[] lhsColumns, boolean nullable, - int currentDepth) - throws MappingException { - - int joinType = super.getJoinType( - type, - config, - path, - lhsTable, - lhsColumns, - nullable, - currentDepth, - null - ); + int currentDepth) throws MappingException { + JoinType joinType = super.getJoinType( + persister, + path, + propertyNumber, + associationType, + metadataFetchMode, + metadataCascadeStyle, + lhsTable, + lhsColumns, + nullable, + currentDepth + ); //we can use an inner join for the many-to-many - if ( joinType==JoinFragment.LEFT_OUTER_JOIN && "".equals(path) ) { - joinType=JoinFragment.INNER_JOIN; + if ( joinType==JoinType.LEFT_OUTER_JOIN && path.isRoot() ) { + joinType=JoinType.INNER_JOIN; } return joinType; } - + public String toString() { return getClass().getName() + '(' + collectionPersister.getRole() + ')'; } Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/BasicCollectionLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/collection/BasicCollectionLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/BasicCollectionLoader.java 17 Aug 2012 14:34:01 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/BasicCollectionLoader.java 30 Jul 2014 16:16:43 -0000 1.1.2.1 @@ -24,15 +24,15 @@ */ package org.hibernate.loader.collection; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.MappingException; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.CoreMessageLogger; import org.hibernate.loader.JoinWalker; import org.hibernate.persister.collection.QueryableCollection; +import org.jboss.logging.Logger; + /** * Loads a collection of values or a many-to-many association. *
        @@ -44,47 +44,44 @@ */ public class BasicCollectionLoader extends CollectionLoader { - private static final Logger log = LoggerFactory.getLogger(BasicCollectionLoader.class); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, BasicCollectionLoader.class.getName() ); public BasicCollectionLoader( - QueryableCollection collectionPersister, - SessionFactoryImplementor session, - Map enabledFilters) - throws MappingException { - this(collectionPersister, 1, session, enabledFilters); + QueryableCollection collectionPersister, + SessionFactoryImplementor session, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + this( collectionPersister, 1, session, loadQueryInfluencers ); } public BasicCollectionLoader( - QueryableCollection collectionPersister, - int batchSize, - SessionFactoryImplementor factory, - Map enabledFilters) - throws MappingException { - this(collectionPersister, batchSize, null, factory, enabledFilters); + QueryableCollection collectionPersister, + int batchSize, + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + this( collectionPersister, batchSize, null, factory, loadQueryInfluencers ); } - + protected BasicCollectionLoader( - QueryableCollection collectionPersister, - int batchSize, - String subquery, - SessionFactoryImplementor factory, - Map enabledFilters) - throws MappingException { - - super(collectionPersister, factory, enabledFilters); - + QueryableCollection collectionPersister, + int batchSize, + String subquery, + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + super( collectionPersister, factory, loadQueryInfluencers ); + JoinWalker walker = new BasicCollectionJoinWalker( - collectionPersister, - batchSize, - subquery, - factory, - enabledFilters - ); + collectionPersister, + batchSize, + subquery, + factory, + loadQueryInfluencers + ); initFromWalker( walker ); postInstantiate(); - log.debug( "Static select for collection " + collectionPersister.getRole() + ": " + getSQLString() ); + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Static select for collection %s: %s", collectionPersister.getRole(), getSQLString() ); + } } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/BatchingCollectionInitializer.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/collection/BatchingCollectionInitializer.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/BatchingCollectionInitializer.java 17 Aug 2012 14:34:00 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/BatchingCollectionInitializer.java 30 Jul 2014 16:16:43 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2012, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,100 +20,35 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.loader.collection; -import java.io.Serializable; -import java.util.Map; - -import org.hibernate.HibernateException; -import org.hibernate.MappingException; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.loader.Loader; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.QueryableCollection; -import org.hibernate.util.ArrayHelper; /** - * "Batch" loads collections, using multiple foreign key values in the - * SQL where clause. + * The base contract for loaders capable of performing batch-fetch loading of collections using multiple foreign key + * values in the SQL WHERE clause. * + * @author Gavin King + * @author Steve Ebersole + * + * @see BatchingCollectionInitializerBuilder * @see BasicCollectionLoader * @see OneToManyLoader - * @author Gavin King */ -public class BatchingCollectionInitializer implements CollectionInitializer { +public abstract class BatchingCollectionInitializer implements CollectionInitializer { + private final QueryableCollection collectionPersister; - private final Loader[] loaders; - private final int[] batchSizes; - private final CollectionPersister collectionPersister; - - public BatchingCollectionInitializer(CollectionPersister collPersister, int[] batchSizes, Loader[] loaders) { - this.loaders = loaders; - this.batchSizes = batchSizes; - this.collectionPersister = collPersister; + public BatchingCollectionInitializer(QueryableCollection collectionPersister) { + this.collectionPersister = collectionPersister; } - public void initialize(Serializable id, SessionImplementor session) - throws HibernateException { - - Serializable[] batch = session.getPersistenceContext().getBatchFetchQueue() - .getCollectionBatch( collectionPersister, id, batchSizes[0], session.getEntityMode() ); - - for ( int i=0; i1 ) { - int[] batchSizesToCreate = ArrayHelper.getBatchSizes(maxBatchSize); - Loader[] loadersToCreate = new Loader[ batchSizesToCreate.length ]; - for ( int i=0; i1 ) { - int[] batchSizesToCreate = ArrayHelper.getBatchSizes(maxBatchSize); - Loader[] loadersToCreate = new Loader[ batchSizesToCreate.length ]; - for ( int i=0; i1) buf.append('('); buf.append( StringHelper.join(", ", StringHelper.qualify(alias, columnNames) ) ); if (columnNames.length>1) buf.append(')'); Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/CollectionLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/collection/CollectionLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/CollectionLoader.java 17 Aug 2012 14:34:00 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/CollectionLoader.java 30 Jul 2014 16:16:44 -0000 1.1.2.1 @@ -23,13 +23,12 @@ * */ package org.hibernate.loader.collection; - import java.io.Serializable; -import java.util.Map; import org.hibernate.HibernateException; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.loader.OuterJoinLoader; import org.hibernate.persister.collection.QueryableCollection; import org.hibernate.type.Type; @@ -45,11 +44,18 @@ private final QueryableCollection collectionPersister; - public CollectionLoader(QueryableCollection collectionPersister, SessionFactoryImplementor factory, Map enabledFilters) { - super( factory, enabledFilters ); + public CollectionLoader( + QueryableCollection collectionPersister, + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) { + super( factory, loadQueryInfluencers ); this.collectionPersister = collectionPersister; } + protected QueryableCollection collectionPersister() { + return collectionPersister; + } + protected boolean isSubselectLoadingEnabled() { return hasSubselectLoadableCollections(); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/collection/DynamicBatchingCollectionInitializerBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/collection/LegacyBatchingCollectionInitializerBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/OneToManyJoinWalker.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/collection/OneToManyJoinWalker.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/OneToManyJoinWalker.java 17 Aug 2012 14:34:00 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/OneToManyJoinWalker.java 30 Jul 2014 16:16:44 -0000 1.1.2.1 @@ -27,19 +27,18 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Map; import org.hibernate.LockMode; import org.hibernate.MappingException; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.util.StringHelper; import org.hibernate.loader.BasicLoader; import org.hibernate.loader.OuterJoinableAssociation; import org.hibernate.persister.collection.QueryableCollection; import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.sql.JoinFragment; import org.hibernate.sql.Select; -import org.hibernate.util.CollectionHelper; -import org.hibernate.util.StringHelper; /** * Walker for one-to-many associations @@ -51,27 +50,26 @@ private final QueryableCollection oneToManyPersister; - protected boolean isDuplicateAssociation( - final String foreignKeyTable, + @Override + protected boolean isDuplicateAssociation( + final String foreignKeyTable, final String[] foreignKeyColumns ) { //disable a join back to this same association final boolean isSameJoin = oneToManyPersister.getTableName().equals(foreignKeyTable) && Arrays.equals( foreignKeyColumns, oneToManyPersister.getKeyColumnNames() ); - return isSameJoin || + return isSameJoin || super.isDuplicateAssociation(foreignKeyTable, foreignKeyColumns); } public OneToManyJoinWalker( - QueryableCollection oneToManyPersister, - int batchSize, - String subquery, - SessionFactoryImplementor factory, - Map enabledFilters) - throws MappingException { + QueryableCollection oneToManyPersister, + int batchSize, + String subquery, + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + super( factory, loadQueryInfluencers ); - super(factory, enabledFilters); - this.oneToManyPersister = oneToManyPersister; final OuterJoinLoadable elementPersister = (OuterJoinLoadable) oneToManyPersister.getElementPersister(); @@ -81,19 +79,9 @@ List allAssociations = new ArrayList(); allAssociations.addAll(associations); - allAssociations.add( new OuterJoinableAssociation( - oneToManyPersister.getCollectionType(), - null, - null, - alias, - JoinFragment.LEFT_OUTER_JOIN, - getFactory(), - CollectionHelper.EMPTY_MAP - ) ); - + allAssociations.add( OuterJoinableAssociation.createRoot( oneToManyPersister.getCollectionType(), alias, getFactory() ) ); initPersisters(allAssociations, LockMode.NONE); initStatementString(elementPersister, alias, batchSize, subquery); - } private void initStatementString( @@ -109,14 +97,14 @@ final int collectionJoins = countCollectionPersisters( associations ) + 1; collectionSuffixes = BasicLoader.generateSuffixes( joins + 1, collectionJoins ); - StringBuffer whereString = whereString( - alias, - oneToManyPersister.getKeyColumnNames(), + StringBuilder whereString = whereString( + alias, + oneToManyPersister.getKeyColumnNames(), subquery, batchSize ); - String filter = oneToManyPersister.filterFragment( alias, getEnabledFilters() ); - whereString.insert( 0, StringHelper.moveAndToBeginning(filter) ); + String filter = oneToManyPersister.filterFragment( alias, getLoadQueryInfluencers().getEnabledFilters() ); + whereString.insert( 0, StringHelper.moveAndToBeginning( filter ) ); JoinFragment ojf = mergeOuterJoins(associations); Select select = new Select( getDialect() ) @@ -144,7 +132,8 @@ sql = select.toStatementString(); } - public String toString() { + @Override + public String toString() { return getClass().getName() + '(' + oneToManyPersister.getRole() + ')'; } Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/OneToManyLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/collection/OneToManyLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/OneToManyLoader.java 17 Aug 2012 14:34:00 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/OneToManyLoader.java 30 Jul 2014 16:16:43 -0000 1.1.2.1 @@ -24,15 +24,15 @@ */ package org.hibernate.loader.collection; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.MappingException; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.CoreMessageLogger; import org.hibernate.loader.JoinWalker; import org.hibernate.persister.collection.QueryableCollection; +import org.jboss.logging.Logger; + /** * Loads one-to-many associations
        *
        @@ -44,47 +44,43 @@ */ public class OneToManyLoader extends CollectionLoader { - private static final Logger log = LoggerFactory.getLogger(OneToManyLoader.class); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, OneToManyLoader.class.getName() ); public OneToManyLoader( - QueryableCollection oneToManyPersister, - SessionFactoryImplementor session, - Map enabledFilters) - throws MappingException { - this(oneToManyPersister, 1, session, enabledFilters); + QueryableCollection oneToManyPersister, + SessionFactoryImplementor session, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + this( oneToManyPersister, 1, session, loadQueryInfluencers ); } public OneToManyLoader( - QueryableCollection oneToManyPersister, - int batchSize, - SessionFactoryImplementor factory, - Map enabledFilters) - throws MappingException { - this(oneToManyPersister, batchSize, null, factory, enabledFilters); + QueryableCollection oneToManyPersister, + int batchSize, + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + this( oneToManyPersister, batchSize, null, factory, loadQueryInfluencers ); } public OneToManyLoader( - QueryableCollection oneToManyPersister, - int batchSize, - String subquery, - SessionFactoryImplementor factory, - Map enabledFilters) - throws MappingException { + QueryableCollection oneToManyPersister, + int batchSize, + String subquery, + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + super( oneToManyPersister, factory, loadQueryInfluencers ); - super(oneToManyPersister, factory, enabledFilters); - JoinWalker walker = new OneToManyJoinWalker( - oneToManyPersister, - batchSize, - subquery, - factory, - enabledFilters - ); + oneToManyPersister, + batchSize, + subquery, + factory, + loadQueryInfluencers + ); initFromWalker( walker ); postInstantiate(); - - log.debug( "Static select for one-to-many " + oneToManyPersister.getRole() + ": " + getSQLString() ); + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Static select for one-to-many %s: %s", oneToManyPersister.getRole(), getSQLString() ); + } } - } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/collection/PaddedBatchingCollectionInitializerBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/SubselectCollectionLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/collection/SubselectCollectionLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/SubselectCollectionLoader.java 17 Aug 2012 14:34:01 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/SubselectCollectionLoader.java 30 Jul 2014 16:16:44 -0000 1.1.2.1 @@ -23,18 +23,19 @@ * */ package org.hibernate.loader.collection; - import java.io.Serializable; import java.util.Collection; import java.util.Iterator; import java.util.Map; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.engine.EntityKey; -import org.hibernate.engine.QueryParameters; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.EntityKey; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.engine.spi.TypedValue; import org.hibernate.persister.collection.QueryableCollection; import org.hibernate.type.Type; @@ -47,20 +48,18 @@ private final Serializable[] keys; private final Type[] types; private final Object[] values; - private final Map namedParameters; - private final Map namedParameterLocMap; + private final Map namedParameters; + private final Map namedParameterLocMap; public SubselectCollectionLoader( QueryableCollection persister, String subquery, Collection entityKeys, QueryParameters queryParameters, - Map namedParameterLocMap, + Map namedParameterLocMap, SessionFactoryImplementor factory, - Map enabledFilters) - throws MappingException { - - super(persister, 1, subquery, factory, enabledFilters); + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + super( persister, 1, subquery, factory, loadQueryInfluencers ); keys = new Serializable[ entityKeys.size() ]; Iterator iter = entityKeys.iterator(); @@ -76,20 +75,22 @@ } + @Override public void initialize(Serializable id, SessionImplementor session) - throws HibernateException { + throws HibernateException { loadCollectionSubselect( session, keys, values, types, namedParameters, getKeyType() - ); + ); } + @Override public int[] getNamedParameterLocs(String name) { - return (int[]) namedParameterLocMap.get( name ); + return namedParameterLocMap.get( name ); } } Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/SubselectOneToManyLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/collection/SubselectOneToManyLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/SubselectOneToManyLoader.java 17 Aug 2012 14:34:00 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/collection/SubselectOneToManyLoader.java 30 Jul 2014 16:16:44 -0000 1.1.2.1 @@ -23,18 +23,19 @@ * */ package org.hibernate.loader.collection; - import java.io.Serializable; import java.util.Collection; import java.util.Iterator; import java.util.Map; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.engine.EntityKey; -import org.hibernate.engine.QueryParameters; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.EntityKey; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.engine.spi.TypedValue; import org.hibernate.persister.collection.QueryableCollection; import org.hibernate.type.Type; @@ -47,20 +48,18 @@ private final Serializable[] keys; private final Type[] types; private final Object[] values; - private final Map namedParameters; - private final Map namedParameterLocMap; + private final Map namedParameters; + private final Map namedParameterLocMap; public SubselectOneToManyLoader( QueryableCollection persister, String subquery, Collection entityKeys, QueryParameters queryParameters, - Map namedParameterLocMap, + Map namedParameterLocMap, SessionFactoryImplementor factory, - Map enabledFilters) - throws MappingException { - - super(persister, 1, subquery, factory, enabledFilters); + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + super( persister, 1, subquery, factory, loadQueryInfluencers ); keys = new Serializable[ entityKeys.size() ]; Iterator iter = entityKeys.iterator(); @@ -73,23 +72,22 @@ this.types = queryParameters.getFilteredPositionalParameterTypes(); this.values = queryParameters.getFilteredPositionalParameterValues(); this.namedParameterLocMap = namedParameterLocMap; - } - public void initialize(Serializable id, SessionImplementor session) - throws HibernateException { + @Override + public void initialize(Serializable id, SessionImplementor session) throws HibernateException { loadCollectionSubselect( session, keys, values, types, namedParameters, getKeyType() - ); + ); } - + @Override public int[] getNamedParameterLocs(String name) { - return (int[]) namedParameterLocMap.get( name ); + return namedParameterLocMap.get( name ); } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/collection/plan/AbstractBatchingCollectionInitializerBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/collection/plan/AbstractLoadPlanBasedCollectionInitializer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/collection/plan/BatchingCollectionInitializer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/collection/plan/CollectionLoader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/collection/plan/LegacyBatchingCollectionInitializerBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/criteria/ComponentCollectionCriteriaInfoProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/criteria/CriteriaInfoProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/criteria/CriteriaJoinWalker.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/criteria/CriteriaJoinWalker.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/criteria/CriteriaJoinWalker.java 17 Aug 2012 14:33:59 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/criteria/CriteriaJoinWalker.java 30 Jul 2014 16:16:07 -0000 1.1.2.1 @@ -23,27 +23,29 @@ * */ package org.hibernate.loader.criteria; - import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import java.util.Map; import java.util.Set; import org.hibernate.Criteria; import org.hibernate.FetchMode; -import org.hibernate.LockMode; +import org.hibernate.LockOptions; import org.hibernate.MappingException; -import org.hibernate.engine.CascadeStyle; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.impl.CriteriaImpl; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.CriteriaImpl; +import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.loader.AbstractEntityJoinWalker; +import org.hibernate.loader.PropertyPath; +import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.Joinable; import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.persister.entity.Queryable; +import org.hibernate.sql.JoinType; import org.hibernate.type.AssociationType; import org.hibernate.type.Type; -import org.hibernate.type.TypeFactory; -import org.hibernate.util.ArrayHelper; /** * A JoinWalker for Criteria queries. @@ -59,10 +61,14 @@ private final CriteriaQueryTranslator translator; private final Set querySpaces; private final Type[] resultTypes; + private final boolean[] includeInResultRow; + //the user visible aliases, which are unknown to the superclass, //these are not the actual "physical" SQL aliases private final String[] userAliases; - private final List userAliasList = new ArrayList(); + private final List userAliasList = new ArrayList(); + private final List resultTypeList = new ArrayList(); + private final List includeInResultRowList = new ArrayList(); public Type[] getResultTypes() { return resultTypes; @@ -72,14 +78,18 @@ return userAliases; } + public boolean[] includeInResultRow() { + return includeInResultRow; + } + public CriteriaJoinWalker( final OuterJoinLoadable persister, final CriteriaQueryTranslator translator, final SessionFactoryImplementor factory, final CriteriaImpl criteria, final String rootEntityName, - final Map enabledFilters) { - this(persister, translator, factory, criteria, rootEntityName, enabledFilters, null); + final LoadQueryInfluencers loadQueryInfluencers) { + this( persister, translator, factory, criteria, rootEntityName, loadQueryInfluencers, null ); } public CriteriaJoinWalker( @@ -88,80 +98,139 @@ final SessionFactoryImplementor factory, final CriteriaImpl criteria, final String rootEntityName, - final Map enabledFilters, + final LoadQueryInfluencers loadQueryInfluencers, final String alias) { - super(persister, factory, enabledFilters, alias); + super( persister, factory, loadQueryInfluencers, alias ); this.translator = translator; querySpaces = translator.getQuerySpaces(); - if ( translator.hasProjection() ) { - resultTypes = translator.getProjectedTypes(); - - initProjection( + if ( translator.hasProjection() ) { + initProjection( translator.getSelect(), translator.getWhereCondition(), translator.getOrderBy(), translator.getGroupBy(), - LockMode.NONE + LockOptions.NONE ); + resultTypes = translator.getProjectedTypes(); + userAliases = translator.getProjectedAliases(); + includeInResultRow = new boolean[ resultTypes.length ]; + Arrays.fill( includeInResultRow, true ); } else { - resultTypes = new Type[] { TypeFactory.manyToOne( persister.getEntityName() ) }; - - initAll( translator.getWhereCondition(), translator.getOrderBy(), LockMode.NONE ); + initAll( translator.getWhereCondition(), translator.getOrderBy(), LockOptions.NONE ); + // root entity comes last + userAliasList.add( criteria.getAlias() ); //root entity comes *last* + resultTypeList.add( translator.getResultType( criteria ) ); + includeInResultRowList.add( true ); + userAliases = ArrayHelper.toStringArray( userAliasList ); + resultTypes = ArrayHelper.toTypeArray( resultTypeList ); + includeInResultRow = ArrayHelper.toBooleanArray( includeInResultRowList ); } - - userAliasList.add( criteria.getAlias() ); //root entity comes *last* - userAliases = ArrayHelper.toStringArray(userAliasList); - } - - protected int getJoinType( - AssociationType type, - FetchMode config, - String path, + @Override + protected JoinType getJoinType( + OuterJoinLoadable persister, + final PropertyPath path, + int propertyNumber, + AssociationType associationType, + FetchMode metadataFetchMode, + CascadeStyle metadataCascadeStyle, String lhsTable, String[] lhsColumns, - boolean nullable, - int currentDepth, CascadeStyle cascadeStyle) - throws MappingException { - - if ( translator.isJoin(path) ) { - return translator.getJoinType( path ); + final boolean nullable, + final int currentDepth) throws MappingException { + final JoinType resolvedJoinType; + if ( translator.isJoin( path.getFullPath() ) ) { + resolvedJoinType = translator.getJoinType( path.getFullPath() ); } else { if ( translator.hasProjection() ) { - return -1; + resolvedJoinType = JoinType.NONE; } else { - FetchMode fetchMode = translator.getRootCriteria() - .getFetchMode(path); - if ( isDefaultFetchMode(fetchMode) ) { - return super.getJoinType( - type, - config, - path, - lhsTable, - lhsColumns, - nullable, - currentDepth, cascadeStyle + FetchMode fetchMode = translator.getRootCriteria().getFetchMode( path.getFullPath() ); + if ( isDefaultFetchMode( fetchMode ) ) { + if ( persister != null ) { + if ( isJoinFetchEnabledByProfile( persister, path, propertyNumber ) ) { + if ( isDuplicateAssociation( lhsTable, lhsColumns, associationType ) ) { + resolvedJoinType = JoinType.NONE; + } + else if ( isTooDeep(currentDepth) || ( associationType.isCollectionType() && isTooManyCollections() ) ) { + resolvedJoinType = JoinType.NONE; + } + else { + resolvedJoinType = getJoinType( nullable, currentDepth ); + } + } + else { + resolvedJoinType = super.getJoinType( + persister, + path, + propertyNumber, + associationType, + metadataFetchMode, + metadataCascadeStyle, + lhsTable, + lhsColumns, + nullable, + currentDepth + ); + } + } + else { + resolvedJoinType = super.getJoinType( + associationType, + metadataFetchMode, + path, + lhsTable, + lhsColumns, + nullable, + currentDepth, + metadataCascadeStyle ); + + } } else { - if ( fetchMode==FetchMode.JOIN ) { - isDuplicateAssociation(lhsTable, lhsColumns, type); //deliberately ignore return value! - return getJoinType(nullable, currentDepth); + if ( fetchMode == FetchMode.JOIN ) { + isDuplicateAssociation( lhsTable, lhsColumns, associationType ); //deliberately ignore return value! + resolvedJoinType = getJoinType( nullable, currentDepth ); } else { - return -1; + resolvedJoinType = JoinType.NONE; } } } } + return resolvedJoinType; } - + @Override + protected JoinType getJoinType( + AssociationType associationType, + FetchMode config, + PropertyPath path, + String lhsTable, + String[] lhsColumns, + boolean nullable, + int currentDepth, + CascadeStyle cascadeStyle) throws MappingException { + return getJoinType( + null, + path, + -1, + associationType, + config, + cascadeStyle, + lhsTable, + lhsColumns, + nullable, + currentDepth + ); + } + private static boolean isDefaultFetchMode(FetchMode fetchMode) { return fetchMode==null || fetchMode==FetchMode.DEFAULT; } @@ -170,36 +239,74 @@ * Use the discriminator, to narrow the select to instances * of the queried subclass, also applying any filters. */ + @Override protected String getWhereFragment() throws MappingException { return super.getWhereFragment() + - ( (Queryable) getPersister() ).filterFragment( getAlias(), getEnabledFilters() ); + ( (Queryable) getPersister() ).filterFragment( getAlias(), getLoadQueryInfluencers().getEnabledFilters() ); } - - protected String generateTableAlias(int n, String path, Joinable joinable) { - if ( joinable.consumesEntityAlias() ) { - final Criteria subcriteria = translator.getCriteria(path); - String sqlAlias = subcriteria==null ? null : translator.getSQLAlias(subcriteria); - if (sqlAlias!=null) { - userAliasList.add( subcriteria.getAlias() ); //alias may be null - return sqlAlias; //EARLY EXIT + @Override + protected String generateTableAlias(int n, PropertyPath path, Joinable joinable) { + // TODO: deal with side-effects (changes to includeInResultRowList, userAliasList, resultTypeList)!!! + + // for collection-of-entity, we are called twice for given "path" + // once for the collection Joinable, once for the entity Joinable. + // the second call will/must "consume" the alias + perform side effects according to consumesEntityAlias() + // for collection-of-other, however, there is only one call + // it must "consume" the alias + perform side effects, despite what consumeEntityAlias() return says + // + // note: the logic for adding to the userAliasList is still strictly based on consumesEntityAlias return value + boolean checkForSqlAlias = joinable.consumesEntityAlias(); + + if ( !checkForSqlAlias && joinable.isCollection() ) { + // is it a collection-of-other (component or value) ? + CollectionPersister collectionPersister = (CollectionPersister)joinable; + Type elementType = collectionPersister.getElementType(); + if ( elementType.isComponentType() || !elementType.isEntityType() ) { + checkForSqlAlias = true; + } + } + + String sqlAlias = null; + + if ( checkForSqlAlias ) { + final Criteria subcriteria = translator.getCriteria( path.getFullPath() ); + sqlAlias = subcriteria==null ? null : translator.getSQLAlias(subcriteria); + + if (joinable.consumesEntityAlias() && ! translator.hasProjection()) { + includeInResultRowList.add( subcriteria != null && subcriteria.getAlias() != null ); + if (sqlAlias!=null) { + if ( subcriteria.getAlias() != null ) { + userAliasList.add( subcriteria.getAlias() ); + resultTypeList.add( translator.getResultType( subcriteria ) ); + } + } } - else { - userAliasList.add(null); - } } - return super.generateTableAlias( n + translator.getSQLAliasCount(), path, joinable ); - } + if (sqlAlias == null) { + sqlAlias = super.generateTableAlias( n + translator.getSQLAliasCount(), path, joinable ); + } + + return sqlAlias; + } + @Override protected String generateRootAlias(String tableName) { return CriteriaQueryTranslator.ROOT_SQL_ALIAS; } public Set getQuerySpaces() { return querySpaces; } - + @Override public String getComment() { return "criteria query"; } - + @Override + protected String getWithClause(PropertyPath path) { + return translator.getWithClause( path.getFullPath() ); + } + @Override + protected boolean hasRestriction(PropertyPath path) { + return translator.hasRestriction( path.getFullPath() ); + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/criteria/CriteriaLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/criteria/CriteriaLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/criteria/CriteriaLoader.java 17 Aug 2012 14:33:59 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/criteria/CriteriaLoader.java 30 Jul 2014 16:16:07 -0000 1.1.2.1 @@ -1,7 +1,7 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are * distributed under license by Red Hat Middleware LLC. @@ -23,28 +23,33 @@ * */ package org.hibernate.loader.criteria; - +import java.io.Serializable; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.Iterator; import org.hibernate.HibernateException; import org.hibernate.LockMode; +import org.hibernate.LockOptions; import org.hibernate.QueryException; import org.hibernate.ScrollMode; import org.hibernate.ScrollableResults; +import org.hibernate.Session; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.QueryParameters; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.impl.CriteriaImpl; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.CriteriaImpl; +import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.loader.OuterJoinLoader; -import org.hibernate.persister.entity.OuterJoinLoadable; +import org.hibernate.loader.spi.AfterLoadAction; +import org.hibernate.persister.entity.Loadable; import org.hibernate.persister.entity.Lockable; +import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.transform.ResultTransformer; import org.hibernate.type.Type; @@ -64,20 +69,21 @@ // multithreaded, or cacheable!! private final CriteriaQueryTranslator translator; - private final Set querySpaces; + private final Set querySpaces; private final Type[] resultTypes; //the user visible aliases, which are unknown to the superclass, //these are not the actual "physical" SQL aliases private final String[] userAliases; + private final boolean[] includeInResultRow; + private final int resultRowLength; public CriteriaLoader( final OuterJoinLoadable persister, final SessionFactoryImplementor factory, final CriteriaImpl criteria, final String rootEntityName, - final Map enabledFilters) - throws HibernateException { - super(factory, enabledFilters); + final LoadQueryInfluencers loadQueryInfluencers) throws HibernateException { + super( factory, loadQueryInfluencers ); translator = new CriteriaQueryTranslator( factory, @@ -94,13 +100,15 @@ factory, criteria, rootEntityName, - enabledFilters + loadQueryInfluencers ); initFromWalker(walker); userAliases = walker.getUserAliases(); resultTypes = walker.getResultTypes(); + includeInResultRow = walker.includeInResultRow(); + resultRowLength = ArrayHelper.countTrue( includeInResultRow ); postInstantiate(); @@ -118,74 +126,166 @@ return list( session, translator.getQueryParameters(), querySpaces, resultTypes ); } - + @Override + protected String[] getResultRowAliases() { + return userAliases; + } + @Override + protected ResultTransformer resolveResultTransformer(ResultTransformer resultTransformer) { + return translator.getRootCriteria().getResultTransformer(); + } + @Override + protected boolean areResultSetRowsTransformedImmediately() { + return true; + } + @Override + protected boolean[] includeInResultRow() { + return includeInResultRow; + } + @Override protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session) throws SQLException, HibernateException { + return resolveResultTransformer( transformer ).transformTuple( + getResultRow( row, rs, session), + getResultRowAliases() + ); + } + @Override + protected Object[] getResultRow(Object[] row, ResultSet rs, SessionImplementor session) + throws SQLException, HibernateException { final Object[] result; - final String[] aliases; if ( translator.hasProjection() ) { Type[] types = translator.getProjectedTypes(); result = new Object[types.length]; String[] columnAliases = translator.getProjectedColumnAliases(); - for ( int i=0; i 1 ) { + String[] typeColumnAliases = ArrayHelper.slice( columnAliases, pos, numColumns ); + result[i] = types[i].nullSafeGet(rs, typeColumnAliases, session, null); + } + else { + result[i] = types[i].nullSafeGet(rs, columnAliases[pos], session, null); + } + pos += numColumns; } - aliases = translator.getProjectedAliases(); } else { - result = row; - aliases = userAliases; + result = toResultRow( row ); } - return translator.getRootCriteria().getResultTransformer() - .transformTuple(result, aliases); + return result; } + private Object[] toResultRow(Object[] row) { + if ( resultRowLength == row.length ) { + return row; + } + else { + Object[] result = new Object[ resultRowLength ]; + int j = 0; + for ( int i = 0; i < row.length; i++ ) { + if ( includeInResultRow[i] ) result[j++] = row[i]; + } + return result; + } + } + public Set getQuerySpaces() { return querySpaces; } - protected String applyLocks(String sqlSelectString, Map lockModes, Dialect dialect) throws QueryException { - if ( lockModes == null || lockModes.isEmpty() ) { - return sqlSelectString; + @Override + protected String applyLocks( + String sql, + QueryParameters parameters, + Dialect dialect, + List afterLoadActions) throws QueryException { + final LockOptions lockOptions = parameters.getLockOptions(); + if ( lockOptions == null || + ( lockOptions.getLockMode() == LockMode.NONE && lockOptions.getAliasLockCount() == 0 ) ) { + return sql; } - final Map aliasedLockModes = new HashMap(); + if ( dialect.useFollowOnLocking() ) { + final LockMode lockMode = determineFollowOnLockMode( lockOptions ); + if( lockMode != LockMode.UPGRADE_SKIPLOCKED ) { + // Dialect prefers to perform locking in a separate step + LOG.usingFollowOnLocking(); + + final LockOptions lockOptionsToUse = new LockOptions( lockMode ); + lockOptionsToUse.setTimeOut( lockOptions.getTimeOut() ); + lockOptionsToUse.setScope( lockOptions.getScope() ); + + afterLoadActions.add( + new AfterLoadAction() { + @Override + public void afterLoad(SessionImplementor session, Object entity, Loadable persister) { + ( (Session) session ).buildLockRequest( lockOptionsToUse ) + .lock( persister.getEntityName(), entity ); + } + } + ); + parameters.setLockOptions( new LockOptions() ); + return sql; + } + } + final LockOptions locks = new LockOptions(lockOptions.getLockMode()); + locks.setScope( lockOptions.getScope()); + locks.setTimeOut( lockOptions.getTimeOut()); + final Map keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap() : null; final String[] drivingSqlAliases = getAliases(); for ( int i = 0; i < drivingSqlAliases.length; i++ ) { - final LockMode lockMode = ( LockMode ) lockModes.get( drivingSqlAliases[i] ); + final LockMode lockMode = lockOptions.getAliasSpecificLockMode( drivingSqlAliases[i] ); if ( lockMode != null ) { final Lockable drivingPersister = ( Lockable ) getEntityPersisters()[i]; final String rootSqlAlias = drivingPersister.getRootTableAlias( drivingSqlAliases[i] ); - aliasedLockModes.put( rootSqlAlias, lockMode ); + locks.setAliasSpecificLockMode( rootSqlAlias, lockMode ); if ( keyColumnNames != null ) { keyColumnNames.put( rootSqlAlias, drivingPersister.getRootTableIdentifierColumnNames() ); } } } - return dialect.applyLocksToSql( sqlSelectString, aliasedLockModes, keyColumnNames ); + return dialect.applyLocksToSql( sql, locks, keyColumnNames ); } - protected LockMode[] getLockModes(Map lockModes) { + + @Override + protected LockMode determineFollowOnLockMode(LockOptions lockOptions) { + final LockMode lockModeToUse = lockOptions.findGreatestLockMode(); + + if ( lockOptions.getAliasLockCount() > 1 ) { + // > 1 here because criteria always uses alias map for the root lock mode (under 'this_') + LOG.aliasSpecificLockingWithFollowOnLocking( lockModeToUse ); + } + + return lockModeToUse; + } + @Override + protected LockMode[] getLockModes(LockOptions lockOptions) { final String[] entityAliases = getAliases(); if ( entityAliases == null ) { return null; } final int size = entityAliases.length; LockMode[] lockModesArray = new LockMode[size]; for ( int i=0; i criteriaInfoMap = new LinkedHashMap(); + private final Map nameCriteriaInfoMap = new LinkedHashMap(); + private final Map criteriaSQLAliasMap = new HashMap(); + private final Map aliasCriteriaMap = new HashMap(); + private final Map associationPathCriteriaMap = new LinkedHashMap(); + private final Map associationPathJoinTypesMap = new LinkedHashMap(); + private final Map withClauseMap = new HashMap(); + private final SessionFactoryImplementor sessionFactory; + private final SessionFactoryHelper helper; public CriteriaQueryTranslator( final SessionFactoryImplementor factory, @@ -99,13 +106,15 @@ this.rootEntityName = rootEntityName; this.sessionFactory = factory; this.rootSQLAlias = rootSQLAlias; + this.helper = new SessionFactoryHelper(factory); createAliasCriteriaMap(); createAssociationPathCriteriaMap(); createCriteriaEntityNameMap(); createCriteriaSQLAliasMap(); } - + @Override public String generateSQLAlias() { + int aliasCount = 0; return StringHelper.generateAlias( Criteria.ROOT_ALIAS, aliasCount ) + '_'; } @@ -114,37 +123,35 @@ } private Criteria getAliasedCriteria(String alias) { - return ( Criteria ) aliasCriteriaMap.get( alias ); + return aliasCriteriaMap.get( alias ); } public boolean isJoin(String path) { return associationPathCriteriaMap.containsKey( path ); } - public int getJoinType(String path) { - Integer result = ( Integer ) associationPathJoinTypesMap.get( path ); - return ( result == null ? Criteria.INNER_JOIN : result.intValue() ); + public JoinType getJoinType(String path) { + JoinType result = associationPathJoinTypesMap.get( path ); + return ( result == null ? JoinType.INNER_JOIN : result ); } public Criteria getCriteria(String path) { - return ( Criteria ) associationPathCriteriaMap.get( path ); + return associationPathCriteriaMap.get( path ); } - public Set getQuerySpaces() { - Set result = new HashSet(); - Iterator iter = criteriaEntityNames.values().iterator(); - while ( iter.hasNext() ) { - String entityName = ( String ) iter.next(); - result.addAll( Arrays.asList( getFactory().getEntityPersister( entityName ).getQuerySpaces() ) ); + public Set getQuerySpaces() { + Set result = new HashSet(); + for ( CriteriaInfoProvider info : criteriaInfoMap.values() ) { + result.addAll( Arrays.asList( info.getSpaces() ) ); } return result; } private void createAliasCriteriaMap() { aliasCriteriaMap.put( rootCriteria.getAlias(), rootCriteria ); - Iterator iter = rootCriteria.iterateSubcriteria(); + Iterator iter = rootCriteria.iterateSubcriteria(); while ( iter.hasNext() ) { - Criteria subcriteria = ( Criteria ) iter.next(); + Criteria subcriteria = iter.next(); if ( subcriteria.getAlias() != null ) { Object old = aliasCriteriaMap.put( subcriteria.getAlias(), subcriteria ); if ( old != null ) { @@ -155,20 +162,23 @@ } private void createAssociationPathCriteriaMap() { - Iterator iter = rootCriteria.iterateSubcriteria(); + final Iterator iter = rootCriteria.iterateSubcriteria(); while ( iter.hasNext() ) { - CriteriaImpl.Subcriteria crit = ( CriteriaImpl.Subcriteria ) iter.next(); + CriteriaImpl.Subcriteria crit = iter.next(); String wholeAssociationPath = getWholeAssociationPath( crit ); Object old = associationPathCriteriaMap.put( wholeAssociationPath, crit ); if ( old != null ) { throw new QueryException( "duplicate association path: " + wholeAssociationPath ); } - int joinType = crit.getJoinType(); - old = associationPathJoinTypesMap.put( wholeAssociationPath, new Integer( joinType ) ); + JoinType joinType = crit.getJoinType(); + old = associationPathJoinTypesMap.put( wholeAssociationPath, joinType ); if ( old != null ) { // TODO : not so sure this is needed... throw new QueryException( "duplicate association path: " + wholeAssociationPath ); } + if ( crit.getWithClause() != null ) { + this.withClauseMap.put( wholeAssociationPath, crit.getWithClause() ); + } } } @@ -185,7 +195,7 @@ // and the qualifier is not the alias of this criteria // -> check to see if we belong to some criteria other // than the one that created us - parent = ( Criteria ) aliasCriteriaMap.get( testAlias ); + parent = aliasCriteriaMap.get( testAlias ); } } if ( parent == null ) { @@ -207,39 +217,69 @@ } private void createCriteriaEntityNameMap() { - criteriaEntityNames.put( rootCriteria, rootEntityName ); - Iterator iter = associationPathCriteriaMap.entrySet().iterator(); - while ( iter.hasNext() ) { - Map.Entry me = ( Map.Entry ) iter.next(); - criteriaEntityNames.put( - me.getValue(), //the criteria instance - getPathEntityName( ( String ) me.getKey() ) - ); + // initialize the rootProvider first + final CriteriaInfoProvider rootProvider = new EntityCriteriaInfoProvider( + (Queryable) sessionFactory.getEntityPersister( rootEntityName ) + ); + criteriaInfoMap.put( rootCriteria, rootProvider); + nameCriteriaInfoMap.put( rootProvider.getName(), rootProvider ); + + for ( final String key : associationPathCriteriaMap.keySet() ) { + final Criteria value = associationPathCriteriaMap.get( key ); + final CriteriaInfoProvider info = getPathInfo( key ); + criteriaInfoMap.put( value, info ); + nameCriteriaInfoMap.put( info.getName(), info ); } } - private String getPathEntityName(String path) { - Queryable persister = ( Queryable ) sessionFactory.getEntityPersister( rootEntityName ); + + private CriteriaInfoProvider getPathInfo(String path) { StringTokenizer tokens = new StringTokenizer( path, "." ); String componentPath = ""; + + // start with the 'rootProvider' + CriteriaInfoProvider provider = nameCriteriaInfoMap.get( rootEntityName ); + while ( tokens.hasMoreTokens() ) { componentPath += tokens.nextToken(); - Type type = persister.toType( componentPath ); + final Type type = provider.getType( componentPath ); if ( type.isAssociationType() ) { - AssociationType atype = ( AssociationType ) type; - persister = ( Queryable ) sessionFactory.getEntityPersister( - atype.getAssociatedEntityName( sessionFactory ) - ); + // CollectionTypes are always also AssociationTypes - but there's not always an associated entity... + final AssociationType atype = (AssociationType) type; + final CollectionType ctype = type.isCollectionType() ? (CollectionType)type : null; + final Type elementType = (ctype != null) ? ctype.getElementType( sessionFactory ) : null; + // is the association a collection of components or value-types? (i.e a colloction of valued types?) + if ( ctype != null && elementType.isComponentType() ) { + provider = new ComponentCollectionCriteriaInfoProvider( helper.getCollectionPersister(ctype.getRole()) ); + } + else if ( ctype != null && !elementType.isEntityType() ) { + provider = new ScalarCollectionCriteriaInfoProvider( helper, ctype.getRole() ); + } + else { + provider = new EntityCriteriaInfoProvider( + (Queryable) sessionFactory.getEntityPersister( atype.getAssociatedEntityName( sessionFactory ) ) + ); + } + componentPath = ""; } else if ( type.isComponentType() ) { - componentPath += '.'; + if (!tokens.hasMoreTokens()) { + throw new QueryException( + "Criteria objects cannot be created directly on components. Create a criteria on " + + "owning entity and use a dotted property to access component property: " + path + ); + } + else { + componentPath += '.'; + } } else { throw new QueryException( "not an association: " + componentPath ); } } - return persister.getEntityName(); + + return provider; } public int getSQLAliasCount() { @@ -248,16 +288,16 @@ private void createCriteriaSQLAliasMap() { int i = 0; - Iterator criteriaIterator = criteriaEntityNames.entrySet().iterator(); - while ( criteriaIterator.hasNext() ) { - Map.Entry me = ( Map.Entry ) criteriaIterator.next(); - Criteria crit = ( Criteria ) me.getKey(); + for(final Criteria crit : criteriaInfoMap.keySet()){ + final CriteriaInfoProvider value = criteriaInfoMap.get( crit ); String alias = crit.getAlias(); if ( alias == null ) { - alias = ( String ) me.getValue(); // the entity name + // the entity name + alias = value.getName(); } criteriaSQLAliasMap.put( crit, StringHelper.generateAlias( alias, i++ ) ); } + criteriaSQLAliasMap.put( rootCriteria, rootSQLAlias ); } @@ -266,50 +306,63 @@ } public QueryParameters getQueryParameters() { - List values = new ArrayList(); - List types = new ArrayList(); - Iterator iter = rootCriteria.iterateExpressionEntries(); - while ( iter.hasNext() ) { - CriteriaImpl.CriterionEntry ce = ( CriteriaImpl.CriterionEntry ) iter.next(); - TypedValue[] tv = ce.getCriterion().getTypedValues( ce.getCriteria(), this ); - for ( int i = 0; i < tv.length; i++ ) { - values.add( tv[i].getValue() ); - types.add( tv[i].getType() ); - } - } - Object[] valueArray = values.toArray(); - Type[] typeArray = ArrayHelper.toTypeArray( types ); - - RowSelection selection = new RowSelection(); + final RowSelection selection = new RowSelection(); selection.setFirstRow( rootCriteria.getFirstResult() ); selection.setMaxRows( rootCriteria.getMaxResults() ); selection.setTimeout( rootCriteria.getTimeout() ); selection.setFetchSize( rootCriteria.getFetchSize() ); - Map lockModes = new HashMap(); - iter = rootCriteria.getLockModes().entrySet().iterator(); - while ( iter.hasNext() ) { - Map.Entry me = ( Map.Entry ) iter.next(); - final Criteria subcriteria = getAliasedCriteria( ( String ) me.getKey() ); - lockModes.put( getSQLAlias( subcriteria ), me.getValue() ); + final LockOptions lockOptions = new LockOptions(); + final Map lockModeMap = rootCriteria.getLockModes(); + for ( final String key : lockModeMap.keySet() ) { + final Criteria subcriteria = getAliasedCriteria( key ); + lockOptions.setAliasSpecificLockMode( getSQLAlias( subcriteria ), lockModeMap.get( key ) ); } - iter = rootCriteria.iterateSubcriteria(); - while ( iter.hasNext() ) { - CriteriaImpl.Subcriteria subcriteria = ( CriteriaImpl.Subcriteria ) iter.next(); - LockMode lm = subcriteria.getLockMode(); + + final List values = new ArrayList(); + final List types = new ArrayList(); + final Iterator subcriteriaIterator = rootCriteria.iterateSubcriteria(); + while ( subcriteriaIterator.hasNext() ) { + final CriteriaImpl.Subcriteria subcriteria = subcriteriaIterator.next(); + final LockMode lm = subcriteria.getLockMode(); if ( lm != null ) { - lockModes.put( getSQLAlias( subcriteria ), lm ); + lockOptions.setAliasSpecificLockMode( getSQLAlias( subcriteria ), lm ); } + if ( subcriteria.getWithClause() != null ) { + final TypedValue[] tv = subcriteria.getWithClause().getTypedValues( subcriteria, this ); + for ( TypedValue aTv : tv ) { + values.add( aTv.getValue() ); + types.add( aTv.getType() ); + } + } } + // Type and value gathering for the WHERE clause needs to come AFTER lock mode gathering, + // because the lock mode gathering loop now contains join clauses which can contain + // parameter bindings (as in the HQL WITH clause). + final Iterator iter = rootCriteria.iterateExpressionEntries(); + while ( iter.hasNext() ) { + final CriteriaImpl.CriterionEntry ce = iter.next(); + final TypedValue[] tv = ce.getCriterion().getTypedValues( ce.getCriteria(), this ); + for ( TypedValue aTv : tv ) { + values.add( aTv.getValue() ); + types.add( aTv.getType() ); + } + } + + final Object[] valueArray = values.toArray(); + final Type[] typeArray = ArrayHelper.toTypeArray( types ); return new QueryParameters( typeArray, valueArray, - lockModes, + lockOptions, selection, + rootCriteria.isReadOnlyInitialized(), + ( rootCriteria.isReadOnlyInitialized() && rootCriteria.isReadOnly() ), rootCriteria.getCacheable(), rootCriteria.getCacheRegion(), rootCriteria.getComment(), + rootCriteria.getQueryHints(), rootCriteria.isLookupByNaturalKey(), rootCriteria.getResultTransformer() ); @@ -337,23 +390,30 @@ ); } + /* package-protected */ + Type getResultType(Criteria criteria) { + return getFactory().getTypeResolver().getTypeFactory().manyToOne( getEntityName( criteria ) ); + } + public Type[] getProjectedTypes() { return rootCriteria.getProjection().getTypes( rootCriteria, this ); } public String[] getProjectedColumnAliases() { - return rootCriteria.getProjection().getColumnAliases( 0 ); + return rootCriteria.getProjection() instanceof EnhancedProjection ? + ( ( EnhancedProjection ) rootCriteria.getProjection() ).getColumnAliases( 0, rootCriteria, this ) : + rootCriteria.getProjection().getColumnAliases( 0 ); } public String[] getProjectedAliases() { return rootCriteria.getProjection().getAliases(); } public String getWhereCondition() { - StringBuffer condition = new StringBuffer( 30 ); - Iterator criterionIterator = rootCriteria.iterateExpressionEntries(); + StringBuilder condition = new StringBuilder( 30 ); + Iterator criterionIterator = rootCriteria.iterateExpressionEntries(); while ( criterionIterator.hasNext() ) { - CriteriaImpl.CriterionEntry entry = ( CriteriaImpl.CriterionEntry ) criterionIterator.next(); + CriteriaImpl.CriterionEntry entry = criterionIterator.next(); String sqlString = entry.getCriterion().toSqlString( entry.getCriteria(), this ); condition.append( sqlString ); if ( criterionIterator.hasNext() ) { @@ -364,30 +424,31 @@ } public String getOrderBy() { - StringBuffer orderBy = new StringBuffer( 30 ); - Iterator criterionIterator = rootCriteria.iterateOrderings(); + StringBuilder orderBy = new StringBuilder( 30 ); + Iterator criterionIterator = rootCriteria.iterateOrderings(); while ( criterionIterator.hasNext() ) { - CriteriaImpl.OrderEntry oe = ( CriteriaImpl.OrderEntry ) criterionIterator.next(); + CriteriaImpl.OrderEntry oe = criterionIterator.next(); orderBy.append( oe.getOrder().toSqlString( oe.getCriteria(), this ) ); if ( criterionIterator.hasNext() ) { orderBy.append( ", " ); } } return orderBy.toString(); } - + @Override public SessionFactoryImplementor getFactory() { return sessionFactory; } - + @Override public String getSQLAlias(Criteria criteria) { - return ( String ) criteriaSQLAliasMap.get( criteria ); + return criteriaSQLAliasMap.get( criteria ); } - + @Override public String getEntityName(Criteria criteria) { - return ( String ) criteriaEntityNames.get( criteria ); + final CriteriaInfoProvider infoProvider = criteriaInfoMap.get( criteria ); + return infoProvider != null ? infoProvider.getName() : null; } - + @Override public String getColumn(Criteria criteria, String propertyName) { String[] cols = getColumns( propertyName, criteria ); if ( cols.length != 1 ) { @@ -400,16 +461,20 @@ * Get the names of the columns constrained * by this criterion. */ + @Override public String[] getColumnsUsingProjection( Criteria subcriteria, String propertyName) throws HibernateException { //first look for a reference to a projection alias final Projection projection = rootCriteria.getProjection(); - String[] projectionColumns = projection == null ? - null : - projection.getColumnAliases( propertyName, 0 ); - + String[] projectionColumns = null; + if ( projection != null ) { + projectionColumns = ( projection instanceof EnhancedProjection ? + ( ( EnhancedProjection ) projection ).getColumnAliases( propertyName, 0, rootCriteria, this ) : + projection.getColumnAliases( propertyName, 0 ) + ); + } if ( projectionColumns == null ) { //it does not refer to an alias of a projection, //look for a property @@ -431,27 +496,23 @@ return projectionColumns; } } - - public String[] getIdentifierColumns(Criteria subcriteria) { + @Override + public String[] getIdentifierColumns(Criteria criteria) { String[] idcols = - ( ( Loadable ) getPropertyMapping( getEntityName( subcriteria ) ) ).getIdentifierColumnNames(); - return StringHelper.qualify( getSQLAlias( subcriteria ), idcols ); + ( ( Loadable ) getPropertyMapping( getEntityName( criteria ) ) ).getIdentifierColumnNames(); + return StringHelper.qualify( getSQLAlias( criteria ), idcols ); } - - public Type getIdentifierType(Criteria subcriteria) { - return ( ( Loadable ) getPropertyMapping( getEntityName( subcriteria ) ) ).getIdentifierType(); + @Override + public Type getIdentifierType(Criteria criteria) { + return ( ( Loadable ) getPropertyMapping( getEntityName( criteria ) ) ).getIdentifierType(); } - - public TypedValue getTypedIdentifierValue(Criteria subcriteria, Object value) { - final Loadable loadable = ( Loadable ) getPropertyMapping( getEntityName( subcriteria ) ); - return new TypedValue( - loadable.getIdentifierType(), - value, - EntityMode.POJO - ); + @Override + public TypedValue getTypedIdentifierValue(Criteria criteria, Object value) { + final Loadable loadable = ( Loadable ) getPropertyMapping( getEntityName( criteria ) ); + return new TypedValue( loadable.getIdentifierType(), value ); } - - private String[] getColumns( + @Override + public String[] getColumns( String propertyName, Criteria subcriteria) throws HibernateException { return getPropertyMapping( getEntityName( subcriteria, propertyName ) ) @@ -461,6 +522,28 @@ ); } + /** + * Get the names of the columns mapped by a property path; if the + * property path is not found in subcriteria, try the "outer" query. + * Projection aliases are ignored. + */ + @Override + public String[] findColumns(String propertyName, Criteria subcriteria ) + throws HibernateException { + try { + return getColumns( propertyName, subcriteria ); + } + catch ( HibernateException he ) { + //not found in inner query, try the outer query + if ( outerQueryTranslator != null ) { + return outerQueryTranslator.findColumns( propertyName, subcriteria ); + } + else { + throw he; + } + } + } + @Override public Type getTypeUsingProjection(Criteria subcriteria, String propertyName) throws HibernateException { @@ -494,7 +577,7 @@ return projectionTypes[0]; } } - + @Override public Type getType(Criteria subcriteria, String propertyName) throws HibernateException { return getPropertyMapping( getEntityName( subcriteria, propertyName ) ) @@ -504,76 +587,89 @@ /** * Get the a typed value for the given property value. */ - public TypedValue getTypedValue(Criteria subcriteria, String propertyName, Object value) - throws HibernateException { + @Override + public TypedValue getTypedValue(Criteria subcriteria, String propertyName, Object value) throws HibernateException { // Detect discriminator values... if ( value instanceof Class ) { - Class entityClass = ( Class ) value; - Queryable q = SessionFactoryHelper.findQueryableUsingImports( sessionFactory, entityClass.getName() ); + final Class entityClass = (Class) value; + final Queryable q = SessionFactoryHelper.findQueryableUsingImports( sessionFactory, entityClass.getName() ); if ( q != null ) { - Type type = q.getDiscriminatorType(); + final Type type = q.getDiscriminatorType(); String stringValue = q.getDiscriminatorSQLValue(); + if ( stringValue != null + && stringValue.length() > 2 + && stringValue.startsWith( "'" ) + && stringValue.endsWith( "'" ) ) { + // remove the single quotes + stringValue = stringValue.substring( 1, stringValue.length() - 1 ); + } + // Convert the string value into the proper type. - if ( type instanceof NullableType ) { - NullableType nullableType = ( NullableType ) type; + if ( type instanceof StringRepresentableType ) { + final StringRepresentableType nullableType = (StringRepresentableType) type; value = nullableType.fromStringValue( stringValue ); } else { throw new QueryException( "Unsupported discriminator type " + type ); } - return new TypedValue( - type, - value, - EntityMode.POJO - ); + return new TypedValue( type, value ); } } // Otherwise, this is an ordinary value. - return new TypedValue( - getTypeUsingProjection( subcriteria, propertyName ), - value, - EntityMode.POJO - ); + return new TypedValue( getTypeUsingProjection( subcriteria, propertyName ), value ); } - private PropertyMapping getPropertyMapping(String entityName) - throws MappingException { - return ( PropertyMapping ) sessionFactory.getEntityPersister( entityName ); + private PropertyMapping getPropertyMapping(String entityName) throws MappingException { + final CriteriaInfoProvider info = nameCriteriaInfoMap.get( entityName ); + if ( info == null ) { + throw new HibernateException( "Unknown entity: " + entityName ); + } + return info.getPropertyMapping(); } //TODO: use these in methods above - + @Override public String getEntityName(Criteria subcriteria, String propertyName) { if ( propertyName.indexOf( '.' ) > 0 ) { - String root = StringHelper.root( propertyName ); - Criteria crit = getAliasedCriteria( root ); + final String root = StringHelper.root( propertyName ); + final Criteria crit = getAliasedCriteria( root ); if ( crit != null ) { return getEntityName( crit ); } } return getEntityName( subcriteria ); } - + @Override public String getSQLAlias(Criteria criteria, String propertyName) { if ( propertyName.indexOf( '.' ) > 0 ) { - String root = StringHelper.root( propertyName ); - Criteria subcriteria = getAliasedCriteria( root ); + final String root = StringHelper.root( propertyName ); + final Criteria subcriteria = getAliasedCriteria( root ); if ( subcriteria != null ) { return getSQLAlias( subcriteria ); } } return getSQLAlias( criteria ); } - + @Override public String getPropertyName(String propertyName) { if ( propertyName.indexOf( '.' ) > 0 ) { - String root = StringHelper.root( propertyName ); - Criteria crit = getAliasedCriteria( root ); - if ( crit != null ) { + final String root = StringHelper.root( propertyName ); + final Criteria criteria = getAliasedCriteria( root ); + if ( criteria != null ) { return propertyName.substring( root.length() + 1 ); } } return propertyName; } + public String getWithClause(String path) { + final Criterion criterion = withClauseMap.get( path ); + return criterion == null ? null : criterion.toSqlString( getCriteria( path ), this ); + } + + public boolean hasRestriction(String path) { + final CriteriaImpl.Subcriteria subcriteria = (CriteriaImpl.Subcriteria) getCriteria( path ); + return subcriteria != null && subcriteria.hasRestriction(); + } + } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/criteria/EntityCriteriaInfoProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/criteria/ScalarCollectionCriteriaInfoProvider.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CollectionFetchReturn.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CollectionFetchReturn.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CollectionFetchReturn.java 17 Aug 2012 14:33:54 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CollectionFetchReturn.java 30 Jul 2014 16:16:52 -0000 1.1.2.1 @@ -23,13 +23,12 @@ * */ package org.hibernate.loader.custom; - +import org.hibernate.LockMode; import org.hibernate.loader.CollectionAliases; import org.hibernate.loader.EntityAliases; -import org.hibernate.LockMode; /** - * Spefically a fetch return that refers to a collection association. + * Specifically a fetch return that refers to a collection association. * * @author Steve Ebersole */ Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CollectionReturn.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CollectionReturn.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CollectionReturn.java 17 Aug 2012 14:33:54 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CollectionReturn.java 30 Jul 2014 16:16:52 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.loader.custom; - import org.hibernate.LockMode; import org.hibernate.loader.CollectionAliases; import org.hibernate.loader.EntityAliases; Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/ColumnCollectionAliases.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/custom/ColumnCollectionAliases.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/ColumnCollectionAliases.java 17 Aug 2012 14:33:53 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/ColumnCollectionAliases.java 30 Jul 2014 16:16:51 -0000 1.1.2.1 @@ -26,14 +26,14 @@ import java.util.Map; +import org.hibernate.internal.util.StringHelper; import org.hibernate.loader.CollectionAliases; import org.hibernate.persister.collection.SQLLoadableCollection; -import org.hibernate.util.StringHelper; /** * CollectionAliases that uses columnnames instead of generated aliases. * Aliases can still be overwritten via - * + * * @author Max Rydahl Andersen * */ @@ -43,29 +43,29 @@ private final String[] elementAliases; private final String identifierAlias; private Map userProvidedAliases; - - + + public ColumnCollectionAliases(Map userProvidedAliases, SQLLoadableCollection persister) { this.userProvidedAliases = userProvidedAliases; this.keyAliases = getUserProvidedAliases( - "key", + "key", persister.getKeyColumnNames() ); this.indexAliases = getUserProvidedAliases( "index", persister.getIndexColumnNames() ); - - this.elementAliases = getUserProvidedAliases( "element", + + this.elementAliases = getUserProvidedAliases( "element", persister.getElementColumnNames() ); - - this.identifierAlias = getUserProvidedAlias( "id", + + this.identifierAlias = getUserProvidedAlias( "id", persister.getIdentifierColumnName() ); - + } @@ -115,7 +115,8 @@ return ""; } - public String toString() { + @Override + public String toString() { return super.toString() + " [ suffixedKeyAliases=[" + join( keyAliases ) + "], suffixedIndexAliases=[" + join( indexAliases ) + "], suffixedElementAliases=[" + join( elementAliases ) + @@ -127,12 +128,12 @@ return StringHelper.join( ", ", aliases ); } - + private String[] getUserProvidedAliases(String propertyPath, String[] defaultAliases) { String[] result = (String[]) userProvidedAliases.get(propertyPath); if (result==null) { - return defaultAliases; - } + return defaultAliases; + } else { return result; } @@ -142,7 +143,7 @@ String[] columns = (String[]) userProvidedAliases.get(propertyPath); if (columns==null) { return defaultAlias; - } + } else { return columns[0]; } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/custom/ConstructorResultColumnProcessor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/custom/ConstructorReturn.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CustomLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CustomLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CustomLoader.java 17 Aug 2012 14:33:54 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CustomLoader.java 30 Jul 2014 16:16:51 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,54 +20,59 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.loader.custom; +import java.io.Serializable; import java.sql.ResultSet; -import java.sql.ResultSetMetaData; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.HashSet; import org.hibernate.HibernateException; import org.hibernate.LockMode; +import org.hibernate.LockOptions; import org.hibernate.QueryException; import org.hibernate.ScrollableResults; -import org.hibernate.engine.QueryParameters; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.hql.HolderInstantiator; +import org.hibernate.Session; +import org.hibernate.cache.spi.QueryCache; +import org.hibernate.cache.spi.QueryKey; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.hql.internal.HolderInstantiator; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.loader.CollectionAliases; import org.hibernate.loader.EntityAliases; import org.hibernate.loader.Loader; +import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.QueryableCollection; import org.hibernate.persister.entity.Loadable; import org.hibernate.persister.entity.Queryable; import org.hibernate.transform.ResultTransformer; -import org.hibernate.type.Type; -import org.hibernate.type.TypeFactory; -import org.hibernate.type.EntityType; import org.hibernate.type.CollectionType; -import org.hibernate.util.ArrayHelper; +import org.hibernate.type.EntityType; +import org.hibernate.type.Type; + /** * Extension point for loaders which use a SQL result set with "unexpected" column aliases. - * + * * @author Gavin King * @author Steve Ebersole */ public class CustomLoader extends Loader { - + // Currently *not* cachable if autodiscover types is in effect (e.g. "select * ...") private final String sql; - private final Set querySpaces = new HashSet(); + private final Set querySpaces = new HashSet(); private final Map namedParameterBindPoints; private final Queryable[] entityPersisters; @@ -79,6 +84,9 @@ private final CollectionAliases[] collectionAliases; private final LockMode[] lockModes; + + private boolean[] includeInResultRow; + // private final String[] sqlAliases; // private final String[] sqlAliasSuffixes; private final ResultRowProcessor rowProcessor; @@ -90,118 +98,142 @@ // this is only needed (afaict) for ResultTransformer processing... private String[] transformerAliases; - public CustomLoader(CustomQuery customQuery, SessionFactoryImplementor factory) { super( factory ); this.sql = customQuery.getSQL(); this.querySpaces.addAll( customQuery.getQuerySpaces() ); this.namedParameterBindPoints = customQuery.getNamedParameterBindPoints(); - List entityPersisters = new ArrayList(); - List entityOwners = new ArrayList(); - List entityAliases = new ArrayList(); + List entityPersisters = new ArrayList(); + List entityOwners = new ArrayList(); + List entityAliases = new ArrayList(); - List collectionPersisters = new ArrayList(); - List collectionOwners = new ArrayList(); - List collectionAliases = new ArrayList(); + List collectionPersisters = new ArrayList(); + List collectionOwners = new ArrayList(); + List collectionAliases = new ArrayList(); - List lockModes = new ArrayList(); - List resultColumnProcessors = new ArrayList(); - List nonScalarReturnList = new ArrayList(); - List resultTypes = new ArrayList(); - List specifiedAliases = new ArrayList(); + List lockModes = new ArrayList(); + List resultColumnProcessors = new ArrayList(); + List nonScalarReturnList = new ArrayList(); + List resultTypes = new ArrayList(); + List specifiedAliases = new ArrayList(); + int returnableCounter = 0; boolean hasScalars = false; - Iterator itr = customQuery.getCustomQueryReturns().iterator(); - while ( itr.hasNext() ) { - final Return rtn = ( Return ) itr.next(); + List includeInResultRowList = new ArrayList(); + + for ( Return rtn : customQuery.getCustomQueryReturns() ) { if ( rtn instanceof ScalarReturn ) { - ScalarReturn scalarRtn = ( ScalarReturn ) rtn; + ScalarReturn scalarRtn = (ScalarReturn) rtn; resultTypes.add( scalarRtn.getType() ); specifiedAliases.add( scalarRtn.getColumnAlias() ); resultColumnProcessors.add( new ScalarResultColumnProcessor( - scalarRtn.getColumnAlias(), + StringHelper.unquote( scalarRtn.getColumnAlias(), factory.getDialect() ), scalarRtn.getType() ) ); + includeInResultRowList.add( true ); hasScalars = true; } + else if ( ConstructorReturn.class.isInstance( rtn ) ) { + final ConstructorReturn constructorReturn = (ConstructorReturn) rtn; + resultTypes.add( null ); // this bit makes me nervous + includeInResultRowList.add( true ); + hasScalars = true; + + ScalarResultColumnProcessor[] scalarProcessors = new ScalarResultColumnProcessor[constructorReturn.getScalars().length]; + int i = 0; + for ( ScalarReturn scalarReturn : constructorReturn.getScalars() ) { + scalarProcessors[i++] = new ScalarResultColumnProcessor( + StringHelper.unquote( scalarReturn.getColumnAlias(), factory.getDialect() ), + scalarReturn.getType() + ); + } + + resultColumnProcessors.add( + new ConstructorResultColumnProcessor( constructorReturn.getTargetClass(), scalarProcessors ) + ); + } else if ( rtn instanceof RootReturn ) { - RootReturn rootRtn = ( RootReturn ) rtn; - Queryable persister = ( Queryable ) factory.getEntityPersister( rootRtn.getEntityName() ); + RootReturn rootRtn = (RootReturn) rtn; + Queryable persister = (Queryable) factory.getEntityPersister( rootRtn.getEntityName() ); entityPersisters.add( persister ); - lockModes.add( rootRtn.getLockMode() ); + lockModes.add( (rootRtn.getLockMode()) ); resultColumnProcessors.add( new NonScalarResultColumnProcessor( returnableCounter++ ) ); nonScalarReturnList.add( rtn ); - entityOwners.add( new Integer( -1 ) ); + entityOwners.add( -1 ); resultTypes.add( persister.getType() ); specifiedAliases.add( rootRtn.getAlias() ); entityAliases.add( rootRtn.getEntityAliases() ); ArrayHelper.addAll( querySpaces, persister.getQuerySpaces() ); + includeInResultRowList.add( true ); } else if ( rtn instanceof CollectionReturn ) { - CollectionReturn collRtn = ( CollectionReturn ) rtn; + CollectionReturn collRtn = (CollectionReturn) rtn; String role = collRtn.getOwnerEntityName() + "." + collRtn.getOwnerProperty(); - QueryableCollection persister = ( QueryableCollection ) factory.getCollectionPersister( role ); + QueryableCollection persister = (QueryableCollection) factory.getCollectionPersister( role ); collectionPersisters.add( persister ); lockModes.add( collRtn.getLockMode() ); resultColumnProcessors.add( new NonScalarResultColumnProcessor( returnableCounter++ ) ); nonScalarReturnList.add( rtn ); - collectionOwners.add( new Integer( -1 ) ); + collectionOwners.add( -1 ); resultTypes.add( persister.getType() ); specifiedAliases.add( collRtn.getAlias() ); collectionAliases.add( collRtn.getCollectionAliases() ); // determine if the collection elements are entities... Type elementType = persister.getElementType(); if ( elementType.isEntityType() ) { - Queryable elementPersister = ( Queryable ) ( ( EntityType ) elementType ).getAssociatedJoinable( factory ); + Queryable elementPersister = (Queryable) ((EntityType) elementType).getAssociatedJoinable( factory ); entityPersisters.add( elementPersister ); - entityOwners.add( new Integer( -1 ) ); + entityOwners.add( -1 ); entityAliases.add( collRtn.getElementEntityAliases() ); ArrayHelper.addAll( querySpaces, elementPersister.getQuerySpaces() ); } + includeInResultRowList.add( true ); } else if ( rtn instanceof EntityFetchReturn ) { - EntityFetchReturn fetchRtn = ( EntityFetchReturn ) rtn; + EntityFetchReturn fetchRtn = (EntityFetchReturn) rtn; NonScalarReturn ownerDescriptor = fetchRtn.getOwner(); int ownerIndex = nonScalarReturnList.indexOf( ownerDescriptor ); - entityOwners.add( new Integer( ownerIndex ) ); + entityOwners.add( ownerIndex ); lockModes.add( fetchRtn.getLockMode() ); Queryable ownerPersister = determineAppropriateOwnerPersister( ownerDescriptor ); - EntityType fetchedType = ( EntityType ) ownerPersister.getPropertyType( fetchRtn.getOwnerProperty() ); + EntityType fetchedType = (EntityType) ownerPersister.getPropertyType( fetchRtn.getOwnerProperty() ); String entityName = fetchedType.getAssociatedEntityName( getFactory() ); - Queryable persister = ( Queryable ) factory.getEntityPersister( entityName ); + Queryable persister = (Queryable) factory.getEntityPersister( entityName ); entityPersisters.add( persister ); nonScalarReturnList.add( rtn ); specifiedAliases.add( fetchRtn.getAlias() ); entityAliases.add( fetchRtn.getEntityAliases() ); ArrayHelper.addAll( querySpaces, persister.getQuerySpaces() ); + includeInResultRowList.add( false ); } else if ( rtn instanceof CollectionFetchReturn ) { - CollectionFetchReturn fetchRtn = ( CollectionFetchReturn ) rtn; + CollectionFetchReturn fetchRtn = (CollectionFetchReturn) rtn; NonScalarReturn ownerDescriptor = fetchRtn.getOwner(); int ownerIndex = nonScalarReturnList.indexOf( ownerDescriptor ); - collectionOwners.add( new Integer( ownerIndex ) ); + collectionOwners.add( ownerIndex ); lockModes.add( fetchRtn.getLockMode() ); Queryable ownerPersister = determineAppropriateOwnerPersister( ownerDescriptor ); String role = ownerPersister.getEntityName() + '.' + fetchRtn.getOwnerProperty(); - QueryableCollection persister = ( QueryableCollection ) factory.getCollectionPersister( role ); + QueryableCollection persister = (QueryableCollection) factory.getCollectionPersister( role ); collectionPersisters.add( persister ); nonScalarReturnList.add( rtn ); specifiedAliases.add( fetchRtn.getAlias() ); collectionAliases.add( fetchRtn.getCollectionAliases() ); // determine if the collection elements are entities... Type elementType = persister.getElementType(); if ( elementType.isEntityType() ) { - Queryable elementPersister = ( Queryable ) ( ( EntityType ) elementType ).getAssociatedJoinable( factory ); + Queryable elementPersister = (Queryable) ((EntityType) elementType).getAssociatedJoinable( factory ); entityPersisters.add( elementPersister ); - entityOwners.add( new Integer( ownerIndex ) ); + entityOwners.add( ownerIndex ); entityAliases.add( fetchRtn.getElementEntityAliases() ); ArrayHelper.addAll( querySpaces, elementPersister.getQuerySpaces() ); } + includeInResultRowList.add( false ); } else { throw new HibernateException( "unexpected custom query return type : " + rtn.getClass().getName() ); @@ -210,36 +242,38 @@ this.entityPersisters = new Queryable[ entityPersisters.size() ]; for ( int i = 0; i < entityPersisters.size(); i++ ) { - this.entityPersisters[i] = ( Queryable ) entityPersisters.get( i ); + this.entityPersisters[i] = entityPersisters.get( i ); } this.entiytOwners = ArrayHelper.toIntArray( entityOwners ); this.entityAliases = new EntityAliases[ entityAliases.size() ]; for ( int i = 0; i < entityAliases.size(); i++ ) { - this.entityAliases[i] = ( EntityAliases ) entityAliases.get( i ); + this.entityAliases[i] = entityAliases.get( i ); } this.collectionPersisters = new QueryableCollection[ collectionPersisters.size() ]; for ( int i = 0; i < collectionPersisters.size(); i++ ) { - this.collectionPersisters[i] = ( QueryableCollection ) collectionPersisters.get( i ); + this.collectionPersisters[i] = collectionPersisters.get( i ); } this.collectionOwners = ArrayHelper.toIntArray( collectionOwners ); this.collectionAliases = new CollectionAliases[ collectionAliases.size() ]; for ( int i = 0; i < collectionAliases.size(); i++ ) { - this.collectionAliases[i] = ( CollectionAliases ) collectionAliases.get( i ); + this.collectionAliases[i] = collectionAliases.get( i ); } this.lockModes = new LockMode[ lockModes.size() ]; for ( int i = 0; i < lockModes.size(); i++ ) { - this.lockModes[i] = ( LockMode ) lockModes.get( i ); + this.lockModes[i] = lockModes.get( i ); } this.resultTypes = ArrayHelper.toTypeArray( resultTypes ); this.transformerAliases = ArrayHelper.toStringArray( specifiedAliases ); this.rowProcessor = new ResultRowProcessor( hasScalars, - ( ResultColumnProcessor[] ) resultColumnProcessors.toArray( new ResultColumnProcessor[ resultColumnProcessors.size() ] ) + resultColumnProcessors.toArray( new ResultColumnProcessor[ resultColumnProcessors.size() ] ) ); + + this.includeInResultRow = ArrayHelper.toBooleanArray( includeInResultRowList ); } private Queryable determineAppropriateOwnerPersister(NonScalarReturn ownerDescriptor) { @@ -276,71 +310,130 @@ return ( Queryable ) getFactory().getEntityPersister( entityName ); } - protected String getQueryIdentifier() { + @Override + protected String getQueryIdentifier() { return sql; } - protected String getSQLString() { + @Override + public String getSQLString() { return sql; } public Set getQuerySpaces() { return querySpaces; } - protected LockMode[] getLockModes(Map lockModesMap) { + @Override + protected LockMode[] getLockModes(LockOptions lockOptions) { return lockModes; } - protected Loadable[] getEntityPersisters() { + @Override + protected Loadable[] getEntityPersisters() { return entityPersisters; } - protected CollectionPersister[] getCollectionPersisters() { + @Override + protected CollectionPersister[] getCollectionPersisters() { return collectionPersisters; } - protected int[] getCollectionOwners() { + @Override + protected int[] getCollectionOwners() { return collectionOwners; } - - protected int[] getOwners() { + + @Override + protected int[] getOwners() { return entiytOwners; } public List list(SessionImplementor session, QueryParameters queryParameters) throws HibernateException { return list( session, queryParameters, querySpaces, resultTypes ); } - public ScrollableResults scroll( - final QueryParameters queryParameters, - final SessionImplementor session) throws HibernateException { + @Override + protected String applyLocks( + String sql, + QueryParameters parameters, + Dialect dialect, + List afterLoadActions) throws QueryException { + final LockOptions lockOptions = parameters.getLockOptions(); + if ( lockOptions == null || + ( lockOptions.getLockMode() == LockMode.NONE && lockOptions.getAliasLockCount() == 0 ) ) { + return sql; + } + + // user is request locking, lets see if we can apply locking directly to the SQL... + + // some dialects wont allow locking with paging... + afterLoadActions.add( + new AfterLoadAction() { + private final LockOptions originalLockOptions = lockOptions.makeCopy(); + @Override + public void afterLoad(SessionImplementor session, Object entity, Loadable persister) { + ( (Session) session ).buildLockRequest( originalLockOptions ).lock( persister.getEntityName(), entity ); + } + } + ); + parameters.getLockOptions().setLockMode( LockMode.READ ); + + return sql; + } + + public ScrollableResults scroll(final QueryParameters queryParameters, final SessionImplementor session) + throws HibernateException { return scroll( queryParameters, resultTypes, getHolderInstantiator( queryParameters.getResultTransformer(), getReturnAliasesForTransformer() ), session ); } - + static private HolderInstantiator getHolderInstantiator(ResultTransformer resultTransformer, String[] queryReturnAliases) { - if ( resultTransformer != null ) { + if ( resultTransformer == null ) { return HolderInstantiator.NOOP_INSTANTIATOR; } else { return new HolderInstantiator(resultTransformer, queryReturnAliases); } } - - protected Object getResultColumnOrRow( + + @Override + protected String[] getResultRowAliases() { + return transformerAliases; + } + + @Override + protected ResultTransformer resolveResultTransformer(ResultTransformer resultTransformer) { + return HolderInstantiator.resolveResultTransformer( null, resultTransformer ); + } + + @Override + protected boolean[] includeInResultRow() { + return includeInResultRow; + } + + @Override + protected Object getResultColumnOrRow( Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session) throws SQLException, HibernateException { return rowProcessor.buildResultRow( row, rs, transformer != null, session ); } - protected List getResultList(List results, ResultTransformer resultTransformer) throws QueryException { + @Override + protected Object[] getResultRow(Object[] row, ResultSet rs, SessionImplementor session) + throws SQLException, HibernateException { + return rowProcessor.buildResultRow( row, rs, session ); + } + + @Override + @SuppressWarnings("unchecked") + protected List getResultList(List results, ResultTransformer resultTransformer) throws QueryException { // meant to handle dynamic instantiation queries...(Copy from QueryLoader) HolderInstantiator holderInstantiator = HolderInstantiator.getHolderInstantiator( null, @@ -353,7 +446,7 @@ Object result = holderInstantiator.instantiate(row); results.set( i, result ); } - + return resultTransformer.transformList(results); } else { @@ -364,16 +457,19 @@ private String[] getReturnAliasesForTransformer() { return transformerAliases; } - - protected EntityAliases[] getEntityAliases() { + + @Override + protected EntityAliases[] getEntityAliases() { return entityAliases; } - protected CollectionAliases[] getCollectionAliases() { + @Override + protected CollectionAliases[] getCollectionAliases() { return collectionAliases; } - - public int[] getNamedParameterLocs(String name) throws QueryException { + + @Override + public int[] getNamedParameterLocs(String name) throws QueryException { Object loc = namedParameterBindPoints.get( name ); if ( loc == null ) { throw new QueryException( @@ -382,148 +478,28 @@ ); } if ( loc instanceof Integer ) { - return new int[] { ( ( Integer ) loc ).intValue() }; + return new int[] { (Integer) loc }; } else { return ArrayHelper.toIntArray( ( List ) loc ); } } - public class ResultRowProcessor { - private final boolean hasScalars; - private ResultColumnProcessor[] columnProcessors; - - public ResultRowProcessor(boolean hasScalars, ResultColumnProcessor[] columnProcessors) { - this.hasScalars = hasScalars || ( columnProcessors == null || columnProcessors.length == 0 ); - this.columnProcessors = columnProcessors; - } - - public void prepareForAutoDiscovery(Metadata metadata) throws SQLException { - if ( columnProcessors == null || columnProcessors.length == 0 ) { - int columns = metadata.getColumnCount(); - columnProcessors = new ResultColumnProcessor[ columns ]; - for ( int i = 1; i <= columns; i++ ) { - columnProcessors[ i - 1 ] = new ScalarResultColumnProcessor( i ); - } - - } - } - - /** - * Build a logical result row. - *

        - * At this point, Loader has already processed all non-scalar result data. We - * just need to account for scalar result data here... - * - * @param data Entity data defined as "root returns" and already handled by the - * normal Loader mechanism. - * @param resultSet The JDBC result set (positioned at the row currently being processed). - * @param hasTransformer Does this query have an associated {@link ResultTransformer} - * @param session The session from which the query request originated. - * @return The logical result row - * @throws SQLException - * @throws HibernateException - */ - public Object buildResultRow( - Object[] data, - ResultSet resultSet, - boolean hasTransformer, - SessionImplementor session) throws SQLException, HibernateException { - Object[] resultRow; - if ( !hasScalars ) { - resultRow = data; - } - else { - // build an array with indices equal to the total number - // of actual returns in the result Hibernate will return - // for this query (scalars + non-scalars) - resultRow = new Object[ columnProcessors.length ]; - for ( int i = 0; i < columnProcessors.length; i++ ) { - resultRow[i] = columnProcessors[i].extract( data, resultSet, session ); - } - } - - return ( hasTransformer ) - ? resultRow - : ( resultRow.length == 1 ) - ? resultRow[0] - : resultRow; - } - } - - private static interface ResultColumnProcessor { - public Object extract(Object[] data, ResultSet resultSet, SessionImplementor session) throws SQLException, HibernateException; - public void performDiscovery(Metadata metadata, List types, List aliases) throws SQLException, HibernateException; - } - - public class NonScalarResultColumnProcessor implements ResultColumnProcessor { - private final int position; - - public NonScalarResultColumnProcessor(int position) { - this.position = position; - } - - public Object extract( - Object[] data, - ResultSet resultSet, - SessionImplementor session) throws SQLException, HibernateException { - return data[ position ]; - } - - public void performDiscovery(Metadata metadata, List types, List aliases) { - } - - } - - public class ScalarResultColumnProcessor implements ResultColumnProcessor { - private int position = -1; - private String alias; - private Type type; - - public ScalarResultColumnProcessor(int position) { - this.position = position; - } - - public ScalarResultColumnProcessor(String alias, Type type) { - this.alias = alias; - this.type = type; - } - - public Object extract( - Object[] data, - ResultSet resultSet, - SessionImplementor session) throws SQLException, HibernateException { - return type.nullSafeGet( resultSet, alias, session, null ); - } - - public void performDiscovery(Metadata metadata, List types, List aliases) throws SQLException { - if ( alias == null ) { - alias = metadata.getColumnName( position ); - } - else if ( position < 0 ) { - position = metadata.resolveColumnPosition( alias ); - } - if ( type == null ) { - type = metadata.getHibernateType( position ); - } - types.add( type ); - aliases.add( alias ); - } - } - - protected void autoDiscoverTypes(ResultSet rs) { + @Override + protected void autoDiscoverTypes(ResultSet rs) { try { - Metadata metadata = new Metadata( getFactory(), rs ); - List aliases = new ArrayList(); - List types = new ArrayList(); - + JdbcResultMetadata metadata = new JdbcResultMetadata( getFactory(), rs ); rowProcessor.prepareForAutoDiscovery( metadata ); - for ( int i = 0; i < rowProcessor.columnProcessors.length; i++ ) { - rowProcessor.columnProcessors[i].performDiscovery( metadata, types, aliases ); + List aliases = new ArrayList(); + List types = new ArrayList(); + for ( ResultColumnProcessor resultProcessor : rowProcessor.getColumnProcessors() ) { + resultProcessor.performDiscovery( metadata, types, aliases ); } + validateAliases( aliases ); + resultTypes = ArrayHelper.toTypeArray( types ); transformerAliases = ArrayHelper.toStringArray( aliases ); } @@ -532,61 +508,50 @@ } } - private static class Metadata { - private final SessionFactoryImplementor factory; - private final ResultSet resultSet; - private final ResultSetMetaData resultSetMetaData; - - public Metadata(SessionFactoryImplementor factory, ResultSet resultSet) throws HibernateException { - try { - this.factory = factory; - this.resultSet = resultSet; - this.resultSetMetaData = resultSet.getMetaData(); + private void validateAliases(List aliases) { + // lets make sure we did not end up with duplicate aliases. this can occur when the user supplied query + // did not rename same-named columns. e.g.: + // select u.username, u2.username from t_user u, t_user u2 ... + // + // the above will lead to an unworkable situation in most cases (the difference is how the driver/db + // handle this situation. But if the 'aliases' variable contains duplicate names, then we have that + // troublesome condition, so lets throw an error. See HHH-5992 + final HashSet aliasesSet = new HashSet(); + for ( String alias : aliases ) { + validateAlias( alias ); + boolean alreadyExisted = !aliasesSet.add( alias ); + if ( alreadyExisted ) { + throw new NonUniqueDiscoveredSqlAliasException( + "Encountered a duplicated sql alias [" + alias + "] during auto-discovery of a native-sql query" + ); } - catch( SQLException e ) { - throw new HibernateException( "Could not extract result set metadata", e ); - } } + } - public int getColumnCount() throws HibernateException { - try { - return resultSetMetaData.getColumnCount(); - } - catch( SQLException e ) { - throw new HibernateException( "Could not determine result set column count", e ); - } - } - - public int resolveColumnPosition(String columnName) throws HibernateException { - try { - return resultSet.findColumn( columnName ); - } - catch( SQLException e ) { - throw new HibernateException( "Could not resolve column name in result set [" + columnName + "]", e ); - } - } - - public String getColumnName(int position) throws HibernateException { - try { - return resultSetMetaData.getColumnName( position ); - } - catch( SQLException e ) { - throw new HibernateException( "Could not resolve column name [" + position + "]", e ); - } - } - - public Type getHibernateType(int columnPos) throws SQLException { - int columnType = resultSetMetaData.getColumnType( columnPos ); - int scale = resultSetMetaData.getScale( columnPos ); - int precision = resultSetMetaData.getPrecision( columnPos ); - return TypeFactory.heuristicType( - factory.getDialect().getHibernateTypeName( - columnType, - precision, - precision, - scale - ) - ); - } + @SuppressWarnings("UnusedParameters") + protected void validateAlias(String alias) { } + + /** + * {@link #resultTypes} can be overridden by {@link #autoDiscoverTypes(ResultSet)}, + * *after* {@link #list(SessionImplementor, QueryParameters)} has already been called. It's a bit of a + * chicken-and-the-egg issue since {@link #autoDiscoverTypes(ResultSet)} needs the {@link ResultSet}. + * + * As a hacky workaround, override + * {@link #putResultInQueryCache(SessionImplementor, QueryParameters, Type[], QueryCache, QueryKey, List)} here + * and provide the {@link #resultTypes}. + * + * @see HHH-3051 + */ + @Override + protected void putResultInQueryCache( + final SessionImplementor session, + final QueryParameters queryParameters, + final Type[] resultTypes, + final QueryCache queryCache, + final QueryKey key, + final List result) { + super.putResultInQueryCache( session, queryParameters, this.resultTypes, queryCache, key, result ); + } + } Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CustomQuery.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CustomQuery.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CustomQuery.java 17 Aug 2012 14:33:54 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/CustomQuery.java 30 Jul 2014 16:16:52 -0000 1.1.2.1 @@ -23,10 +23,9 @@ * */ package org.hibernate.loader.custom; - +import java.util.List; import java.util.Map; import java.util.Set; -import java.util.List; /** * Extension point allowing any SQL query with named and positional parameters @@ -51,7 +50,7 @@ * * @return The query spaces */ - public Set getQuerySpaces(); + public Set getQuerySpaces(); /** * A map representing positions within the supplied {@link #getSQL query} to @@ -74,5 +73,5 @@ * * @return List of return descriptors. */ - public List getCustomQueryReturns(); + public List getCustomQueryReturns(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/EntityFetchReturn.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/custom/EntityFetchReturn.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/EntityFetchReturn.java 17 Aug 2012 14:33:54 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/EntityFetchReturn.java 30 Jul 2014 16:16:52 -0000 1.1.2.1 @@ -23,9 +23,8 @@ * */ package org.hibernate.loader.custom; - -import org.hibernate.loader.EntityAliases; import org.hibernate.LockMode; +import org.hibernate.loader.EntityAliases; /** * Spefically a fetch return that refers to an entity association. Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/FetchReturn.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/custom/FetchReturn.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/FetchReturn.java 17 Aug 2012 14:33:54 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/FetchReturn.java 30 Jul 2014 16:16:51 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.loader.custom; - import org.hibernate.LockMode; /** Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/custom/JdbcResultMetadata.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/custom/NonScalarResultColumnProcessor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/NonScalarReturn.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/custom/NonScalarReturn.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/NonScalarReturn.java 17 Aug 2012 14:33:54 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/NonScalarReturn.java 30 Jul 2014 16:16:52 -0000 1.1.2.1 @@ -23,9 +23,8 @@ * */ package org.hibernate.loader.custom; - -import org.hibernate.LockMode; import org.hibernate.HibernateException; +import org.hibernate.LockMode; /** * Represents some non-scalar (entity/collection) return within the query result. Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/custom/NonUniqueDiscoveredSqlAliasException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/custom/ResultColumnProcessor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/custom/ResultRowProcessor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/Return.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/custom/Return.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/Return.java 17 Aug 2012 14:33:54 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/Return.java 30 Jul 2014 16:16:51 -0000 1.1.2.1 @@ -24,6 +24,7 @@ */ package org.hibernate.loader.custom; + /** * Represents a return in a custom query. * Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/RootReturn.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/custom/RootReturn.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/RootReturn.java 17 Aug 2012 14:33:53 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/RootReturn.java 30 Jul 2014 16:16:51 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.loader.custom; - import org.hibernate.LockMode; import org.hibernate.loader.EntityAliases; Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/custom/ScalarResultColumnProcessor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/ScalarReturn.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/custom/ScalarReturn.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/ScalarReturn.java 17 Aug 2012 14:33:54 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/ScalarReturn.java 30 Jul 2014 16:16:52 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.loader.custom; - import org.hibernate.type.Type; /** Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/sql/SQLCustomQuery.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/custom/sql/SQLCustomQuery.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/sql/SQLCustomQuery.java 17 Aug 2012 14:33:41 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/sql/SQLCustomQuery.java 30 Jul 2014 16:16:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,39 +20,40 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.loader.custom.sql; +import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.HashMap; import org.hibernate.HibernateException; -import org.hibernate.engine.query.sql.NativeSQLQueryReturn; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.CoreMessageLogger; import org.hibernate.loader.custom.CustomQuery; import org.hibernate.persister.collection.SQLLoadableCollection; import org.hibernate.persister.entity.SQLLoadable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.jboss.logging.Logger; + /** * Implements Hibernate's built-in support for native SQL queries. *

        * This support is built on top of the notion of "custom queries"... - * + * * @author Gavin King * @author Max Andersen * @author Steve Ebersole */ -public class SQLCustomQuery implements CustomQuery { +public class SQLCustomQuery implements CustomQuery, Serializable { - public static final Logger log = LoggerFactory.getLogger( SQLCustomQuery.class ); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, SQLCustomQuery.class.getName() ); private final String sql; private final Set querySpaces = new HashSet(); @@ -82,7 +83,7 @@ final Collection additionalQuerySpaces, final SessionFactoryImplementor factory) throws HibernateException { - log.trace( "starting processing of sql query [" + sqlQuery + "]" ); + LOG.tracev( "Starting processing of sql query [{0}]", sqlQuery ); SQLQueryReturnProcessor processor = new SQLQueryReturnProcessor(queryReturns, factory); SQLQueryReturnProcessor.ResultAliasContext aliasContext = processor.process(); @@ -129,7 +130,7 @@ // // String[] suffixes = BasicLoader.generateSuffixes(entityPersisters.length); - SQLQueryParser parser = new SQLQueryParser( sqlQuery, new ParserContext( aliasContext ) ); + SQLQueryParser parser = new SQLQueryParser( sqlQuery, new ParserContext( aliasContext ), factory ); this.sql = parser.process(); this.namedParameterBindPoints.putAll( parser.getNamedParameters() ); Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/sql/SQLQueryParser.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/custom/sql/SQLQueryParser.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/sql/SQLQueryParser.java 17 Aug 2012 14:33:41 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/sql/SQLQueryParser.java 30 Jul 2014 16:16:58 -0000 1.1.2.1 @@ -23,29 +23,35 @@ * */ package org.hibernate.loader.custom.sql; - -import org.hibernate.QueryException; -import org.hibernate.engine.query.ParameterParser; -import org.hibernate.persister.collection.SQLLoadableCollection; -import org.hibernate.persister.entity.SQLLoadable; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.hibernate.QueryException; +import org.hibernate.engine.query.spi.ParameterParser; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.persister.collection.SQLLoadableCollection; +import org.hibernate.persister.entity.SQLLoadable; + /** * @author Gavin King * @author Max Andersen * @author Steve Ebersole + * @author Paul Benedict */ public class SQLQueryParser { + private static final String HIBERNATE_PLACEHOLDER_PREFIX = "h-"; + private static final String DOMAIN_PLACEHOLDER = "h-domain"; + private static final String CATALOG_PLACEHOLDER = "h-catalog"; + private static final String SCHEMA_PLACEHOLDER = "h-schema"; + private final SessionFactoryImplementor factory; private final String originalQueryString; private final ParserContext context; private final Map namedParameters = new HashMap(); - private long aliasesFound = 0; + private long aliasesFound; static interface ParserContext { boolean isEntityAlias(String aliasName); @@ -57,9 +63,10 @@ Map getPropertyResultsMapByAlias(String alias); } - public SQLQueryParser(String queryString, ParserContext context) { + public SQLQueryParser(String queryString, ParserContext context, SessionFactoryImplementor factory) { this.originalQueryString = queryString; this.context = context; + this.factory = factory; } public Map getNamedParameters() { @@ -71,14 +78,16 @@ } public String process() { - return substituteParams( substituteBrackets( originalQueryString ) ); + String processedSql = substituteBrackets( originalQueryString ); + processedSql = substituteParams( processedSql ); + return processedSql; } // TODO: should "record" how many properties we have reffered to - and if we // don't get'em'all we throw an exception! Way better than trial and error ;) private String substituteBrackets(String sqlQuery) throws QueryException { - StringBuffer result = new StringBuffer( sqlQuery.length() + 20 ); + StringBuilder result = new StringBuilder( sqlQuery.length() + 20 ); int left, right; // replace {....} with corresponding column aliases @@ -97,41 +106,75 @@ throw new QueryException( "Unmatched braces for alias path", sqlQuery ); } - String aliasPath = sqlQuery.substring( left + 1, right ); - int firstDot = aliasPath.indexOf( '.' ); - if ( firstDot == -1 ) { - if ( context.isEntityAlias( aliasPath ) ) { - // it is a simple table alias {foo} - result.append( aliasPath ); - aliasesFound++; + final String aliasPath = sqlQuery.substring( left + 1, right ); + boolean isPlaceholder = aliasPath.startsWith( HIBERNATE_PLACEHOLDER_PREFIX ); + + if ( isPlaceholder ) { + // Domain replacement + if ( DOMAIN_PLACEHOLDER.equals( aliasPath ) ) { + final String catalogName = factory.getSettings().getDefaultCatalogName(); + if ( catalogName != null ) { + result.append( catalogName ); + result.append( "." ); + } + final String schemaName = factory.getSettings().getDefaultSchemaName(); + if ( schemaName != null ) { + result.append( schemaName ); + result.append( "." ); + } + } + // Schema replacement + else if ( SCHEMA_PLACEHOLDER.equals( aliasPath ) ) { + final String schemaName = factory.getSettings().getDefaultSchemaName(); + if ( schemaName != null ) { + result.append(schemaName); + result.append("."); + } } + // Catalog replacement + else if ( CATALOG_PLACEHOLDER.equals( aliasPath ) ) { + final String catalogName = factory.getSettings().getDefaultCatalogName(); + if ( catalogName != null ) { + result.append( catalogName ); + result.append( "." ); + } + } else { - // passing through anything we do not know : to support jdbc escape sequences HB-898 - result.append( '{' ).append(aliasPath).append( '}' ); + throw new QueryException( "Unknown placeholder ", aliasPath ); } } else { - String aliasName = aliasPath.substring(0, firstDot); - boolean isCollection = context.isCollectionAlias( aliasName ); - boolean isEntity = context.isEntityAlias( aliasName ); - - if ( isCollection ) { - // The current alias is referencing the collection to be eagerly fetched - String propertyName = aliasPath.substring( firstDot + 1 ); - result.append( resolveCollectionProperties( aliasName, propertyName ) ); - aliasesFound++; - } - else if ( isEntity ) { - // it is a property reference {foo.bar} - String propertyName = aliasPath.substring( firstDot + 1 ); - result.append( resolveProperties( aliasName, propertyName ) ); - aliasesFound++; + int firstDot = aliasPath.indexOf( '.' ); + if ( firstDot == -1 ) { + if ( context.isEntityAlias( aliasPath ) ) { + // it is a simple table alias {foo} + result.append( aliasPath ); + aliasesFound++; + } + else { + // passing through anything we do not know : to support jdbc escape sequences HB-898 + result.append( '{' ).append(aliasPath).append( '}' ); + } } else { - // passing through anything we do not know : to support jdbc escape sequences HB-898 - result.append( '{' ).append(aliasPath).append( '}' ); + final String aliasName = aliasPath.substring( 0, firstDot ); + if ( context.isCollectionAlias( aliasName ) ) { + // The current alias is referencing the collection to be eagerly fetched + String propertyName = aliasPath.substring( firstDot + 1 ); + result.append( resolveCollectionProperties( aliasName, propertyName ) ); + aliasesFound++; + } + else if ( context.isEntityAlias( aliasName ) ) { + // it is a property reference {foo.bar} + String propertyName = aliasPath.substring( firstDot + 1 ); + result.append( resolveProperties( aliasName, propertyName ) ); + aliasesFound++; + } + else { + // passing through anything we do not know : to support jdbc escape sequences HB-898 + result.append( '{' ).append(aliasPath).append( '}' ); + } } - } } @@ -252,33 +295,38 @@ } public static class ParameterSubstitutionRecognizer implements ParameterParser.Recognizer { - StringBuffer result = new StringBuffer(); + StringBuilder result = new StringBuilder(); Map namedParameterBindPoints = new HashMap(); - int parameterCount = 0; + int parameterCount; + @Override public void outParameter(int position) { result.append( '?' ); } + @Override public void ordinalParameter(int position) { result.append( '?' ); } + @Override public void namedParameter(String name, int position) { addNamedParameter( name ); result.append( '?' ); } + @Override public void jpaPositionalParameter(String name, int position) { namedParameter( name, position ); } + @Override public void other(char character) { result.append( character ); } private void addNamedParameter(String name) { - Integer loc = new Integer( parameterCount++ ); + Integer loc = parameterCount++; Object o = namedParameterBindPoints.get( name ); if ( o == null ) { namedParameterBindPoints.put( name, loc ); Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java 17 Aug 2012 14:33:41 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java 30 Jul 2014 16:16:58 -0000 1.1.2.1 @@ -25,46 +25,53 @@ package org.hibernate.loader.custom.sql; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.loader.custom.Return; -import org.hibernate.loader.custom.ScalarReturn; -import org.hibernate.loader.custom.RootReturn; +import org.hibernate.engine.query.spi.sql.NativeSQLQueryCollectionReturn; +import org.hibernate.engine.query.spi.sql.NativeSQLQueryConstructorReturn; +import org.hibernate.engine.query.spi.sql.NativeSQLQueryJoinReturn; +import org.hibernate.engine.query.spi.sql.NativeSQLQueryNonScalarReturn; +import org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn; +import org.hibernate.engine.query.spi.sql.NativeSQLQueryRootReturn; +import org.hibernate.engine.query.spi.sql.NativeSQLQueryScalarReturn; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.CoreLogging; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.loader.BasicLoader; +import org.hibernate.loader.CollectionAliases; +import org.hibernate.loader.ColumnEntityAliases; +import org.hibernate.loader.DefaultEntityAliases; +import org.hibernate.loader.EntityAliases; +import org.hibernate.loader.GeneratedCollectionAliases; +import org.hibernate.loader.custom.CollectionFetchReturn; import org.hibernate.loader.custom.CollectionReturn; import org.hibernate.loader.custom.ColumnCollectionAliases; +import org.hibernate.loader.custom.ConstructorReturn; +import org.hibernate.loader.custom.EntityFetchReturn; import org.hibernate.loader.custom.FetchReturn; -import org.hibernate.loader.custom.CollectionFetchReturn; import org.hibernate.loader.custom.NonScalarReturn; -import org.hibernate.loader.custom.EntityFetchReturn; -import org.hibernate.loader.BasicLoader; -import org.hibernate.loader.EntityAliases; -import org.hibernate.loader.DefaultEntityAliases; -import org.hibernate.loader.ColumnEntityAliases; -import org.hibernate.loader.CollectionAliases; -import org.hibernate.loader.GeneratedCollectionAliases; -import org.hibernate.engine.query.sql.NativeSQLQueryReturn; -import org.hibernate.engine.query.sql.NativeSQLQueryCollectionReturn; -import org.hibernate.engine.query.sql.NativeSQLQueryScalarReturn; -import org.hibernate.engine.query.sql.NativeSQLQueryNonScalarReturn; -import org.hibernate.engine.query.sql.NativeSQLQueryJoinReturn; -import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.loader.custom.Return; +import org.hibernate.loader.custom.RootReturn; +import org.hibernate.loader.custom.ScalarReturn; +import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.SQLLoadableCollection; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.entity.Joinable; import org.hibernate.persister.entity.SQLLoadable; import org.hibernate.type.EntityType; import org.hibernate.type.Type; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * Responsible for processing the series of {@link org.hibernate.engine.query.sql.NativeSQLQueryReturn returns} - * defined by a {@link org.hibernate.engine.query.sql.NativeSQLQuerySpecification} and + * Responsible for processing the series of {@link org.hibernate.engine.query.spi.sql.NativeSQLQueryReturn returns} + * defined by a {@link org.hibernate.engine.query.spi.sql.NativeSQLQuerySpecification} and * breaking them down into a series of {@link Return returns} for use within the * {@link org.hibernate.loader.custom.CustomLoader}. * @@ -73,20 +80,19 @@ * @author Steve Ebersole */ public class SQLQueryReturnProcessor { + private static final CoreMessageLogger LOG = CoreLogging.messageLogger( SQLQueryReturnProcessor.class ); - public static final Logger log = LoggerFactory.getLogger( SQLQueryReturnProcessor.class ); - private NativeSQLQueryReturn[] queryReturns; // private final List persisters = new ArrayList(); private final Map alias2Return = new HashMap(); private final Map alias2OwnerAlias = new HashMap(); - private final Map alias2Persister = new HashMap(); + private final Map alias2Persister = new HashMap(); private final Map alias2Suffix = new HashMap(); - private final Map alias2CollectionPersister = new HashMap(); + private final Map alias2CollectionPersister = new HashMap(); private final Map alias2CollectionSuffix = new HashMap(); private final Map entityPropertyResultMaps = new HashMap(); @@ -102,39 +108,58 @@ // private List collectionPersisters = new ArrayList(); // private List collectionResults = new ArrayList(); - private int entitySuffixSeed = 0; - private int collectionSuffixSeed = 0; + private int entitySuffixSeed; + private int collectionSuffixSeed; public SQLQueryReturnProcessor(NativeSQLQueryReturn[] queryReturns, SessionFactoryImplementor factory) { this.queryReturns = queryReturns; this.factory = factory; } - /*package*/ class ResultAliasContext { + public class ResultAliasContext { public SQLLoadable getEntityPersister(String alias) { - return ( SQLLoadable ) alias2Persister.get( alias ); + return (SQLLoadable) alias2Persister.get( alias ); } public SQLLoadableCollection getCollectionPersister(String alias) { - return ( SQLLoadableCollection ) alias2CollectionPersister.get( alias ); + return (SQLLoadableCollection) alias2CollectionPersister.get( alias ); } public String getEntitySuffix(String alias) { - return ( String ) alias2Suffix.get( alias ); + return (String) alias2Suffix.get( alias ); } public String getCollectionSuffix(String alias) { - return ( String ) alias2CollectionSuffix.get ( alias ); + return (String) alias2CollectionSuffix.get( alias ); } public String getOwnerAlias(String alias) { - return ( String ) alias2OwnerAlias.get( alias ); + return (String) alias2OwnerAlias.get( alias ); } public Map getPropertyResultsMap(String alias) { return internalGetPropertyResultsMap( alias ); } + + public String[] collectQuerySpaces() { + final HashSet spaces = new HashSet(); + collectQuerySpaces( spaces ); + return spaces.toArray( new String[ spaces.size() ] ); + } + + public void collectQuerySpaces(Collection spaces) { + for ( EntityPersister persister : alias2Persister.values() ) { + Collections.addAll( spaces, (String[]) persister.getQuerySpaces() ); + } + for ( CollectionPersister persister : alias2CollectionPersister.values() ) { + final Type elementType = persister.getElementType(); + if ( elementType.isEntityType() && ! elementType.isAnyType() ) { + final Joinable joinable = ( (EntityType) elementType ).getAssociatedJoinable( factory ); + Collections.addAll( spaces, (String[]) ( (EntityPersister) joinable ).getQuerySpaces() ); + } + } + } } private Map internalGetPropertyResultsMap(String alias) { @@ -155,49 +180,49 @@ public ResultAliasContext process() { // first, break down the returns into maps keyed by alias // so that role returns can be more easily resolved to their owners - for ( int i = 0; i < queryReturns.length; i++ ) { - if ( queryReturns[i] instanceof NativeSQLQueryNonScalarReturn ) { - NativeSQLQueryNonScalarReturn rtn = ( NativeSQLQueryNonScalarReturn ) queryReturns[i]; + for ( NativeSQLQueryReturn queryReturn : queryReturns ) { + if ( queryReturn instanceof NativeSQLQueryNonScalarReturn ) { + NativeSQLQueryNonScalarReturn rtn = (NativeSQLQueryNonScalarReturn) queryReturn; alias2Return.put( rtn.getAlias(), rtn ); if ( rtn instanceof NativeSQLQueryJoinReturn ) { - NativeSQLQueryJoinReturn fetchReturn = ( NativeSQLQueryJoinReturn ) rtn; + NativeSQLQueryJoinReturn fetchReturn = (NativeSQLQueryJoinReturn) rtn; alias2OwnerAlias.put( fetchReturn.getAlias(), fetchReturn.getOwnerAlias() ); } } } // Now, process the returns - for ( int i = 0; i < queryReturns.length; i++ ) { - processReturn( queryReturns[i] ); + for ( NativeSQLQueryReturn queryReturn : queryReturns ) { + processReturn( queryReturn ); } return new ResultAliasContext(); } - public List generateCustomReturns(boolean queryHadAliases) { - List customReturns = new ArrayList(); - Map customReturnsByAlias = new HashMap(); - for ( int i = 0; i < queryReturns.length; i++ ) { - if ( queryReturns[i] instanceof NativeSQLQueryScalarReturn ) { - NativeSQLQueryScalarReturn rtn = ( NativeSQLQueryScalarReturn ) queryReturns[i]; + public List generateCustomReturns(boolean queryHadAliases) { + List customReturns = new ArrayList(); + Map customReturnsByAlias = new HashMap(); + for ( NativeSQLQueryReturn queryReturn : queryReturns ) { + if ( queryReturn instanceof NativeSQLQueryScalarReturn ) { + NativeSQLQueryScalarReturn rtn = (NativeSQLQueryScalarReturn) queryReturn; customReturns.add( new ScalarReturn( rtn.getType(), rtn.getColumnAlias() ) ); } - else if ( queryReturns[i] instanceof NativeSQLQueryRootReturn ) { - NativeSQLQueryRootReturn rtn = ( NativeSQLQueryRootReturn ) queryReturns[i]; + else if ( queryReturn instanceof NativeSQLQueryRootReturn ) { + NativeSQLQueryRootReturn rtn = (NativeSQLQueryRootReturn) queryReturn; String alias = rtn.getAlias(); EntityAliases entityAliases; if ( queryHadAliases || hasPropertyResultMap( alias ) ) { entityAliases = new DefaultEntityAliases( - ( Map ) entityPropertyResultMaps.get( alias ), - ( SQLLoadable ) alias2Persister.get( alias ), - ( String ) alias2Suffix.get( alias ) + (Map) entityPropertyResultMaps.get( alias ), + (SQLLoadable) alias2Persister.get( alias ), + (String) alias2Suffix.get( alias ) ); } else { entityAliases = new ColumnEntityAliases( - ( Map ) entityPropertyResultMaps.get( alias ), - ( SQLLoadable ) alias2Persister.get( alias ), - ( String ) alias2Suffix.get( alias ) + (Map) entityPropertyResultMaps.get( alias ), + (SQLLoadable) alias2Persister.get( alias ), + (String) alias2Suffix.get( alias ) ); } RootReturn customReturn = new RootReturn( @@ -209,37 +234,37 @@ customReturns.add( customReturn ); customReturnsByAlias.put( rtn.getAlias(), customReturn ); } - else if ( queryReturns[i] instanceof NativeSQLQueryCollectionReturn ) { - NativeSQLQueryCollectionReturn rtn = ( NativeSQLQueryCollectionReturn ) queryReturns[i]; + else if ( queryReturn instanceof NativeSQLQueryCollectionReturn ) { + NativeSQLQueryCollectionReturn rtn = (NativeSQLQueryCollectionReturn) queryReturn; String alias = rtn.getAlias(); - SQLLoadableCollection persister = ( SQLLoadableCollection ) alias2CollectionPersister.get( alias ); + SQLLoadableCollection persister = (SQLLoadableCollection) alias2CollectionPersister.get( alias ); boolean isEntityElements = persister.getElementType().isEntityType(); CollectionAliases collectionAliases; EntityAliases elementEntityAliases = null; if ( queryHadAliases || hasPropertyResultMap( alias ) ) { collectionAliases = new GeneratedCollectionAliases( - ( Map ) collectionPropertyResultMaps.get( alias ), - ( SQLLoadableCollection ) alias2CollectionPersister.get( alias ), - ( String ) alias2CollectionSuffix.get( alias ) + (Map) collectionPropertyResultMaps.get( alias ), + (SQLLoadableCollection) alias2CollectionPersister.get( alias ), + (String) alias2CollectionSuffix.get( alias ) ); if ( isEntityElements ) { elementEntityAliases = new DefaultEntityAliases( - ( Map ) entityPropertyResultMaps.get( alias ), - ( SQLLoadable ) alias2Persister.get( alias ), - ( String ) alias2Suffix.get( alias ) + (Map) entityPropertyResultMaps.get( alias ), + (SQLLoadable) alias2Persister.get( alias ), + (String) alias2Suffix.get( alias ) ); } } else { collectionAliases = new ColumnCollectionAliases( - ( Map ) collectionPropertyResultMaps.get( alias ), - ( SQLLoadableCollection ) alias2CollectionPersister.get( alias ) + (Map) collectionPropertyResultMaps.get( alias ), + (SQLLoadableCollection) alias2CollectionPersister.get( alias ) ); if ( isEntityElements ) { elementEntityAliases = new ColumnEntityAliases( - ( Map ) entityPropertyResultMaps.get( alias ), - ( SQLLoadable ) alias2Persister.get( alias ), - ( String ) alias2Suffix.get( alias ) + (Map) entityPropertyResultMaps.get( alias ), + (SQLLoadable) alias2Persister.get( alias ), + (String) alias2Suffix.get( alias ) ); } } @@ -248,46 +273,46 @@ rtn.getOwnerEntityName(), rtn.getOwnerProperty(), collectionAliases, - elementEntityAliases, + elementEntityAliases, rtn.getLockMode() ); customReturns.add( customReturn ); customReturnsByAlias.put( rtn.getAlias(), customReturn ); } - else if ( queryReturns[i] instanceof NativeSQLQueryJoinReturn ) { - NativeSQLQueryJoinReturn rtn = ( NativeSQLQueryJoinReturn ) queryReturns[i]; + else if ( queryReturn instanceof NativeSQLQueryJoinReturn ) { + NativeSQLQueryJoinReturn rtn = (NativeSQLQueryJoinReturn) queryReturn; String alias = rtn.getAlias(); FetchReturn customReturn; - NonScalarReturn ownerCustomReturn = ( NonScalarReturn ) customReturnsByAlias.get( rtn.getOwnerAlias() ); + NonScalarReturn ownerCustomReturn = (NonScalarReturn) customReturnsByAlias.get( rtn.getOwnerAlias() ); if ( alias2CollectionPersister.containsKey( alias ) ) { - SQLLoadableCollection persister = ( SQLLoadableCollection ) alias2CollectionPersister.get( alias ); + SQLLoadableCollection persister = (SQLLoadableCollection) alias2CollectionPersister.get( alias ); boolean isEntityElements = persister.getElementType().isEntityType(); CollectionAliases collectionAliases; EntityAliases elementEntityAliases = null; if ( queryHadAliases || hasPropertyResultMap( alias ) ) { collectionAliases = new GeneratedCollectionAliases( - ( Map ) collectionPropertyResultMaps.get( alias ), + (Map) collectionPropertyResultMaps.get( alias ), persister, - ( String ) alias2CollectionSuffix.get( alias ) + (String) alias2CollectionSuffix.get( alias ) ); if ( isEntityElements ) { elementEntityAliases = new DefaultEntityAliases( - ( Map ) entityPropertyResultMaps.get( alias ), - ( SQLLoadable ) alias2Persister.get( alias ), - ( String ) alias2Suffix.get( alias ) + (Map) entityPropertyResultMaps.get( alias ), + (SQLLoadable) alias2Persister.get( alias ), + (String) alias2Suffix.get( alias ) ); } } else { collectionAliases = new ColumnCollectionAliases( - ( Map ) collectionPropertyResultMaps.get( alias ), + (Map) collectionPropertyResultMaps.get( alias ), persister ); if ( isEntityElements ) { elementEntityAliases = new ColumnEntityAliases( - ( Map ) entityPropertyResultMaps.get( alias ), - ( SQLLoadable ) alias2Persister.get( alias ), - ( String ) alias2Suffix.get( alias ) + (Map) entityPropertyResultMaps.get( alias ), + (SQLLoadable) alias2Persister.get( alias ), + (String) alias2Suffix.get( alias ) ); } } @@ -296,24 +321,24 @@ ownerCustomReturn, rtn.getOwnerProperty(), collectionAliases, - elementEntityAliases, + elementEntityAliases, rtn.getLockMode() ); } else { EntityAliases entityAliases; if ( queryHadAliases || hasPropertyResultMap( alias ) ) { entityAliases = new DefaultEntityAliases( - ( Map ) entityPropertyResultMaps.get( alias ), - ( SQLLoadable ) alias2Persister.get( alias ), - ( String ) alias2Suffix.get( alias ) + (Map) entityPropertyResultMaps.get( alias ), + (SQLLoadable) alias2Persister.get( alias ), + (String) alias2Suffix.get( alias ) ); } else { entityAliases = new ColumnEntityAliases( - ( Map ) entityPropertyResultMaps.get( alias ), - ( SQLLoadable ) alias2Persister.get( alias ), - ( String ) alias2Suffix.get( alias ) + (Map) entityPropertyResultMaps.get( alias ), + (SQLLoadable) alias2Persister.get( alias ), + (String) alias2Suffix.get( alias ) ); } customReturn = new EntityFetchReturn( @@ -327,6 +352,20 @@ customReturns.add( customReturn ); customReturnsByAlias.put( alias, customReturn ); } + else if ( NativeSQLQueryConstructorReturn.class.isInstance( queryReturn ) ) { + final NativeSQLQueryConstructorReturn constructorReturn = (NativeSQLQueryConstructorReturn) queryReturn; + final ScalarReturn[] scalars = new ScalarReturn[ constructorReturn.getColumnReturns().length ]; + int i = 0; + for ( NativeSQLQueryScalarReturn scalarReturn : constructorReturn.getColumnReturns() ) { + scalars[i++] = new ScalarReturn( scalarReturn.getType(), scalarReturn.getColumnAlias() ); + } + customReturns.add( new ConstructorReturn( constructorReturn.getTargetClass(), scalars ) ); + } + else { + throw new IllegalStateException( + "Unrecognized NativeSQLQueryReturn concrete type : " + queryReturn + ); + } } return customReturns; } @@ -355,13 +394,25 @@ processRootReturn( ( NativeSQLQueryRootReturn ) rtn ); } else if ( rtn instanceof NativeSQLQueryCollectionReturn ) { - processCollectionReturn( ( NativeSQLQueryCollectionReturn ) rtn ); + processCollectionReturn( (NativeSQLQueryCollectionReturn) rtn ); } - else { + else if ( NativeSQLQueryJoinReturn.class.isInstance( rtn ) ) { processJoinReturn( ( NativeSQLQueryJoinReturn ) rtn ); } + else if ( NativeSQLQueryConstructorReturn.class.isInstance( rtn ) ) { + processConstructorReturn( (NativeSQLQueryConstructorReturn) rtn ); + } + else { + throw new IllegalStateException( + "Unrecognized NativeSQLQueryReturn concrete type encountered : " + rtn + ); + } } + private void processConstructorReturn(NativeSQLQueryConstructorReturn rtn) { + //To change body of created methods use File | Settings | File Templates. + } + private void processScalarReturn(NativeSQLQueryScalarReturn typeReturn) { // scalarColumnAliases.add( typeReturn.getColumnAlias() ); // scalarTypes.add( typeReturn.getType() ); @@ -377,14 +428,10 @@ addPersister( rootReturn.getAlias(), rootReturn.getPropertyResultsMap(), persister ); } - /** - * @param propertyResult - * @param persister - */ private void addPersister(String alias, Map propertyResult, SQLLoadable persister) { alias2Persister.put( alias, persister ); String suffix = generateEntitySuffix(); - log.trace( "mapping alias [" + alias + "] to entity-suffix [" + suffix + "]" ); + LOG.tracev( "Mapping alias [{0}] to entity-suffix [{1}]", alias, suffix ); alias2Suffix.put( alias, suffix ); entityPropertyResultMaps.put( alias, propertyResult ); } @@ -393,11 +440,11 @@ SQLLoadableCollection collectionPersister = ( SQLLoadableCollection ) factory.getCollectionPersister( role ); alias2CollectionPersister.put( alias, collectionPersister ); String suffix = generateCollectionSuffix(); - log.trace( "mapping alias [" + alias + "] to collection-suffix [" + suffix + "]" ); + LOG.tracev( "Mapping alias [{0}] to collection-suffix [{1}]", alias, suffix ); alias2CollectionSuffix.put( alias, suffix ); collectionPropertyResultMaps.put( alias, propertyResults ); - if ( collectionPersister.isOneToMany() ) { + if ( collectionPersister.isOneToMany() || collectionPersister.isManyToMany() ) { SQLLoadable persister = ( SQLLoadable ) collectionPersister.getElementPersister(); addPersister( alias, filter( propertyResults ), persister ); } @@ -521,5 +568,4 @@ // public Map getAlias2Return() { // return alias2Return; // } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/AbstractEntityLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/entity/AbstractEntityLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/AbstractEntityLoader.java 17 Aug 2012 14:34:03 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/AbstractEntityLoader.java 30 Jul 2014 16:16:31 -0000 1.1.2.1 @@ -23,61 +23,69 @@ * */ package org.hibernate.loader.entity; - import java.io.Serializable; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.HibernateException; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.LockOptions; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.loader.OuterJoinLoader; import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.transform.ResultTransformer; import org.hibernate.type.Type; -public abstract class AbstractEntityLoader extends OuterJoinLoader +public abstract class AbstractEntityLoader extends OuterJoinLoader implements UniqueEntityLoader { - protected static final Logger log = LoggerFactory.getLogger(EntityLoader.class); protected final OuterJoinLoadable persister; protected final Type uniqueKeyType; protected final String entityName; public AbstractEntityLoader( - OuterJoinLoadable persister, - Type uniqueKeyType, - SessionFactoryImplementor factory, - Map enabledFilters) { - super( factory, enabledFilters ); + OuterJoinLoadable persister, + Type uniqueKeyType, + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) { + super( factory, loadQueryInfluencers ); this.uniqueKeyType = uniqueKeyType; this.entityName = persister.getEntityName(); this.persister = persister; - + } - public Object load(Serializable id, Object optionalObject, SessionImplementor session) - throws HibernateException { - return load(session, id, optionalObject, id); + @Override + public Object load(Serializable id, Object optionalObject, SessionImplementor session) { + // this form is deprecated! + return load( id, optionalObject, session, LockOptions.NONE ); } - protected Object load(SessionImplementor session, Object id, Object optionalObject, Serializable optionalId) - throws HibernateException { - + @Override + public Object load(Serializable id, Object optionalObject, SessionImplementor session, LockOptions lockOptions) { + return load( session, id, optionalObject, id, lockOptions ); + } + + protected Object load( + SessionImplementor session, + Object id, + Object optionalObject, + Serializable optionalId, + LockOptions lockOptions) { + List list = loadEntity( - session, - id, - uniqueKeyType, - optionalObject, - entityName, - optionalId, - persister + session, + id, + uniqueKeyType, + optionalObject, + entityName, + optionalId, + persister, + lockOptions ); - + if ( list.size()==1 ) { return list.get(0); } @@ -97,15 +105,17 @@ ); } } - + } - protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session) + @Override + protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session) throws SQLException, HibernateException { return row[row.length-1]; } - protected boolean isSingleRowLoader() { + @Override + protected boolean isSingleRowLoader() { return true; } Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/BatchingEntityLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/entity/BatchingEntityLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/BatchingEntityLoader.java 17 Aug 2012 14:34:02 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/BatchingEntityLoader.java 30 Jul 2014 16:16:31 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2012, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,110 +20,109 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.loader.entity; import java.io.Serializable; -import java.util.Iterator; +import java.sql.SQLException; +import java.util.Arrays; import java.util.List; -import java.util.Map; -import org.hibernate.HibernateException; -import org.hibernate.LockMode; -import org.hibernate.MappingException; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.LockOptions; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.loader.Loader; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.persister.entity.OuterJoinLoadable; +import org.hibernate.pretty.MessageHelper; import org.hibernate.type.Type; -import org.hibernate.util.ArrayHelper; +import org.jboss.logging.Logger; + /** - * "Batch" loads entities, using multiple primary key values in the - * SQL where clause. + * The base contract for loaders capable of performing batch-fetch loading of entities using multiple primary key + * values in the SQL WHERE clause. * - * @see EntityLoader * @author Gavin King + * @author Steve Ebersole + * + * @see BatchingEntityLoaderBuilder + * @see UniqueEntityLoader */ -public class BatchingEntityLoader implements UniqueEntityLoader { +public abstract class BatchingEntityLoader implements UniqueEntityLoader { + private static final Logger log = Logger.getLogger( BatchingEntityLoader.class ); - private final Loader[] loaders; - private final int[] batchSizes; private final EntityPersister persister; - private final Type idType; - public BatchingEntityLoader(EntityPersister persister, int[] batchSizes, Loader[] loaders) { - this.batchSizes = batchSizes; - this.loaders = loaders; + public BatchingEntityLoader(EntityPersister persister) { this.persister = persister; - idType = persister.getIdentifierType(); } - private Object getObjectFromList(List results, Serializable id, SessionImplementor session) { - // get the right object from the list ... would it be easier to just call getEntity() ?? - Iterator iter = results.iterator(); - while ( iter.hasNext() ) { - Object obj = iter.next(); - final boolean equal = idType.isEqual( - id, - session.getContextEntityIdentifier(obj), - session.getEntityMode(), - session.getFactory() + public EntityPersister persister() { + return persister; + } + + @Override + @Deprecated + public Object load(Serializable id, Object optionalObject, SessionImplementor session) { + return load( id, optionalObject, session, LockOptions.NONE ); + } + + protected QueryParameters buildQueryParameters( + Serializable id, + Serializable[] ids, + Object optionalObject, + LockOptions lockOptions) { + Type[] types = new Type[ids.length]; + Arrays.fill( types, persister().getIdentifierType() ); + + QueryParameters qp = new QueryParameters(); + qp.setPositionalParameterTypes( types ); + qp.setPositionalParameterValues( ids ); + qp.setOptionalObject( optionalObject ); + qp.setOptionalEntityName( persister().getEntityName() ); + qp.setOptionalId( id ); + qp.setLockOptions( lockOptions ); + return qp; + } + + protected Object getObjectFromList(List results, Serializable id, SessionImplementor session) { + for ( Object obj : results ) { + final boolean equal = persister.getIdentifierType().isEqual( + id, + session.getContextEntityIdentifier( obj ), + session.getFactory() ); - if ( equal ) return obj; + if ( equal ) { + return obj; + } } return null; } - public Object load(Serializable id, Object optionalObject, SessionImplementor session) - throws HibernateException { - - Serializable[] batch = session.getPersistenceContext() - .getBatchFetchQueue() - .getEntityBatch( persister, id, batchSizes[0], session.getEntityMode() ); - - for ( int i=0; i1 ) { - int[] batchSizesToCreate = ArrayHelper.getBatchSizes(maxBatchSize); - Loader[] loadersToCreate = new Loader[ batchSizesToCreate.length ]; - for ( int i=0; i0; } - public String getComment() { + @Override + public String getComment() { return "load " + getPersister().getEntityName(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/CascadeEntityLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/entity/CascadeEntityLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/CascadeEntityLoader.java 17 Aug 2012 14:34:03 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/CascadeEntityLoader.java 30 Jul 2014 16:16:31 -0000 1.1.2.1 @@ -23,39 +23,38 @@ * */ package org.hibernate.loader.entity; - import org.hibernate.MappingException; -import org.hibernate.engine.CascadingAction; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.CascadingAction; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.JoinWalker; import org.hibernate.persister.entity.OuterJoinLoadable; -import org.hibernate.util.CollectionHelper; public class CascadeEntityLoader extends AbstractEntityLoader { - + public CascadeEntityLoader( OuterJoinLoadable persister, CascadingAction action, - SessionFactoryImplementor factory) - throws MappingException { + SessionFactoryImplementor factory) throws MappingException { super( - persister, - persister.getIdentifierType(), - factory, - CollectionHelper.EMPTY_MAP - ); + persister, + persister.getIdentifierType(), + factory, + LoadQueryInfluencers.NONE + ); JoinWalker walker = new CascadeEntityJoinWalker( - persister, + persister, action, factory - ); + ); initFromWalker( walker ); postInstantiate(); - - log.debug( "Static select for action " + action + " on entity " + entityName + ": " + getSQLString() ); + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Static select for action %s on entity %s: %s", action, entityName, getSQLString() ); + } } } Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/CollectionElementLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/entity/CollectionElementLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/CollectionElementLoader.java 17 Aug 2012 14:34:03 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/CollectionElementLoader.java 30 Jul 2014 16:16:31 -0000 1.1.2.1 @@ -27,80 +27,82 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.HibernateException; import org.hibernate.LockMode; import org.hibernate.MappingException; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.loader.JoinWalker; import org.hibernate.loader.OuterJoinLoader; import org.hibernate.persister.collection.QueryableCollection; import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.transform.ResultTransformer; import org.hibernate.type.Type; -import org.hibernate.util.ArrayHelper; +import org.jboss.logging.Logger; + /** - * * + * * @author Gavin King */ public class CollectionElementLoader extends OuterJoinLoader { - - private static final Logger log = LoggerFactory.getLogger(CollectionElementLoader.class); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, CollectionElementLoader.class.getName() ); + private final OuterJoinLoadable persister; private final Type keyType; private final Type indexType; private final String entityName; public CollectionElementLoader( QueryableCollection collectionPersister, - SessionFactoryImplementor factory, - Map enabledFilters) - throws MappingException { - super(factory, enabledFilters); + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + super( factory, loadQueryInfluencers ); this.keyType = collectionPersister.getKeyType(); this.indexType = collectionPersister.getIndexType(); this.persister = (OuterJoinLoadable) collectionPersister.getElementPersister(); this.entityName = persister.getEntityName(); - + JoinWalker walker = new EntityJoinWalker( persister, - ArrayHelper.join( - collectionPersister.getKeyColumnNames(), - collectionPersister.getIndexColumnNames() - ), + ArrayHelper.join( + collectionPersister.getKeyColumnNames(), + collectionPersister.toColumns("index") + ), 1, LockMode.NONE, factory, - enabledFilters + loadQueryInfluencers ); initFromWalker( walker ); postInstantiate(); - - log.debug( "Static select for entity " + entityName + ": " + getSQLString() ); + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Static select for entity %s: %s", entityName, getSQLString() ); + } + } - public Object loadElement(SessionImplementor session, Object key, Object index) + public Object loadElement(SessionImplementor session, Object key, Object index) throws HibernateException { - + List list = loadEntity( - session, + session, key, index, - keyType, + keyType, indexType, persister ); - + if ( list.size()==1 ) { return list.get(0); } @@ -115,20 +117,20 @@ throw new HibernateException("More than one row was found"); } } - + } - protected Object getResultColumnOrRow( + @Override + protected Object getResultColumnOrRow( Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session) throws SQLException, HibernateException { return row[row.length-1]; } - protected boolean isSingleRowLoader() { + @Override + protected boolean isSingleRowLoader() { return true; } - - -} \ No newline at end of file +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/entity/DynamicBatchingEntityLoaderBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/EntityJoinWalker.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/entity/EntityJoinWalker.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/EntityJoinWalker.java 17 Aug 2012 14:34:02 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/EntityJoinWalker.java 30 Jul 2014 16:16:31 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,21 +20,30 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.loader.entity; - +import java.util.ArrayList; import java.util.Collections; -import java.util.Map; +import java.util.HashMap; import org.hibernate.FetchMode; import org.hibernate.LockMode; +import org.hibernate.LockOptions; import org.hibernate.MappingException; -import org.hibernate.engine.CascadeStyle; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.loader.AbstractEntityJoinWalker; +import org.hibernate.loader.OuterJoinableAssociation; +import org.hibernate.loader.PropertyPath; +import org.hibernate.persister.collection.QueryableCollection; +import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.OuterJoinLoadable; +import org.hibernate.sql.JoinType; import org.hibernate.type.AssociationType; +import org.hibernate.type.CompositeType; +import org.hibernate.type.EntityType; +import org.hibernate.type.Type; /** * A walker for loaders that fetch entities @@ -44,40 +53,206 @@ */ public class EntityJoinWalker extends AbstractEntityJoinWalker { - private final LockMode lockMode; + private final LockOptions lockOptions = new LockOptions(); + private final int[][] compositeKeyManyToOneTargetIndices; public EntityJoinWalker( OuterJoinLoadable persister, String[] uniqueKey, int batchSize, LockMode lockMode, - SessionFactoryImplementor factory, - Map enabledFilters) - throws MappingException { - super(persister, factory, enabledFilters); + final SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + super( persister, factory, loadQueryInfluencers ); - this.lockMode = lockMode; + this.lockOptions.setLockMode(lockMode); - StringBuffer whereCondition = whereString( getAlias(), uniqueKey, batchSize ) - //include the discriminator and class-level where, but not filters - .append( persister.filterFragment( getAlias(), Collections.EMPTY_MAP ) ); + StringBuilder whereCondition = whereString( getAlias(), uniqueKey, batchSize ) + //include the discriminator and class-level where, but not filters + .append( persister.filterFragment( getAlias(), Collections.EMPTY_MAP ) ); - initAll( whereCondition.toString(), "", lockMode ); - + AssociationInitCallbackImpl callback = new AssociationInitCallbackImpl( factory ); + initAll( whereCondition.toString(), "", lockOptions, callback ); + this.compositeKeyManyToOneTargetIndices = callback.resolve(); } - /** - * Disable outer join fetching if this loader obtains an - * upgrade lock mode - */ - protected boolean isJoinedFetchEnabled(AssociationType type, FetchMode config, CascadeStyle cascadeStyle) { - return lockMode.greaterThan(LockMode.READ) ? - false : - super.isJoinedFetchEnabled(type, config, cascadeStyle); + public EntityJoinWalker( + OuterJoinLoadable persister, + String[] uniqueKey, + int batchSize, + LockOptions lockOptions, + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + super( persister, factory, loadQueryInfluencers ); + LockOptions.copy(lockOptions, this.lockOptions); + + StringBuilder whereCondition = whereString( getAlias(), uniqueKey, batchSize ) + //include the discriminator and class-level where, but not filters + .append( persister.filterFragment( getAlias(), Collections.EMPTY_MAP ) ); + + AssociationInitCallbackImpl callback = new AssociationInitCallbackImpl( factory ); + initAll( whereCondition.toString(), "", lockOptions, callback ); + this.compositeKeyManyToOneTargetIndices = callback.resolve(); } + protected JoinType getJoinType( + OuterJoinLoadable persister, + PropertyPath path, + int propertyNumber, + AssociationType associationType, + FetchMode metadataFetchMode, + CascadeStyle metadataCascadeStyle, + String lhsTable, + String[] lhsColumns, + boolean nullable, + int currentDepth) throws MappingException { + // NOTE : we override this form here specifically to account for + // fetch profiles. + // TODO : how to best handle criteria queries? + if ( lockOptions.getLockMode().greaterThan( LockMode.READ ) ) { + return JoinType.NONE; + } + if ( isTooDeep( currentDepth ) + || ( associationType.isCollectionType() && isTooManyCollections() ) ) { + return JoinType.NONE; + } + if ( !isJoinedFetchEnabledInMapping( metadataFetchMode, associationType ) + && !isJoinFetchEnabledByProfile( persister, path, propertyNumber ) ) { + return JoinType.NONE; + } + if ( isDuplicateAssociation( lhsTable, lhsColumns, associationType ) ) { + return JoinType.NONE; + } + return getJoinType( nullable, currentDepth ); + } + public String getComment() { return "load " + getPersister().getEntityName(); } - -} \ No newline at end of file + + public int[][] getCompositeKeyManyToOneTargetIndices() { + return compositeKeyManyToOneTargetIndices; + } + + private static class AssociationInitCallbackImpl implements AssociationInitCallback { + private final SessionFactoryImplementor factory; + private final HashMap associationsByAlias + = new HashMap(); + private final HashMap positionsByAlias = new HashMap(); + private final ArrayList aliasesForAssociationsWithCompositesIds + = new ArrayList(); + + public AssociationInitCallbackImpl(SessionFactoryImplementor factory) { + this.factory = factory; + } + + public void associationProcessed(OuterJoinableAssociation oja, int position) { + associationsByAlias.put( oja.getRhsAlias(), oja ); + positionsByAlias.put( oja.getRhsAlias(), position ); + EntityPersister entityPersister = null; + if ( oja.getJoinableType().isCollectionType() ) { + entityPersister = ( ( QueryableCollection) oja.getJoinable() ).getElementPersister(); + } + else if ( oja.getJoinableType().isEntityType() ) { + entityPersister = ( EntityPersister ) oja.getJoinable(); + } + if ( entityPersister != null + && entityPersister.getIdentifierType().isComponentType() + && ! entityPersister.getEntityMetamodel().getIdentifierProperty().isEmbedded() + && hasAssociation( (CompositeType) entityPersister.getIdentifierType() ) ) { + aliasesForAssociationsWithCompositesIds.add( oja.getRhsAlias() ); + } + } + + private boolean hasAssociation(CompositeType componentType) { + for ( Type subType : componentType.getSubtypes() ) { + if ( subType.isEntityType() ) { + return true; + } + else if ( subType.isComponentType() && hasAssociation( ( (CompositeType) subType ) ) ) { + return true; + } + } + return false; + } + + public int[][] resolve() { + int[][] compositeKeyManyToOneTargetIndices = null; + for ( final String aliasWithCompositeId : aliasesForAssociationsWithCompositesIds ) { + final OuterJoinableAssociation joinWithCompositeId = associationsByAlias.get( aliasWithCompositeId ); + final ArrayList keyManyToOneTargetIndices = new ArrayList(); + // for each association with a composite id containing key-many-to-one(s), find the bidirectional side of + // each key-many-to-one (if exists) to see if it is eager as well. If so, we need to track the indices + EntityPersister entityPersister = null; + if ( joinWithCompositeId.getJoinableType().isCollectionType() ) { + entityPersister = ( ( QueryableCollection) joinWithCompositeId.getJoinable() ).getElementPersister(); + } + else if ( joinWithCompositeId.getJoinableType().isEntityType() ) { + entityPersister = ( EntityPersister ) joinWithCompositeId.getJoinable(); + } + + findKeyManyToOneTargetIndices( + keyManyToOneTargetIndices, + joinWithCompositeId, + (CompositeType) entityPersister.getIdentifierType() + ); + + if ( ! keyManyToOneTargetIndices.isEmpty() ) { + if ( compositeKeyManyToOneTargetIndices == null ) { + compositeKeyManyToOneTargetIndices = new int[ associationsByAlias.size() ][]; + } + int position = positionsByAlias.get( aliasWithCompositeId ); + compositeKeyManyToOneTargetIndices[position] = new int[ keyManyToOneTargetIndices.size() ]; + int i = 0; + for ( int index : keyManyToOneTargetIndices ) { + compositeKeyManyToOneTargetIndices[position][i] = index; + i++; + } + } + } + return compositeKeyManyToOneTargetIndices; + } + + private void findKeyManyToOneTargetIndices( + ArrayList keyManyToOneTargetIndices, + OuterJoinableAssociation joinWithCompositeId, + CompositeType componentType) { + for ( Type subType : componentType.getSubtypes() ) { + if ( subType.isEntityType() ) { + Integer index = locateKeyManyToOneTargetIndex( joinWithCompositeId, (EntityType) subType ); + if ( index != null ) { + keyManyToOneTargetIndices.add( index ); + } + } + else if ( subType.isComponentType() ) { + findKeyManyToOneTargetIndices( + keyManyToOneTargetIndices, + joinWithCompositeId, + (CompositeType) subType + ); + } + } + } + + private Integer locateKeyManyToOneTargetIndex(OuterJoinableAssociation joinWithCompositeId, EntityType keyManyToOneType) { + // the lhs (if one) is a likely candidate + if ( joinWithCompositeId.getLhsAlias() != null ) { + final OuterJoinableAssociation lhs = associationsByAlias.get( joinWithCompositeId.getLhsAlias() ); + if ( keyManyToOneType.getAssociatedEntityName( factory ).equals( lhs.getJoinableType().getAssociatedEntityName( factory ) ) ) { + return positionsByAlias.get( lhs.getRhsAlias() ); + } + } + // otherwise, seek out OuterJoinableAssociation which are RHS of given OuterJoinableAssociation + // (joinWithCompositeId) + for ( OuterJoinableAssociation oja : associationsByAlias.values() ) { + if ( oja.getLhsAlias() != null && oja.getLhsAlias().equals( joinWithCompositeId.getRhsAlias() ) ) { + if ( keyManyToOneType.equals( oja.getJoinableType() ) ) { + return positionsByAlias.get( oja.getLhsAlias() ); + } + } + } + return null; + } + } + +} Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/EntityLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/entity/EntityLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/EntityLoader.java 17 Aug 2012 14:34:03 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/EntityLoader.java 30 Jul 2014 16:16:31 -0000 1.1.2.1 @@ -23,15 +23,12 @@ * */ package org.hibernate.loader.entity; - -import java.util.Map; - -import org.hibernate.HibernateException; import org.hibernate.LockMode; +import org.hibernate.LockOptions; import org.hibernate.MappingException; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.loader.JoinWalker; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.type.Type; @@ -44,72 +41,133 @@ * @author Gavin King */ public class EntityLoader extends AbstractEntityLoader { - + private final boolean batchLoader; - + private final int[][] compositeKeyManyToOneTargetIndices; + public EntityLoader( - OuterJoinLoadable persister, + OuterJoinLoadable persister, LockMode lockMode, - SessionFactoryImplementor factory, - Map enabledFilters) - throws MappingException { - this(persister, 1, lockMode, factory, enabledFilters); + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + this( persister, 1, lockMode, factory, loadQueryInfluencers ); } - + public EntityLoader( - OuterJoinLoadable persister, - int batchSize, + OuterJoinLoadable persister, + LockOptions lockOptions, + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + this( persister, 1, lockOptions, factory, loadQueryInfluencers ); + } + + public EntityLoader( + OuterJoinLoadable persister, + int batchSize, LockMode lockMode, - SessionFactoryImplementor factory, - Map enabledFilters) - throws MappingException { - this( - persister, - persister.getIdentifierColumnNames(), - persister.getIdentifierType(), + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + this( + persister, + persister.getIdentifierColumnNames(), + persister.getIdentifierType(), batchSize, lockMode, - factory, - enabledFilters + factory, + loadQueryInfluencers ); } public EntityLoader( - OuterJoinLoadable persister, - String[] uniqueKey, - Type uniqueKeyType, - int batchSize, + OuterJoinLoadable persister, + int batchSize, + LockOptions lockOptions, + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + this( + persister, + persister.getIdentifierColumnNames(), + persister.getIdentifierType(), + batchSize, + lockOptions, + factory, + loadQueryInfluencers + ); + } + + public EntityLoader( + OuterJoinLoadable persister, + String[] uniqueKey, + Type uniqueKeyType, + int batchSize, LockMode lockMode, - SessionFactoryImplementor factory, - Map enabledFilters) - throws MappingException { - super(persister, uniqueKeyType, factory, enabledFilters); + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + super( persister, uniqueKeyType, factory, loadQueryInfluencers ); - JoinWalker walker = new EntityJoinWalker( - persister, - uniqueKey, - batchSize, - lockMode, - factory, - enabledFilters - ); + EntityJoinWalker walker = new EntityJoinWalker( + persister, + uniqueKey, + batchSize, + lockMode, + factory, + loadQueryInfluencers + ); initFromWalker( walker ); + this.compositeKeyManyToOneTargetIndices = walker.getCompositeKeyManyToOneTargetIndices(); + postInstantiate(); + batchLoader = batchSize > 1; + + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Static select for entity %s [%s]: %s", entityName, lockMode, getSQLString() ); + } + } + + public EntityLoader( + OuterJoinLoadable persister, + String[] uniqueKey, + Type uniqueKeyType, + int batchSize, + LockOptions lockOptions, + SessionFactoryImplementor factory, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + super( persister, uniqueKeyType, factory, loadQueryInfluencers ); + + EntityJoinWalker walker = new EntityJoinWalker( + persister, + uniqueKey, + batchSize, + lockOptions, + factory, + loadQueryInfluencers + ); + initFromWalker( walker ); + this.compositeKeyManyToOneTargetIndices = walker.getCompositeKeyManyToOneTargetIndices(); postInstantiate(); batchLoader = batchSize > 1; - - log.debug( "Static select for entity " + entityName + ": " + getSQLString() ); + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Static select for entity %s [%s:%s]: %s", + entityName, + lockOptions.getLockMode(), + lockOptions.getTimeOut(), + getSQLString() ); + } } - public Object loadByUniqueKey(SessionImplementor session, Object key) - throws HibernateException { - return load(session, key, null, null); + public Object loadByUniqueKey(SessionImplementor session,Object key) { + return load( session, key, null, null, LockOptions.NONE ); } - protected boolean isSingleRowLoader() { + @Override + protected boolean isSingleRowLoader() { return !batchLoader; } - -} \ No newline at end of file + + @Override + public int[][] getCompositeKeyManyToOneTargetIndices() { + return compositeKeyManyToOneTargetIndices; + } +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/entity/LegacyBatchingEntityLoaderBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/entity/PaddedBatchingEntityLoaderBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/UniqueEntityLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/entity/UniqueEntityLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/UniqueEntityLoader.java 17 Aug 2012 14:34:03 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/entity/UniqueEntityLoader.java 30 Jul 2014 16:16:31 -0000 1.1.2.1 @@ -23,20 +23,41 @@ * */ package org.hibernate.loader.entity; - import java.io.Serializable; import org.hibernate.HibernateException; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.LockOptions; +import org.hibernate.engine.spi.SessionImplementor; /** * Loads entities for a EntityPersister + * * @author Gavin King + * @author Steve Ebersole */ public interface UniqueEntityLoader { /** * Load an entity instance. If optionalObject is supplied, * load the entity state into the given (uninitialized) object. + * + * @deprecated use {@link #load(java.io.Serializable, Object, SessionImplementor, LockOptions)} instead. */ + @SuppressWarnings( {"JavaDoc"}) + @Deprecated public Object load(Serializable id, Object optionalObject, SessionImplementor session) throws HibernateException; + + /** + * Load an entity instance by id. If optionalObject is supplied (non-null, + * the entity state is loaded into that object instance instead of instantiating a new one. + * + * @param id The id to be loaded + * @param optionalObject The (optional) entity instance in to which to load the state + * @param session The session from which the request originated + * @param lockOptions The lock options. + * + * @return The loaded entity + * + * @throws HibernateException indicates problem performing the load. + */ + public Object load(Serializable id, Object optionalObject, SessionImplementor session, LockOptions lockOptions); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/entity/plan/AbstractBatchingEntityLoaderBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/entity/plan/AbstractLoadPlanBasedEntityLoader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/entity/plan/BatchingEntityLoader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/entity/plan/EntityLoader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/entity/plan/LegacyBatchingEntityLoaderBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/loader/hql/QueryLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/loader/hql/QueryLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/loader/hql/QueryLoader.java 17 Aug 2012 14:34:00 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/loader/hql/QueryLoader.java 30 Jul 2014 16:17:09 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,45 +20,48 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.loader.hql; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.hibernate.HibernateException; import org.hibernate.LockMode; +import org.hibernate.LockOptions; import org.hibernate.QueryException; import org.hibernate.ScrollableResults; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.QueryParameters; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.event.EventSource; -import org.hibernate.exception.JDBCExceptionHelper; -import org.hibernate.hql.HolderInstantiator; -import org.hibernate.hql.ast.QueryTranslatorImpl; -import org.hibernate.hql.ast.tree.FromElement; -import org.hibernate.hql.ast.tree.SelectClause; -import org.hibernate.hql.ast.tree.QueryNode; -import org.hibernate.impl.IteratorImpl; +import org.hibernate.engine.spi.QueryParameters; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.event.spi.EventSource; +import org.hibernate.hql.internal.HolderInstantiator; +import org.hibernate.hql.internal.ast.QueryTranslatorImpl; +import org.hibernate.hql.internal.ast.tree.AggregatedSelectExpression; +import org.hibernate.hql.internal.ast.tree.FromElement; +import org.hibernate.hql.internal.ast.tree.QueryNode; +import org.hibernate.hql.internal.ast.tree.SelectClause; +import org.hibernate.internal.IteratorImpl; +import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.loader.BasicLoader; +import org.hibernate.loader.spi.AfterLoadAction; import org.hibernate.param.ParameterSpecification; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.QueryableCollection; import org.hibernate.persister.entity.Loadable; -import org.hibernate.persister.entity.Queryable; import org.hibernate.persister.entity.Lockable; +import org.hibernate.persister.entity.Queryable; import org.hibernate.transform.ResultTransformer; import org.hibernate.type.EntityType; import org.hibernate.type.Type; -import org.hibernate.util.ArrayHelper; /** * A delegate that implements the Loader part of QueryTranslator. @@ -85,7 +88,7 @@ //private Type[] sqlResultTypes; private Type[] queryReturnTypes; - private final Map sqlAliasByEntityAlias = new HashMap(8); + private final Map sqlAliasByEntityAlias = new HashMap(8); private EntityType[] ownerAssociationTypes; private int[] owners; @@ -96,7 +99,7 @@ private int selectLength; - private ResultTransformer selectNewTransformer; + private AggregatedSelectExpression aggregatedSelectExpression; private String[] queryReturnAliases; private LockMode[] defaultLockModes; @@ -128,10 +131,7 @@ //sqlResultTypes = selectClause.getSqlResultTypes(); queryReturnTypes = selectClause.getQueryReturnTypes(); - selectNewTransformer = HolderInstantiator.createSelectNewTransformer( - selectClause.getConstructor(), - selectClause.isMap(), - selectClause.isList()); + aggregatedSelectExpression = selectClause.getAggregatedSelectExpression(); queryReturnAliases = selectClause.getQueryReturnAliases(); List collectionFromElements = selectClause.getCollectionFromElements(); @@ -196,63 +196,69 @@ } //NONE, because its the requested lock mode, not the actual! - defaultLockModes = ArrayHelper.fillArray(LockMode.NONE, size); + defaultLockModes = ArrayHelper.fillArray( LockMode.NONE, size ); + } + public AggregatedSelectExpression getAggregatedSelectExpression() { + return aggregatedSelectExpression; } + // -- Loader implementation -- public final void validateScrollability() throws HibernateException { queryTranslator.validateScrollability(); } - + @Override protected boolean needsFetchingScroll() { return queryTranslator.containsCollectionFetches(); } - + @Override public Loadable[] getEntityPersisters() { return entityPersisters; } - + @Override public String[] getAliases() { return sqlAliases; } public String[] getSqlAliasSuffixes() { return sqlAliasSuffixes; } - + @Override public String[] getSuffixes() { return getSqlAliasSuffixes(); } - + @Override public String[] getCollectionSuffixes() { return collectionSuffixes; } - + @Override protected String getQueryIdentifier() { return queryTranslator.getQueryIdentifier(); } /** * The SQL query string to be called. */ - protected String getSQLString() { + @Override + public String getSQLString() { return queryTranslator.getSQLString(); } /** * An (optional) persister for a collection to be initialized; only collection loaders * return a non-null value */ + @Override protected CollectionPersister[] getCollectionPersisters() { return collectionPersisters; } - + @Override protected int[] getCollectionOwners() { return collectionOwners; } - + @Override protected boolean[] getEntityEagerPropertyFetches() { return entityEagerPropertyFetches; } @@ -261,61 +267,92 @@ * An array of indexes of the entity that owns a one-to-one association * to the entity at the given index (-1 if there is no "owner") */ + @Override protected int[] getOwners() { return owners; } - + @Override protected EntityType[] getOwnerAssociationTypes() { return ownerAssociationTypes; } // -- Loader overrides -- - + @Override protected boolean isSubselectLoadingEnabled() { return hasSubselectLoadableCollections(); } /** - * @param lockModes a collection of lock modes specified dynamically via the Query interface + * @param lockOptions a collection of lock modes specified dynamically via the Query interface */ - protected LockMode[] getLockModes(Map lockModes) { + @Override + protected LockMode[] getLockModes(LockOptions lockOptions) { + if ( lockOptions == null ) { + return defaultLockModes; + } - if ( lockModes==null || lockModes.size()==0 ) { + if ( lockOptions.getAliasLockCount() == 0 + && ( lockOptions.getLockMode() == null || LockMode.NONE.equals( lockOptions.getLockMode() ) ) ) { return defaultLockModes; } - else { - // unfortunately this stuff can't be cached because - // it is per-invocation, not constant for the - // QueryTranslator instance - LockMode[] lockModeArray = new LockMode[entityAliases.length]; - for ( int i = 0; i < entityAliases.length; i++ ) { - LockMode lockMode = (LockMode) lockModes.get( entityAliases[i] ); - if ( lockMode == null ) { - //NONE, because its the requested lock mode, not the actual! - lockMode = LockMode.NONE; - } - lockModeArray[i] = lockMode; + // unfortunately this stuff can't be cached because + // it is per-invocation, not constant for the + // QueryTranslator instance + + LockMode[] lockModesArray = new LockMode[entityAliases.length]; + for ( int i = 0; i < entityAliases.length; i++ ) { + LockMode lockMode = lockOptions.getEffectiveLockMode( entityAliases[i] ); + if ( lockMode == null ) { + //NONE, because its the requested lock mode, not the actual! + lockMode = LockMode.NONE; } - return lockModeArray; + lockModesArray[i] = lockMode; } + + return lockModesArray; } - protected String applyLocks(String sql, Map lockModes, Dialect dialect) throws QueryException { - if ( lockModes == null || lockModes.size() == 0 ) { - return sql; - } - + @Override + protected String applyLocks( + String sql, + QueryParameters parameters, + Dialect dialect, + List afterLoadActions) throws QueryException { // can't cache this stuff either (per-invocation) // we are given a map of user-alias -> lock mode // create a new map of sql-alias -> lock mode - final Map aliasedLockModes = new HashMap(); - final Map keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap() : null; - final Iterator iter = lockModes.entrySet().iterator(); - while ( iter.hasNext() ) { - Map.Entry me = ( Map.Entry ) iter.next(); - final String userAlias = ( String ) me.getKey(); - final String drivingSqlAlias = ( String ) sqlAliasByEntityAlias.get( userAlias ); + + final LockOptions lockOptions = parameters.getLockOptions(); + + if ( lockOptions == null || + ( lockOptions.getLockMode() == LockMode.NONE && lockOptions.getAliasLockCount() == 0 ) ) { + return sql; + } + + + // user is request locking, lets see if we can apply locking directly to the SQL... + + // some dialects wont allow locking with paging... + if ( shouldUseFollowOnLocking( parameters, dialect, afterLoadActions ) ) { + return sql; + } + + // there are other conditions we might want to add here, such as checking the result types etc + // but those are better served after we have redone the SQL generation to use ASTs. + + + // we need both the set of locks and the columns to reference in locks + // as the ultimate output of this section... + final LockOptions locks = new LockOptions( lockOptions.getLockMode() ); + final Map keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap() : null; + + locks.setScope( lockOptions.getScope() ); + locks.setTimeOut( lockOptions.getTimeOut() ); + + for ( Map.Entry entry : sqlAliasByEntityAlias.entrySet() ) { + final String userAlias = entry.getKey(); + final String drivingSqlAlias = entry.getValue(); if ( drivingSqlAlias == null ) { throw new IllegalArgumentException( "could not locate alias to apply lock mode : " + userAlias ); } @@ -325,73 +362,131 @@ // the exception case here is joined-subclass hierarchies where we instead // want to apply the lock against the root table (for all other strategies, // it just happens that driving and root are the same). - final QueryNode select = ( QueryNode ) queryTranslator.getSqlAST(); - final Lockable drivingPersister = ( Lockable ) select.getFromClause().getFromElement( userAlias ).getQueryable(); + final QueryNode select = (QueryNode) queryTranslator.getSqlAST(); + final Lockable drivingPersister = (Lockable) select.getFromClause() + .findFromElementByUserOrSqlAlias( userAlias, drivingSqlAlias ) + .getQueryable(); final String sqlAlias = drivingPersister.getRootTableAlias( drivingSqlAlias ); - aliasedLockModes.put( sqlAlias, me.getValue() ); + + final LockMode effectiveLockMode = lockOptions.getEffectiveLockMode( userAlias ); + locks.setAliasSpecificLockMode( sqlAlias, effectiveLockMode ); + if ( keyColumnNames != null ) { keyColumnNames.put( sqlAlias, drivingPersister.getRootTableIdentifierColumnNames() ); } } - return dialect.applyLocksToSql( sql, aliasedLockModes, keyColumnNames ); - } + // apply the collected locks and columns + return dialect.applyLocksToSql( sql, locks, keyColumnNames ); + } + @Override + protected void applyPostLoadLocks(Object[] row, LockMode[] lockModesArray, SessionImplementor session) { + // todo : scalars??? +// if ( row.length != lockModesArray.length ) { +// return; +// } +// +// for ( int i = 0; i < lockModesArray.length; i++ ) { +// if ( LockMode.OPTIMISTIC_FORCE_INCREMENT.equals( lockModesArray[i] ) ) { +// final EntityEntry pcEntry = +// } +// else if ( LockMode.PESSIMISTIC_FORCE_INCREMENT.equals( lockModesArray[i] ) ) { +// +// } +// } + } + @Override protected boolean upgradeLocks() { return true; } private boolean hasSelectNew() { - return selectNewTransformer!=null; + return aggregatedSelectExpression != null && aggregatedSelectExpression.getResultTransformer() != null; } - + @Override + protected String[] getResultRowAliases() { + return queryReturnAliases; + } + @Override + protected ResultTransformer resolveResultTransformer(ResultTransformer resultTransformer) { + final ResultTransformer implicitResultTransformer = aggregatedSelectExpression == null + ? null + : aggregatedSelectExpression.getResultTransformer(); + return HolderInstantiator.resolveResultTransformer( implicitResultTransformer, resultTransformer ); + } + @Override + protected boolean[] includeInResultRow() { + boolean[] includeInResultTuple = includeInSelect; + if ( hasScalars ) { + includeInResultTuple = new boolean[ queryReturnTypes.length ]; + Arrays.fill( includeInResultTuple, true ); + } + return includeInResultTuple; + } + @Override protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session) throws SQLException, HibernateException { - row = toResultRow( row ); + Object[] resultRow = getResultRow( row, rs, session ); boolean hasTransform = hasSelectNew() || transformer!=null; + return ( ! hasTransform && resultRow.length == 1 ? + resultRow[ 0 ] : + resultRow + ); + } + + @Override + protected Object[] getResultRow(Object[] row, ResultSet rs, SessionImplementor session) + throws SQLException, HibernateException { + Object[] resultRow; if ( hasScalars ) { String[][] scalarColumns = scalarColumnNames; int queryCols = queryReturnTypes.length; - if ( !hasTransform && queryCols == 1 ) { - return queryReturnTypes[0].nullSafeGet( rs, scalarColumns[0], session, null ); + resultRow = new Object[queryCols]; + for ( int i = 0; i < queryCols; i++ ) { + resultRow[i] = queryReturnTypes[i].nullSafeGet( rs, scalarColumns[i], session, null ); } - else { - row = new Object[queryCols]; - for ( int i = 0; i < queryCols; i++ ) { - row[i] = queryReturnTypes[i].nullSafeGet( rs, scalarColumns[i], session, null ); - } - return row; - } } - else if ( !hasTransform ) { - return row.length == 1 ? row[0] : row; - } else { - return row; + resultRow = toResultRow( row ); } - + return resultRow; } + @SuppressWarnings("unchecked") + @Override protected List getResultList(List results, ResultTransformer resultTransformer) throws QueryException { // meant to handle dynamic instantiation queries... - HolderInstantiator holderInstantiator = HolderInstantiator.getHolderInstantiator(selectNewTransformer, resultTransformer, queryReturnAliases); + HolderInstantiator holderInstantiator = buildHolderInstantiator( resultTransformer ); if ( holderInstantiator.isRequired() ) { for ( int i = 0; i < results.size(); i++ ) { Object[] row = ( Object[] ) results.get( i ); Object result = holderInstantiator.instantiate(row); results.set( i, result ); } - if(!hasSelectNew() && resultTransformer!=null) { + if ( !hasSelectNew() && resultTransformer != null ) { return resultTransformer.transformList(results); - } else { + } + else { return results; } - } else { + } + else { return results; } } + private HolderInstantiator buildHolderInstantiator(ResultTransformer queryLocalResultTransformer) { + final ResultTransformer implicitResultTransformer = aggregatedSelectExpression == null + ? null + : aggregatedSelectExpression.getResultTransformer(); + return HolderInstantiator.getHolderInstantiator( + implicitResultTransformer, + queryLocalResultTransformer, + queryReturnAliases + ); + } // --- Query translator methods --- public List list( @@ -418,21 +513,21 @@ } try { - - final PreparedStatement st = prepareQueryStatement( queryParameters, false, session ); - - if(queryParameters.isCallable()) { + if ( queryParameters.isCallable() ) { throw new QueryException("iterate() not supported for callable statements"); } - final ResultSet rs = getResultSet(st, queryParameters.hasAutoDiscoverScalarTypes(), false, queryParameters.getRowSelection(), session); + final SqlStatementWrapper wrapper = executeQueryStatement( queryParameters, false, Collections.emptyList(), session ); + final ResultSet rs = wrapper.getResultSet(); + final PreparedStatement st = (PreparedStatement) wrapper.getStatement(); final Iterator result = new IteratorImpl( rs, st, session, + queryParameters.isReadOnly( session ), queryReturnTypes, queryTranslator.getColumnNames(), - HolderInstantiator.getHolderInstantiator(selectNewTransformer, queryParameters.getResultTransformer(), queryReturnAliases) - ); + buildHolderInstantiator( queryParameters.getResultTransformer() ) + ); if ( stats ) { session.getFactory().getStatisticsImplementor().queryExecuted( @@ -447,8 +542,7 @@ } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - getFactory().getSQLExceptionConverter(), + throw getFactory().getSQLExceptionHelper().convert( sqle, "could not execute query using iterate", getSQLString() @@ -461,7 +555,12 @@ final QueryParameters queryParameters, final SessionImplementor session) throws HibernateException { checkQuery( queryParameters ); - return scroll( queryParameters, queryReturnTypes, HolderInstantiator.getHolderInstantiator(selectNewTransformer, queryParameters.getResultTransformer(), queryReturnAliases), session ); + return scroll( + queryParameters, + queryReturnTypes, + buildHolderInstantiator( queryParameters.getResultTransformer() ), + session + ); } // -- Implementation private methods -- @@ -485,14 +584,15 @@ /** * Returns the locations of all occurrences of the named parameter. */ + @Override public int[] getNamedParameterLocs(String name) throws QueryException { return queryTranslator.getParameterTranslations().getNamedParameterSqlLocations( name ); } /** * We specifically override this method here, because in general we know much more * about the parameters and their appropriate bind positions here then we do in - * our super because we track them explciitly here through the ParameterSpecification + * our super because we track them explicitly here through the ParameterSpecification * interface. * * @param queryParameters The encapsulation of the parameter values to be bound. @@ -501,43 +601,17 @@ * @return The number of JDBC bind positions actually bound during this method execution. * @throws SQLException Indicates problems performing the binding. */ + @Override protected int bindParameterValues( final PreparedStatement statement, final QueryParameters queryParameters, final int startIndex, final SessionImplementor session) throws SQLException { - int position = bindFilterParameterValues( statement, queryParameters, startIndex, session ); - List parameterSpecs = queryTranslator.getSqlAST().getWalker().getParameters(); - Iterator itr = parameterSpecs.iterator(); - while ( itr.hasNext() ) { - ParameterSpecification spec = ( ParameterSpecification ) itr.next(); + int position = startIndex; + List parameterSpecs = queryTranslator.getCollectedParameterSpecifications(); + for ( ParameterSpecification spec : parameterSpecs ) { position += spec.bind( statement, queryParameters, session, position ); } return position - startIndex; } - - private int bindFilterParameterValues( - PreparedStatement st, - QueryParameters queryParameters, - int position, - SessionImplementor session) throws SQLException { - // todo : better to handle dynamic filters through implicit DynamicFilterParameterSpecification - // see the discussion there in DynamicFilterParameterSpecification's javadocs as to why - // it is currently not done that way. - int filteredParamCount = queryParameters.getFilteredPositionalParameterTypes() == null - ? 0 - : queryParameters.getFilteredPositionalParameterTypes().length; - int nonfilteredParamCount = queryParameters.getPositionalParameterTypes() == null - ? 0 - : queryParameters.getPositionalParameterTypes().length; - int filterParamCount = filteredParamCount - nonfilteredParamCount; - for ( int i = 0; i < filterParamCount; i++ ) { - Type type = queryParameters.getFilteredPositionalParameterTypes()[i]; - Object value = queryParameters.getFilteredPositionalParameterValues()[i]; - type.nullSafeSet( st, value, position, session ); - position += type.getColumnSpan( getFactory() ); - } - - return position; - } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/AbstractEntityGraphVisitationStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/AbstractLoadPlanBuildingAssociationVisitationStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/CascadeStyleLoadPlanBuildingAssociationVisitationStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/FetchGraphLoadPlanBuildingStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/FetchStyleLoadPlanBuildingAssociationVisitationStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/LoadGraphLoadPlanBuildingStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/LoadPlanImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/AbstractAnyReference.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/AbstractCollectionReference.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/AbstractCompositeEntityIdentifierDescription.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/AbstractCompositeFetch.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/AbstractCompositeReference.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/AbstractEntityReference.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/AbstractExpandingFetchSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/AnyAttributeFetchImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/BidirectionalEntityReferenceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/CollectionAttributeFetchImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/CollectionFetchableElementAnyGraph.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/CollectionFetchableElementCompositeGraph.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/CollectionFetchableElementEntityGraph.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/CollectionFetchableIndexAnyGraph.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/CollectionFetchableIndexCompositeGraph.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/CollectionFetchableIndexEntityGraph.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/CollectionReturnImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/CompositeAttributeFetchImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/EncapsulatedEntityIdentifierDescription.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/EntityAttributeFetchImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/EntityReturnImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/NestedCompositeAttributeFetchImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/NonEncapsulatedEntityIdentifierDescription.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/ScalarReturnImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/SimpleEntityIdentifierDescriptionImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/returns/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/spaces/AbstractExpandingSourceQuerySpace.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/spaces/AbstractQuerySpace.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/spaces/CollectionQuerySpaceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/spaces/CompositePropertyMapping.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/spaces/CompositeQuerySpaceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/spaces/EntityQuerySpaceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/spaces/JoinHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/spaces/JoinImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/spaces/QuerySpaceHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/spaces/QuerySpacesImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/internal/spaces/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/ExpandingCollectionQuerySpace.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/ExpandingCompositeQuerySpace.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/ExpandingEntityIdentifierDescription.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/ExpandingEntityQuerySpace.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/ExpandingFetchSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/ExpandingQuerySpace.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/ExpandingQuerySpaces.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/LoadPlanBuildingAssociationVisitationStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/LoadPlanBuildingContext.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/LoadPlanTreePrinter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/MetamodelDrivenLoadPlanBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/QuerySpaceTreePrinter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/ReturnGraphTreePrinter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/TreePrinterHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/build/spi/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/internal/AbstractCollectionLoadQueryDetails.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/internal/AbstractLoadPlanBasedLoader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/internal/AbstractLoadQueryDetails.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/internal/AliasResolutionContextImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/internal/BasicCollectionLoadQueryDetails.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/internal/BatchingLoadQueryDetailsFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/internal/CollectionReferenceAliasesImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/internal/EntityLoadQueryDetails.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/internal/EntityReferenceAliasesImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/internal/FetchStats.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/internal/LoadQueryJoinAndFetchProcessor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/internal/OneToManyLoadQueryDetails.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/internal/RootHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/internal/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/internal/AbstractRowReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/internal/CollectionReferenceInitializerImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/internal/CollectionReturnReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/internal/EntityReferenceInitializerImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/internal/EntityReturnReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/internal/HydratedEntityRegistration.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/internal/ResultSetProcessingContextImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/internal/ResultSetProcessorHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/internal/ResultSetProcessorImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/spi/CollectionReferenceInitializer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/spi/EntityReferenceInitializer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/spi/ReaderCollector.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/spi/ResultSetProcessingContext.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/spi/ResultSetProcessor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/spi/ReturnReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/spi/RowReader.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/process/spi/ScrollableResultSetProcessor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/query/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/query/internal/SelectStatementBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/query/internal/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/query/spi/NamedParameterContext.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/query/spi/QueryBuildingParameters.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/query/spi/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/spi/AliasResolutionContext.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/spi/CollectionReferenceAliases.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/spi/EntityReferenceAliases.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/spi/LoadQueryDetails.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/spi/LockModeResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/exec/spi/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/AnyAttributeFetch.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/AttributeFetch.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/BidirectionalEntityReference.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/CollectionAttributeFetch.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/CollectionFetchableElement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/CollectionFetchableIndex.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/CollectionQuerySpace.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/CollectionReference.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/CollectionReturn.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/CompositeAttributeFetch.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/CompositeFetch.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/CompositeQuerySpace.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/EntityFetch.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/EntityIdentifierDescription.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/EntityQuerySpace.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/EntityReference.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/EntityReturn.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/Fetch.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/FetchSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/Join.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/JoinDefinedByMetadata.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/LoadPlan.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/QuerySpace.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/QuerySpaceUidNotRegisteredException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/QuerySpaces.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/Return.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/ScalarReturn.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/plan/spi/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/loader/spi/AfterLoadAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/lob/BlobImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/lob/ClobImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/lob/ReaderInputStream.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/lob/ReaderInputStream.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/lob/ReaderInputStream.java 17 Aug 2012 14:33:55 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/lob/ReaderInputStream.java 30 Jul 2014 16:16:30 -0000 1.1.2.1 @@ -23,25 +23,22 @@ * */ package org.hibernate.lob; - import java.io.IOException; -import java.io.InputStream; import java.io.Reader; /** - * Exposes a Reader as an InputStream - * @author Gavin King + * Exposes a {@link java.io.Reader} as an {@link java.io.InputStream}. + * + * @deprecated Should not be used anymore. */ -public class ReaderInputStream extends InputStream { - - private Reader reader; - +public class ReaderInputStream extends org.hibernate.engine.jdbc.ReaderInputStream { + public ReaderInputStream(Reader reader) { - this.reader = reader; + super(reader); } - + public int read() throws IOException { - return reader.read(); + return super.read(); } - + } Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/lob/SerializableBlob.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/lob/SerializableClob.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/lob/package.html'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/AbstractAuxiliaryDatabaseObject.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/AbstractAuxiliaryDatabaseObject.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/AbstractAuxiliaryDatabaseObject.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/AbstractAuxiliaryDatabaseObject.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,10 +20,8 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.util.HashSet; import org.hibernate.dialect.Dialect; Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Any.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Any.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Any.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Any.java 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,32 +20,27 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ - package org.hibernate.mapping; - import java.util.Map; import org.hibernate.MappingException; +import org.hibernate.cfg.Mappings; import org.hibernate.type.MetaType; -import org.hibernate.type.AnyType; import org.hibernate.type.Type; -import org.hibernate.type.TypeFactory; /** * A Hibernate "any" type (ie. polymorphic association to * one-of-several tables). * @author Gavin King */ public class Any extends SimpleValue { - private String identifierTypeName; private String metaTypeName = "string"; private Map metaValues; - public Any(Table table) { - super(table); + public Any(Mappings mappings, Table table) { + super( mappings, table ); } public String getIdentifierType() { @@ -57,11 +52,11 @@ } public Type getType() throws MappingException { - return new AnyType( - metaValues==null ? - TypeFactory.heuristicType(metaTypeName) : - new MetaType( metaValues, TypeFactory.heuristicType(metaTypeName) ), - TypeFactory.heuristicType(identifierTypeName) + final Type metaType = getMappings().getTypeResolver().heuristicType( metaTypeName ); + + return getMappings().getTypeResolver().getTypeFactory().any( + metaValues == null ? metaType : new MetaType( metaValues, metaType ), + getMappings().getTypeResolver().heuristicType( identifierTypeName ) ); } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Array.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Array.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Array.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Array.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,31 +20,26 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; import org.hibernate.MappingException; +import org.hibernate.cfg.Mappings; +import org.hibernate.internal.util.ReflectHelper; import org.hibernate.type.CollectionType; import org.hibernate.type.PrimitiveType; -import org.hibernate.type.TypeFactory; -import org.hibernate.util.ReflectHelper; /** - * An array mapping has a primary key consisting of - * the key columns + index column. + * An array mapping has a primary key consisting of the key columns + index column. + * * @author Gavin King */ public class Array extends List { private String elementClassName; - /** - * Constructor for Array. - * @param owner - */ - public Array(PersistentClass owner) { - super(owner); + public Array(Mappings mappings, PersistentClass owner) { + super( mappings, owner ); } public Class getElementClass() throws MappingException { @@ -64,11 +59,15 @@ } } - public CollectionType getDefaultCollectionType() throws MappingException { - return TypeFactory.array( getRole(), getReferencedPropertyName(), isEmbedded(), getElementClass() ); + @Override + public CollectionType getDefaultCollectionType() throws MappingException { + return getMappings().getTypeResolver() + .getTypeFactory() + .array( getRole(), getReferencedPropertyName(), getElementClass() ); } - public boolean isArray() { + @Override + public boolean isArray() { return true; } @@ -84,8 +83,9 @@ public void setElementClassName(String elementClassName) { this.elementClassName = elementClassName; } - - public Object accept(ValueVisitor visitor) { + + @Override + public Object accept(ValueVisitor visitor) { return visitor.accept(this); } } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/AuxiliaryDatabaseObject.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/AuxiliaryDatabaseObject.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/AuxiliaryDatabaseObject.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/AuxiliaryDatabaseObject.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,10 +20,8 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.io.Serializable; import org.hibernate.dialect.Dialect; Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Backref.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Backref.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Backref.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Backref.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; @@ -33,28 +32,39 @@ public class Backref extends Property { private String collectionRole; private String entityName; - + + @Override public boolean isBackRef() { return true; } + + @Override + public boolean isSynthetic() { + return true; + } + public String getCollectionRole() { return collectionRole; } + public void setCollectionRole(String collectionRole) { this.collectionRole = collectionRole; } + @Override public boolean isBasicPropertyAccessor() { return false; } + @Override public PropertyAccessor getPropertyAccessor(Class clazz) { return new BackrefPropertyAccessor(collectionRole, entityName); } public String getEntityName() { return entityName; } + public void setEntityName(String entityName) { this.entityName = entityName; } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Bag.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Bag.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Bag.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Bag.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,12 +20,10 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - +import org.hibernate.cfg.Mappings; import org.hibernate.type.CollectionType; -import org.hibernate.type.TypeFactory; /** * A bag permits duplicates, so it has no primary key @@ -34,12 +32,14 @@ */ public class Bag extends Collection { - public Bag(PersistentClass owner) { - super(owner); + public Bag(Mappings mappings, PersistentClass owner) { + super( mappings, owner ); } public CollectionType getDefaultCollectionType() { - return TypeFactory.bag( getRole(), getReferencedPropertyName(), isEmbedded() ); + return getMappings().getTypeResolver() + .getTypeFactory() + .bag( getRole(), getReferencedPropertyName() ); } void createPrimaryKey() { Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Collection.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Collection.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Collection.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Collection.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,26 +20,26 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; +import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Properties; import org.hibernate.FetchMode; import org.hibernate.MappingException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.ExecuteUpdateResultCheckStyle; +import org.hibernate.cfg.Mappings; +import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.internal.FilterConfiguration; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.type.CollectionType; import org.hibernate.type.Type; -import org.hibernate.type.TypeFactory; -import org.hibernate.util.ArrayHelper; -import org.hibernate.util.EmptyIterator; -import org.hibernate.util.ReflectHelper; /** * Mapping for a collection. Subclasses specialize to particular collection styles. @@ -51,6 +51,9 @@ public static final String DEFAULT_ELEMENT_COLUMN_NAME = "elt"; public static final String DEFAULT_KEY_COLUMN_NAME = "id"; + private final Mappings mappings; + private PersistentClass owner; + private KeyValue key; private Value element; private Table collectionTable; @@ -66,10 +69,10 @@ private String where; private String manyToManyWhere; private String manyToManyOrderBy; - private PersistentClass owner; private String referencedPropertyName; private String nodeName; private String elementNodeName; + private String mappedByProperty; private boolean sorted; private Comparator comparator; private String comparatorClassName; @@ -81,8 +84,8 @@ private Class collectionPersisterClass; private String typeName; private Properties typeParameters; - private final java.util.Map filters = new HashMap(); - private final java.util.Map manyToManyFilters = new HashMap(); + private final java.util.List filters = new ArrayList(); + private final java.util.List manyToManyFilters = new ArrayList(); private final java.util.Set synchronizedTables = new HashSet(); private String customSQLInsert; @@ -100,10 +103,15 @@ private String loaderName; - protected Collection(PersistentClass owner) { + protected Collection(Mappings mappings, PersistentClass owner) { + this.mappings = mappings; this.owner = owner; } + public Mappings getMappings() { + return mappings; + } + public boolean isSet() { return false; } @@ -206,7 +214,7 @@ } public void setRole(String role) { - this.role = role==null ? null : role.intern(); + this.role = role; } public void setSorted(boolean sorted) { @@ -221,7 +229,13 @@ return owner; } - public void setOwner(PersistentClass owner) { + /** + * @deprecated Inject the owner into constructor. + * + * @param owner The owner + */ + @Deprecated + public void setOwner(PersistentClass owner) { this.owner = owner; } @@ -353,8 +367,8 @@ } } - public Iterator getColumnIterator() { - return EmptyIterator.INSTANCE; + public Iterator getColumnIterator() { + return Collections.emptyList().iterator(); } public int getColumnSpan() { @@ -370,7 +384,9 @@ return getDefaultCollectionType(); } else { - return TypeFactory.customCollection( typeName, typeParameters, role, referencedPropertyName, isEmbedded() ); + return mappings.getTypeResolver() + .getTypeFactory() + .customCollection( typeName, typeParameters, role, referencedPropertyName ); } } @@ -506,23 +522,23 @@ return deleteAllCheckStyle; } - public void addFilter(String name, String condition) { - filters.put( name, condition ); + public void addFilter(String name, String condition, boolean autoAliasInjection, java.util.Map aliasTableMap, java.util.Map aliasEntityMap) { + filters.add(new FilterConfiguration(name, condition, autoAliasInjection, aliasTableMap, aliasEntityMap, null)); } - - public java.util.Map getFilterMap() { + public java.util.List getFilters() { return filters; } - public void addManyToManyFilter(String name, String condition) { - manyToManyFilters.put( name, condition ); + public void addManyToManyFilter(String name, String condition, boolean autoAliasInjection, java.util.Map aliasTableMap, java.util.Map aliasEntityMap) { + manyToManyFilters.add(new FilterConfiguration(name, condition, autoAliasInjection, aliasTableMap, aliasEntityMap, null)); } - public java.util.Map getManyToManyFilterMap() { + public java.util.List getManyToManyFilters() { return manyToManyFilters; } - public String toString() { + @Override + public String toString() { return getClass().getName() + '(' + getRole() + ')'; } @@ -535,15 +551,15 @@ } public void setLoaderName(String name) { - this.loaderName = name==null ? null : name.intern(); + this.loaderName = name; } public String getReferencedPropertyName() { return referencedPropertyName; } public void setReferencedPropertyName(String propertyRef) { - this.referencedPropertyName = propertyRef==null ? null : propertyRef.intern(); + this.referencedPropertyName = propertyRef; } public boolean isOptimisticLocked() { @@ -598,10 +614,20 @@ this.elementNodeName = elementNodeName; } + /** + * @deprecated To be removed in 5. Removed as part of removing the notion of DOM entity-mode. + * See Jira issue: HHH-7771 + */ + @Deprecated public boolean isEmbedded() { return embedded; } + /** + * @deprecated To be removed in 5. Removed as part of removing the notion of DOM entity-mode. + * See Jira issue: HHH-7771 + */ + @Deprecated public void setEmbedded(boolean embedded) { this.embedded = embedded; } @@ -642,4 +668,12 @@ public String getComparatorClassName() { return comparatorClassName; } -} \ No newline at end of file + + public String getMappedByProperty() { + return mappedByProperty; + } + + public void setMappedByProperty(String mappedByProperty) { + this.mappedByProperty = mappedByProperty; + } +} Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Column.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Column.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Column.java 17 Aug 2012 14:33:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Column.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,18 +20,17 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.io.Serializable; 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; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.sql.Template; /** * A column of a relational database table @@ -47,19 +46,22 @@ private int precision=DEFAULT_PRECISION; private int scale=DEFAULT_SCALE; private Value value; - private int typeIndex = 0; + private int typeIndex; private String name; private boolean nullable=true; - private boolean unique=false; + private boolean unique; private String sqlType; private Integer sqlTypeCode; - private boolean quoted=false; + private boolean quoted; int uniqueInteger; private String checkConstraint; private String comment; private String defaultValue; + private String customWrite; + private String customRead; - public Column() { }; + public Column() { + } public Column(String columnName) { setName(columnName); @@ -82,7 +84,7 @@ } public void setName(String name) { if ( - name.charAt(0)=='`' || + StringHelper.isNotEmpty( name ) && Dialect.QUOTE.indexOf( name.charAt(0) ) > -1 //TODO: deprecated, remove eventually ) { quoted=true; @@ -106,38 +108,38 @@ name; } - /** - * For any column name, generate an alias that is unique - * to that column name, and also 10 characters or less - * in length. - */ + @Override public String getAlias(Dialect dialect) { + final int lastLetter = StringHelper.lastIndexOfLetter( name ); + final String suffix = Integer.toString(uniqueInteger) + '_'; + String alias = name; - String unique = Integer.toString(uniqueInteger) + '_'; - int lastLetter = StringHelper.lastIndexOfLetter(name); if ( lastLetter == -1 ) { alias = "column"; } - else if ( lastLetter < name.length()-1 ) { - alias = name.substring(0, lastLetter+1); + else if ( name.length() > lastLetter + 1 ) { + alias = name.substring( 0, lastLetter + 1 ); } - if ( alias.length() > dialect.getMaxAliasLength() ) { - alias = alias.substring( 0, dialect.getMaxAliasLength() - unique.length() ); + + boolean useRawName = name.length() + suffix.length() <= dialect.getMaxAliasLength() + && !quoted && !name.toLowerCase().equals( "rowid" ); + if ( !useRawName ) { + if ( suffix.length() >= dialect.getMaxAliasLength() ) { + throw new MappingException( String.format( + "Unique suffix [%s] length must be less than maximum [%d]", + suffix, dialect.getMaxAliasLength() ) ); + } + if ( alias.length() + suffix.length() > dialect.getMaxAliasLength() ) { + alias = alias.substring( 0, dialect.getMaxAliasLength() - suffix.length() ); + } } - boolean useRawName = name.equals(alias) && - !quoted && - !name.toLowerCase().equals("rowid"); - if ( useRawName ) { - return alias; - } - else { - return alias + unique; - } + return alias + suffix; } /** * Generate a column alias that is unique across multiple tables */ + @Override public String getAlias(Dialect dialect, Table table) { return getAlias(dialect) + table.getUniqueInteger() + '_'; } @@ -157,56 +159,19 @@ this.typeIndex = typeIndex; } - public int getSqlTypeCode(Mapping mapping) throws MappingException { - org.hibernate.type.Type type = getValue().getType(); - try { - int sqlTypeCode = type.sqlTypes(mapping)[ getTypeIndex() ]; - if(getSqlTypeCode()!=null && getSqlTypeCode().intValue()!=sqlTypeCode) { - throw new MappingException("SQLType code's does not match. mapped as " + sqlTypeCode + " but is " + getSqlTypeCode() ); - } - return sqlTypeCode; - } - catch (Exception e) { - throw new MappingException( - "Could not determine type for column " + - name + - " of type " + - type.getClass().getName() + - ": " + - e.getClass().getName(), - e - ); - } - } - - /** - * Returns the underlying columns sqltypecode. - * If null, it is because the sqltype code is unknown. - * - * Use #getSqlTypeCode(Mapping) to retreive the sqltypecode used - * for the columns associated Value/Type. - * - * @return sqltypecode if it is set, otherwise null. - */ - public Integer getSqlTypeCode() { - return sqlTypeCode; - } - - public void setSqlTypeCode(Integer typecode) { - sqlTypeCode=typecode; - } - public boolean isUnique() { return unique; } - - public String getSqlType(Dialect dialect, Mapping mapping) throws HibernateException { - return sqlType==null ? - dialect.getTypeName( getSqlTypeCode(mapping), getLength(), getPrecision(), getScale() ) : - sqlType; + @Override + public int hashCode() { + //used also for generation of FK names! + return isQuoted() ? + name.hashCode() : + name.toLowerCase().hashCode(); } + @Override public boolean equals(Object object) { return object instanceof Column && equals( (Column) object ); } @@ -220,13 +185,52 @@ name.equalsIgnoreCase(column.name); } - //used also for generation of FK names! - public int hashCode() { - return isQuoted() ? - name.hashCode() : - name.toLowerCase().hashCode(); - } + public int getSqlTypeCode(Mapping mapping) throws MappingException { + org.hibernate.type.Type type = getValue().getType(); + try { + int sqlTypeCode = type.sqlTypes( mapping )[getTypeIndex()]; + if ( getSqlTypeCode() != null && getSqlTypeCode() != sqlTypeCode ) { + throw new MappingException( "SQLType code's does not match. mapped as " + sqlTypeCode + " but is " + getSqlTypeCode() ); + } + return sqlTypeCode; + } + catch ( Exception e ) { + throw new MappingException( + "Could not determine type for column " + + name + + " of type " + + type.getClass().getName() + + ": " + + e.getClass().getName(), + e + ); + } + } + /** + * Returns the underlying columns sqltypecode. + * If null, it is because the sqltype code is unknown. + * + * Use #getSqlTypeCode(Mapping) to retreive the sqltypecode used + * for the columns associated Value/Type. + * + * @return sqlTypeCode if it is set, otherwise null. + */ + public Integer getSqlTypeCode() { + return sqlTypeCode; + } + + public void setSqlTypeCode(Integer typeCode) { + sqlTypeCode=typeCode; + } + + public String getSqlType(Dialect dialect, Mapping mapping) throws HibernateException { + if ( sqlType == null ) { + sqlType = dialect.getTypeName( getSqlTypeCode( mapping ), getLength(), getPrecision(), getScale() ); + } + return sqlType; + } + public String getSqlType() { return sqlType; } @@ -243,6 +247,7 @@ return quoted; } + @Override public String toString() { return getClass().getName() + '(' + getName() + ')'; } @@ -259,17 +264,36 @@ return checkConstraint!=null; } + @Override public String getTemplate(Dialect dialect, SQLFunctionRegistry functionRegistry) { - return getQuotedName(dialect); + return hasCustomRead() + ? Template.renderWhereStringTemplate( customRead, dialect, functionRegistry ) + : Template.TEMPLATE + '.' + getQuotedName( dialect ); } + public boolean hasCustomRead() { + return ( customRead != null && customRead.length() > 0 ); + } + + public String getReadExpr(Dialect dialect) { + return hasCustomRead() ? customRead : getQuotedName( dialect ); + } + + public String getWriteExpr() { + return ( customWrite != null && customWrite.length() > 0 ) ? customWrite : "?"; + } + + @Override public boolean isFormula() { return false; } + @Override public String getText(Dialect d) { return getQuotedName(d); } + + @Override public String getText() { return getName(); } @@ -304,14 +328,31 @@ this.defaultValue = defaultValue; } + public String getCustomWrite() { + return customWrite; + } + + public void setCustomWrite(String customWrite) { + this.customWrite = customWrite; + } + + public String getCustomRead() { + return customRead; + } + + public void setCustomRead(String customRead) { + this.customRead = customRead; + } + public String getCanonicalName() { return quoted ? name : name.toLowerCase(); } /** * Shallow copy, the value is not copied */ - protected Object clone() { + @Override + public Column clone() { Column copy = new Column(); copy.setLength( length ); copy.setScale( scale ); @@ -327,6 +368,8 @@ copy.setCheckConstraint( checkConstraint ); copy.setComment( comment ); copy.setDefaultValue( defaultValue ); + copy.setCustomRead( customRead ); + copy.setCustomWrite( customWrite ); return copy; } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Component.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Component.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Component.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Component.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,32 +20,39 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - +import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.hibernate.EntityMode; import org.hibernate.MappingException; +import org.hibernate.cfg.Mappings; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.id.CompositeNestedGeneratedValueGenerator; +import org.hibernate.id.IdentifierGenerator; +import org.hibernate.id.PersistentIdentifierGenerator; +import org.hibernate.id.factory.IdentifierGeneratorFactory; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.internal.util.collections.JoinedIterator; +import org.hibernate.property.Setter; import org.hibernate.tuple.component.ComponentMetamodel; -import org.hibernate.type.ComponentType; -import org.hibernate.type.EmbeddedComponentType; import org.hibernate.type.Type; -import org.hibernate.util.JoinedIterator; -import org.hibernate.util.ReflectHelper; +import org.hibernate.type.TypeFactory; /** * The mapping for a component, composite element, * composite identifier, etc. + * * @author Gavin King + * @author Steve Ebersole */ public class Component extends SimpleValue implements MetaAttributable { - - private ArrayList properties = new ArrayList(); + private ArrayList properties = new ArrayList(); private String componentClassName; private boolean embedded; private String parentProperty; @@ -56,40 +63,46 @@ private boolean isKey; private String roleName; - private java.util.Map tuplizerImpls; + private java.util.Map tuplizerImpls; - public Component(PersistentClass owner) throws MappingException { - super( owner.getTable() ); + public Component(Mappings mappings, PersistentClass owner) throws MappingException { + super( mappings, owner.getTable() ); this.owner = owner; } - public Component(Component component) throws MappingException { - super( component.getTable() ); + public Component(Mappings mappings, Component component) throws MappingException { + super( mappings, component.getTable() ); this.owner = component.getOwner(); } - public Component(Join join) throws MappingException { - super( join.getTable() ); + public Component(Mappings mappings, Join join) throws MappingException { + super( mappings, join.getTable() ); this.owner = join.getPersistentClass(); } - public Component(Collection collection) throws MappingException { - super( collection.getCollectionTable() ); + public Component(Mappings mappings, Collection collection) throws MappingException { + super( mappings, collection.getCollectionTable() ); this.owner = collection.getOwner(); } public int getPropertySpan() { return properties.size(); } + public Iterator getPropertyIterator() { return properties.iterator(); } + public void addProperty(Property p) { - properties.add(p); + properties.add( p ); } + + @Override public void addColumn(Column column) { throw new UnsupportedOperationException("Cant add a column to a component"); } + + @Override public int getColumnSpan() { int n=0; Iterator iter = getPropertyIterator(); @@ -99,18 +112,19 @@ } return n; } - public Iterator getColumnIterator() { + + @Override + @SuppressWarnings("unchecked") + public Iterator getColumnIterator() { Iterator[] iters = new Iterator[ getPropertySpan() ]; Iterator iter = getPropertyIterator(); int i=0; while ( iter.hasNext() ) { iters[i++] = ( (Property) iter.next() ).getColumnIterator(); } - return new JoinedIterator(iters); + return new JoinedIterator( iters ); } - public void setTypeByReflection(String propertyClass, String propertyName) {} - public boolean isEmbedded() { return embedded; } @@ -160,46 +174,40 @@ this.dynamic = dynamic; } - private Type type; - + @Override public Type getType() throws MappingException { - // added this caching as I noticed that getType() is being called multiple times... - if ( type == null ) { - type = buildType(); - } - return type; - } - - private Type buildType() { // TODO : temporary initial step towards HHH-1907 - ComponentMetamodel metamodel = new ComponentMetamodel( this ); - if ( isEmbedded() ) { - return new EmbeddedComponentType( metamodel ); - } - else { - return new ComponentType( metamodel ); - } + final ComponentMetamodel metamodel = new ComponentMetamodel( this ); + final TypeFactory factory = getMappings().getTypeResolver().getTypeFactory(); + return isEmbedded() ? factory.embeddedComponent( metamodel ) : factory.component( metamodel ); } + @Override public void setTypeUsingReflection(String className, String propertyName) throws MappingException { } - + + @Override public java.util.Map getMetaAttributes() { return metaAttributes; } + + @Override public MetaAttribute getMetaAttribute(String attributeName) { return metaAttributes==null?null:(MetaAttribute) metaAttributes.get(attributeName); } + @Override public void setMetaAttributes(java.util.Map metas) { this.metaAttributes = metas; } - + + @Override public Object accept(ValueVisitor visitor) { return visitor.accept(this); } - + + @Override public boolean[] getColumnInsertability() { boolean[] result = new boolean[ getColumnSpan() ]; Iterator iter = getPropertyIterator(); @@ -215,6 +223,7 @@ return result; } + @Override public boolean[] getColumnUpdateability() { boolean[] result = new boolean[ getColumnSpan() ]; Iterator iter = getPropertyIterator(); @@ -252,7 +261,7 @@ public void addTuplizer(EntityMode entityMode, String implClassName) { if ( tuplizerImpls == null ) { - tuplizerImpls = new HashMap(); + tuplizerImpls = new HashMap(); } tuplizerImpls.put( entityMode, implClassName ); } @@ -262,9 +271,10 @@ if ( tuplizerImpls == null ) { return null; } - return ( String ) tuplizerImpls.get( mode ); + return tuplizerImpls.get( mode ); } + @SuppressWarnings("UnusedDeclaration") public Map getTuplizerMap() { if ( tuplizerImpls == null ) { return null; @@ -291,8 +301,152 @@ this.roleName = roleName; } + @Override public String toString() { return getClass().getName() + '(' + properties.toString() + ')'; } + private IdentifierGenerator builtIdentifierGenerator; + + @Override + public IdentifierGenerator createIdentifierGenerator( + IdentifierGeneratorFactory identifierGeneratorFactory, + Dialect dialect, + String defaultCatalog, + String defaultSchema, + RootClass rootClass) throws MappingException { + if ( builtIdentifierGenerator == null ) { + builtIdentifierGenerator = buildIdentifierGenerator( + identifierGeneratorFactory, + dialect, + defaultCatalog, + defaultSchema, + rootClass + ); + } + return builtIdentifierGenerator; + } + + private IdentifierGenerator buildIdentifierGenerator( + IdentifierGeneratorFactory identifierGeneratorFactory, + Dialect dialect, + String defaultCatalog, + String defaultSchema, + RootClass rootClass) throws MappingException { + final boolean hasCustomGenerator = ! DEFAULT_ID_GEN_STRATEGY.equals( getIdentifierGeneratorStrategy() ); + if ( hasCustomGenerator ) { + return super.createIdentifierGenerator( + identifierGeneratorFactory, dialect, defaultCatalog, defaultSchema, rootClass + ); + } + + final Class entityClass = rootClass.getMappedClass(); + final Class attributeDeclarer; // what class is the declarer of the composite pk attributes + CompositeNestedGeneratedValueGenerator.GenerationContextLocator locator; + + // IMPL NOTE : See the javadoc discussion on CompositeNestedGeneratedValueGenerator wrt the + // various scenarios for which we need to account here + if ( rootClass.getIdentifierMapper() != null ) { + // we have the @IdClass / case + attributeDeclarer = resolveComponentClass(); + } + else if ( rootClass.getIdentifierProperty() != null ) { + // we have the "@EmbeddedId" / case + attributeDeclarer = resolveComponentClass(); + } + else { + // we have the "straight up" embedded (again the hibernate term) component identifier + attributeDeclarer = entityClass; + } + + locator = new StandardGenerationContextLocator( rootClass.getEntityName() ); + final CompositeNestedGeneratedValueGenerator generator = new CompositeNestedGeneratedValueGenerator( locator ); + + Iterator itr = getPropertyIterator(); + while ( itr.hasNext() ) { + final Property property = (Property) itr.next(); + if ( property.getValue().isSimpleValue() ) { + final SimpleValue value = (SimpleValue) property.getValue(); + + if ( DEFAULT_ID_GEN_STRATEGY.equals( value.getIdentifierGeneratorStrategy() ) ) { + // skip any 'assigned' generators, they would have been handled by + // the StandardGenerationContextLocator + continue; + } + + final IdentifierGenerator valueGenerator = value.createIdentifierGenerator( + identifierGeneratorFactory, + dialect, + defaultCatalog, + defaultSchema, + rootClass + ); + generator.addGeneratedValuePlan( + new ValueGenerationPlan( + property.getName(), + valueGenerator, + injector( property, attributeDeclarer ) + ) + ); + } + } + return generator; + } + + private Setter injector(Property property, Class attributeDeclarer) { + return property.getPropertyAccessor( attributeDeclarer ) + .getSetter( attributeDeclarer, property.getName() ); + } + + private Class resolveComponentClass() { + try { + return getComponentClass(); + } + catch ( Exception e ) { + return null; + } + } + + public static class StandardGenerationContextLocator + implements CompositeNestedGeneratedValueGenerator.GenerationContextLocator { + private final String entityName; + + public StandardGenerationContextLocator(String entityName) { + this.entityName = entityName; + } + + @Override + public Serializable locateGenerationContext(SessionImplementor session, Object incomingObject) { + return session.getEntityPersister( entityName, incomingObject ).getIdentifier( incomingObject, session ); + } + } + + public static class ValueGenerationPlan implements CompositeNestedGeneratedValueGenerator.GenerationPlan { + private final String propertyName; + private final IdentifierGenerator subGenerator; + private final Setter injector; + + public ValueGenerationPlan( + String propertyName, + IdentifierGenerator subGenerator, + Setter injector) { + this.propertyName = propertyName; + this.subGenerator = subGenerator; + this.injector = injector; + } + + @Override + public void execute(SessionImplementor session, Object incomingObject, Object injectionContext) { + final Object generatedValue = subGenerator.generate( session, incomingObject ); + injector.set( injectionContext, generatedValue, session.getFactory() ); + } + + @Override + public void registerPersistentGenerators(Map generatorMap) { + if ( PersistentIdentifierGenerator.class.isInstance( subGenerator ) ) { + generatorMap.put( ( (PersistentIdentifierGenerator) subGenerator ).generatorKey(), subGenerator ); + } + } + } + } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Constraint.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Constraint.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Constraint.java 17 Aug 2012 14:33:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Constraint.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,27 +20,33 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.io.Serializable; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; import java.util.Iterator; import java.util.List; +import org.hibernate.HibernateException; +import org.hibernate.annotations.common.util.StringHelper; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.Mapping; +import org.hibernate.engine.spi.Mapping; /** * A relational constraint. * * @author Gavin King + * @author Brett Meyer */ public abstract class Constraint implements RelationalModel, Serializable { private String name; - private final List columns = new ArrayList(); + private final ArrayList columns = new ArrayList(); private Table table; public String getName() { @@ -50,11 +56,86 @@ public void setName(String name) { this.name = name; } + + /** + * If a constraint is not explicitly named, this is called to generate + * a unique hash using the table and column names. + * Static so the name can be generated prior to creating the Constraint. + * They're cached, keyed by name, in multiple locations. + * + * @param prefix + * Appended to the beginning of the generated name + * @param table + * @param columns + * @return String The generated name + */ + public static String generateName(String prefix, Table table, Column... columns) { + // Use a concatenation that guarantees uniqueness, even if identical names + // exist between all table and column identifiers. - public Iterator getColumnIterator() { - return columns.iterator(); + StringBuilder sb = new StringBuilder( "table`" + table.getName() + "`" ); + + // Ensure a consistent ordering of columns, regardless of the order + // they were bound. + // Clone the list, as sometimes a set of order-dependent Column + // bindings are given. + Column[] alphabeticalColumns = columns.clone(); + Arrays.sort( alphabeticalColumns, ColumnComparator.INSTANCE ); + for ( Column column : alphabeticalColumns ) { + String columnName = column == null ? "" : column.getName(); + sb.append( "column`" + columnName + "`" ); + } + return prefix + hashedName( sb.toString() ); } + /** + * Helper method for {@link #generateName(String, Table, Column...)}. + * + * @param prefix + * Appended to the beginning of the generated name + * @param table + * @param columns + * @return String The generated name + */ + public static String generateName(String prefix, Table table, List columns) { + return generateName( prefix, table, columns.toArray( new Column[columns.size()] ) ); + } + + /** + * Hash a constraint name using MD5. Convert the MD5 digest to base 35 + * (full alphanumeric), guaranteeing + * that the length of the name will always be smaller than the 30 + * character identifier restriction enforced by a few dialects. + * + * @param s + * The name to be hashed. + * @return String The hased name. + */ + public static String hashedName(String s) { + try { + MessageDigest md = MessageDigest.getInstance( "MD5" ); + md.reset(); + md.update( s.getBytes() ); + byte[] digest = md.digest(); + BigInteger bigInt = new BigInteger( 1, digest ); + // By converting to base 35 (full alphanumeric), we guarantee + // that the length of the name will always be smaller than the 30 + // character identifier restriction enforced by a few dialects. + return bigInt.toString( 35 ); + } + catch ( NoSuchAlgorithmException e ) { + throw new HibernateException( "Unable to generate a hashed Constraint name!", e ); + } + } + + private static class ColumnComparator implements Comparator { + public static ColumnComparator INSTANCE = new ColumnComparator(); + + public int compare(Column col1, Column col2) { + return col1.getName().compareTo( col2.getName() ); + } + } + public void addColumn(Column column) { if ( !columns.contains( column ) ) columns.add( column ); } @@ -79,10 +160,14 @@ } public Column getColumn(int i) { - return (Column) columns.get( i ); + return columns.get( i ); } + //todo duplicated method, remove one + public Iterator getColumnIterator() { + return columns.iterator(); + } - public Iterator columnIterator() { + public Iterator columnIterator() { return columns.iterator(); } @@ -100,8 +185,12 @@ public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) { if ( isGenerated( dialect ) ) { - return "alter table " + getTable() - .getQualifiedName( dialect, defaultCatalog, defaultSchema ) + " drop constraint " + getName(); + return new StringBuilder() + .append( "alter table " ) + .append( getTable().getQualifiedName( dialect, defaultCatalog, defaultSchema ) ) + .append( " drop constraint " ) + .append( dialect.quote( getName() ) ) + .toString(); } else { return null; @@ -110,15 +199,18 @@ public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) { if ( isGenerated( dialect ) ) { + // Certain dialects (ex: HANA) don't support FKs as expected, but other constraints can still be created. + // If that's the case, hasAlterTable() will be true, but getAddForeignKeyConstraintString will return + // empty string. Prevent blank "alter table" statements. String constraintString = sqlConstraintString( dialect, getName(), defaultCatalog, defaultSchema ); - StringBuffer buf = new StringBuffer( "alter table " ) - .append( getTable().getQualifiedName( dialect, defaultCatalog, defaultSchema ) ) - .append( constraintString ); - return buf.toString(); + if ( !StringHelper.isEmpty( constraintString ) ) { + StringBuilder buf = new StringBuilder( "alter table " ) + .append( getTable().getQualifiedName( dialect, defaultCatalog, defaultSchema ) ) + .append( constraintString ); + return buf.toString(); + } } - else { - return null; - } + return null; } public List getColumns() { @@ -131,4 +223,10 @@ public String toString() { return getClass().getName() + '(' + getTable().getName() + getColumns() + ") as " + name; } + + /** + * @return String The prefix to use in generated constraint names. Examples: + * "UK_", "FK_", and "PK_". + */ + public abstract String generatedConstraintNamePrefix(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/DenormalizedTable.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/DenormalizedTable.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/DenormalizedTable.java 17 Aug 2012 14:33:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/DenormalizedTable.java 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,17 +20,14 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; import java.util.ArrayList; -import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Map; -import org.hibernate.util.JoinedIterator; +import org.hibernate.internal.util.collections.JoinedIterator; /** * @author Gavin King @@ -44,20 +41,23 @@ includedTable.setHasDenormalizedTables(); } - public void createForeignKeys() { + @Override + public void createForeignKeys() { includedTable.createForeignKeys(); Iterator iter = includedTable.getForeignKeyIterator(); while ( iter.hasNext() ) { ForeignKey fk = (ForeignKey) iter.next(); createForeignKey( - fk.getName() + Integer.toHexString( getName().hashCode() ), + Constraint.generateName( fk.generatedConstraintNamePrefix(), this, fk.getColumns() ), fk.getColumns(), - fk.getReferencedEntityName() + fk.getReferencedEntityName(), + fk.getReferencedColumns() ); } } - public Column getColumn(Column column) { + @Override + public Column getColumn(Column column) { Column superColumn = super.getColumn( column ); if (superColumn != null) { return superColumn; @@ -67,33 +67,36 @@ } } - public Iterator getColumnIterator() { + @Override + public Iterator getColumnIterator() { return new JoinedIterator( includedTable.getColumnIterator(), super.getColumnIterator() ); } - public boolean containsColumn(Column column) { + @Override + public boolean containsColumn(Column column) { return super.containsColumn(column) || includedTable.containsColumn(column); } - public PrimaryKey getPrimaryKey() { + @Override + public PrimaryKey getPrimaryKey() { return includedTable.getPrimaryKey(); } - public Iterator getUniqueKeyIterator() { - //wierd implementation because of hacky behavior - //of Table.sqlCreateString() which modifies the - //list of unique keys by side-effect on some - //dialects - Map uks = new HashMap(); - uks.putAll( getUniqueKeys() ); - uks.putAll( includedTable.getUniqueKeys() ); - return uks.values().iterator(); + @Override + public Iterator getUniqueKeyIterator() { + Iterator iter = includedTable.getUniqueKeyIterator(); + while ( iter.hasNext() ) { + UniqueKey uk = (UniqueKey) iter.next(); + createUniqueKey( uk.getColumns() ); + } + return getUniqueKeys().values().iterator(); } - public Iterator getIndexIterator() { + @Override + public Iterator getIndexIterator() { List indexes = new ArrayList(); Iterator iter = includedTable.getIndexIterator(); while ( iter.hasNext() ) { Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/DependantValue.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/DependantValue.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/DependantValue.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/DependantValue.java 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,11 +20,10 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import org.hibernate.MappingException; +import org.hibernate.cfg.Mappings; import org.hibernate.type.Type; /** @@ -39,8 +38,8 @@ private boolean nullable; private boolean updateable; - public DependantValue(Table table, KeyValue prototype) { - super(table); + public DependantValue(Mappings mappings, Table table, KeyValue prototype) { + super( mappings, table ); this.wrappedValue = prototype; } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/mapping/FetchProfile.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Fetchable.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Fetchable.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Fetchable.java 17 Aug 2012 14:33:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Fetchable.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,10 +20,8 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import org.hibernate.FetchMode; /** Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Filterable.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Filterable.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Filterable.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Filterable.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,17 +20,17 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; + /** * Defines mapping elements to which filters may be applied. * * @author Steve Ebersole */ public interface Filterable { - public void addFilter(String name, String condition); + public void addFilter(String name, String condition, boolean autoAliasInjection, java.util.Map aliasTableMap, java.util.Map aliasEntityMap); - public java.util.Map getFilterMap(); + public java.util.List getFilters(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/ForeignKey.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/ForeignKey.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/ForeignKey.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/ForeignKey.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,10 +20,8 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -72,7 +70,7 @@ return referencedTable; } - private void appendColumns(StringBuffer buf, Iterator columns) { + private void appendColumns(StringBuilder buf, Iterator columns) { while( columns.hasNext() ) { Column column = (Column) columns.next(); buf.append( column.getName() ); @@ -90,15 +88,14 @@ * Validates that columnspan of the foreignkey and the primarykey is the same. * * Furthermore it aligns the length of the underlying tables columns. - * @param referencedTable */ public void alignColumns() { if ( isReferenceToPrimaryKey() ) alignColumns(referencedTable); } private void alignColumns(Table referencedTable) { if ( referencedTable.getPrimaryKey().getColumnSpan()!=getColumnSpan() ) { - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); sb.append("Foreign key (") .append( getName() + ":") .append( getTable().getName() ) @@ -130,10 +127,17 @@ } public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) { - return "alter table " + - getTable().getQualifiedName(dialect, defaultCatalog, defaultSchema) + - dialect.getDropForeignKeyString() + - getName(); + final StringBuilder buf = new StringBuilder( "alter table " ); + buf.append( getTable().getQualifiedName(dialect, defaultCatalog, defaultSchema) ); + buf.append( dialect.getDropForeignKeyString() ); + if ( dialect.supportsIfExistsBeforeConstraintName() ) { + buf.append( "if exists " ); + } + buf.append( dialect.quote( getName() ) ); + if ( dialect.supportsIfExistsAfterConstraintName() ) { + buf.append( " if exists" ); + } + return buf.toString(); } public boolean isCascadeDeleteEnabled() { @@ -173,7 +177,7 @@ public String toString() { if(!isReferenceToPrimaryKey() ) { - StringBuffer result = new StringBuffer(getClass().getName() + '(' + getTable().getName() + getColumns() ); + StringBuilder result = new StringBuilder(getClass().getName() + '(' + getTable().getName() + getColumns() ); result.append( " ref-columns:" + '(' + getReferencedColumns() ); result.append( ") as " + getName() ); return result.toString(); @@ -183,4 +187,8 @@ } } + + public String generatedConstraintNamePrefix() { + return "FK_"; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Formula.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Formula.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Formula.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Formula.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; @@ -35,7 +34,7 @@ * @author Gavin King */ public class Formula implements Selectable, Serializable { - private static int formulaUniqueInteger=0; + private static int formulaUniqueInteger; private String formula; private int uniqueInteger; @@ -44,31 +43,45 @@ uniqueInteger = formulaUniqueInteger++; } + @Override public String getTemplate(Dialect dialect, SQLFunctionRegistry functionRegistry) { return Template.renderWhereStringTemplate(formula, dialect, functionRegistry); } + + @Override public String getText(Dialect dialect) { return getFormula(); } + + @Override public String getText() { return getFormula(); } + + @Override public String getAlias(Dialect dialect) { return "formula" + Integer.toString(uniqueInteger) + '_'; } + + @Override public String getAlias(Dialect dialect, Table table) { return getAlias(dialect); } + public String getFormula() { return formula; } + public void setFormula(String string) { formula = string; } + + @Override public boolean isFormula() { return true; } + @Override public String toString() { return this.getClass().getName() + "( " + formula + " )"; } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/mapping/IdGenerator.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/IdentifierBag.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/IdentifierBag.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/IdentifierBag.java 17 Aug 2012 14:33:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/IdentifierBag.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,25 +20,25 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - +import org.hibernate.cfg.Mappings; import org.hibernate.type.CollectionType; -import org.hibernate.type.TypeFactory; /** * An IdentifierBag has a primary key consisting of * just the identifier column */ public class IdentifierBag extends IdentifierCollection { - public IdentifierBag(PersistentClass owner) { - super(owner); + public IdentifierBag(Mappings mappings, PersistentClass owner) { + super( mappings, owner ); } public CollectionType getDefaultCollectionType() { - return TypeFactory.idbag( getRole(), getReferencedPropertyName(), isEmbedded() ); + return getMappings().getTypeResolver() + .getTypeFactory() + .idbag( getRole(), getReferencedPropertyName() ); } public Object accept(ValueVisitor visitor) { Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/IdentifierCollection.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/IdentifierCollection.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/IdentifierCollection.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/IdentifierCollection.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,12 +20,11 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import org.hibernate.MappingException; -import org.hibernate.engine.Mapping; +import org.hibernate.cfg.Mappings; +import org.hibernate.engine.spi.Mapping; /** * A collection with a synthetic "identifier" column @@ -36,8 +35,8 @@ private KeyValue identifier; - public IdentifierCollection(PersistentClass owner) { - super(owner); + public IdentifierCollection(Mappings mappings, PersistentClass owner) { + super( mappings, owner ); } public KeyValue getIdentifier() { Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Index.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Index.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Index.java 17 Aug 2012 14:33:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Index.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,19 +20,19 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.io.Serializable; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import org.hibernate.HibernateException; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.Mapping; -import org.hibernate.util.StringHelper; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.internal.util.StringHelper; /** * A relational table index @@ -42,7 +42,8 @@ public class Index implements RelationalModel, Serializable { private Table table; - private List columns = new ArrayList(); + private List columns = new ArrayList(); + private java.util.Map columnOrderMap = new HashMap( ); private String name; public String sqlCreateString(Dialect dialect, Mapping mapping, String defaultCatalog, String defaultSchema) @@ -52,6 +53,7 @@ getName(), getTable(), getColumnIterator(), + columnOrderMap, false, defaultCatalog, defaultSchema @@ -76,13 +78,13 @@ Dialect dialect, String name, Table table, - Iterator columns, + Iterator columns, + java.util.Map columnOrderMap, boolean unique, String defaultCatalog, String defaultSchema ) { - //TODO handle supportsNotNullUnique=false, but such a case does not exist in the wild so far - StringBuffer buf = new StringBuffer( "create" ) + StringBuilder buf = new StringBuilder( "create" ) .append( unique ? " unique" : "" ) @@ -93,19 +95,34 @@ .append( " on " ) .append( table.getQualifiedName( dialect, defaultCatalog, defaultSchema ) ) .append( " (" ); - Iterator iter = columns; - while ( iter.hasNext() ) { - buf.append( ( (Column) iter.next() ).getQuotedName( dialect ) ); - if ( iter.hasNext() ) buf.append( ", " ); + while ( columns.hasNext() ) { + Column column = columns.next(); + buf.append( column.getQuotedName( dialect ) ); + if ( columnOrderMap.containsKey( column ) ) { + buf.append( " " ).append( columnOrderMap.get( column ) ); + } + if ( columns.hasNext() ) buf.append( ", " ); } buf.append( ")" ); return buf.toString(); } + public static String buildSqlCreateIndexString( + Dialect dialect, + String name, + Table table, + Iterator columns, + boolean unique, + String defaultCatalog, + String defaultSchema + ) { + return buildSqlCreateIndexString( dialect, name, table, columns, Collections.EMPTY_MAP, unique, defaultCatalog, defaultSchema ); + } + // Used only in Table for sqlCreateString (but commented out at the moment) public String sqlConstraintString(Dialect dialect) { - StringBuffer buf = new StringBuffer( " index (" ); + StringBuilder buf = new StringBuilder( " index (" ); Iterator iter = getColumnIterator(); while ( iter.hasNext() ) { buf.append( ( (Column) iter.next() ).getQuotedName( dialect ) ); @@ -134,14 +151,21 @@ return columns.size(); } - public Iterator getColumnIterator() { + public Iterator getColumnIterator() { return columns.iterator(); } public void addColumn(Column column) { if ( !columns.contains( column ) ) columns.add( column ); } + public void addColumn(Column column, String order) { + addColumn( column ); + if ( StringHelper.isNotEmpty( order ) ) { + columnOrderMap.put( column, order ); + } + } + public void addColumns(Iterator extraColumns) { while ( extraColumns.hasNext() ) addColumn( (Column) extraColumns.next() ); } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/IndexBackref.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/IndexBackref.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/IndexBackref.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/IndexBackref.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; @@ -33,28 +32,39 @@ public class IndexBackref extends Property { private String collectionRole; private String entityName; - + + @Override public boolean isBackRef() { return true; } + + @Override + public boolean isSynthetic() { + return true; + } + public String getCollectionRole() { return collectionRole; } + public void setCollectionRole(String collectionRole) { this.collectionRole = collectionRole; } + @Override public boolean isBasicPropertyAccessor() { return false; } + @Override public PropertyAccessor getPropertyAccessor(Class clazz) { return new IndexPropertyAccessor(collectionRole, entityName); } public String getEntityName() { return entityName; } + public void setEntityName(String entityName) { this.entityName = entityName; } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/IndexedCollection.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/IndexedCollection.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/IndexedCollection.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/IndexedCollection.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,14 +20,13 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.util.Iterator; import org.hibernate.MappingException; -import org.hibernate.engine.Mapping; +import org.hibernate.cfg.Mappings; +import org.hibernate.engine.spi.Mapping; /** * Indexed collections include Lists, Maps, arrays and @@ -41,8 +40,8 @@ private Value index; private String indexNodeName; - public IndexedCollection(PersistentClass owner) { - super(owner); + public IndexedCollection(Mappings mappings, PersistentClass owner) { + super( mappings, owner ); } public Value getIndex() { Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Join.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Join.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Join.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Join.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,16 +20,14 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; +import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle; import org.hibernate.sql.Alias; -import org.hibernate.engine.ExecuteUpdateResultCheckStyle; /** * @author Gavin King @@ -39,6 +37,7 @@ private static final Alias PK_ALIAS = new Alias(15, "PK"); private ArrayList properties = new ArrayList(); + private ArrayList declaredProperties = new ArrayList(); private Table table; private KeyValue key; private PersistentClass persistentClass; @@ -59,8 +58,18 @@ public void addProperty(Property prop) { properties.add(prop); + declaredProperties.add(prop); prop.setPersistentClass( getPersistentClass() ); } + public void addMappedsuperclassProperty(Property prop) { + properties.add(prop); + prop.setPersistentClass( getPersistentClass() ); + } + + public Iterator getDeclaredPropertyIterator() { + return declaredProperties.iterator(); + } + public boolean containsProperty(Property prop) { return properties.contains(prop); } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/JoinedSubclass.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/JoinedSubclass.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/JoinedSubclass.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/JoinedSubclass.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,14 +20,12 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.util.Iterator; import org.hibernate.MappingException; -import org.hibernate.engine.Mapping; +import org.hibernate.engine.spi.Mapping; /** * A subclass in a table-per-subclass mapping @@ -74,7 +72,7 @@ public Iterator getReferenceablePropertyIterator() { return getPropertyIterator(); } - + public Object accept(PersistentClassVisitor mv) { return mv.accept(this); } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/KeyValue.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/KeyValue.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/KeyValue.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/KeyValue.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,13 +20,12 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import org.hibernate.MappingException; import org.hibernate.dialect.Dialect; import org.hibernate.id.IdentifierGenerator; +import org.hibernate.id.factory.IdentifierGeneratorFactory; /** * Represents an identifying key of a table: the value for primary key @@ -35,20 +34,21 @@ * @author Gavin King */ public interface KeyValue extends Value { + + public IdentifierGenerator createIdentifierGenerator( + IdentifierGeneratorFactory identifierGeneratorFactory, + Dialect dialect, + String defaultCatalog, + String defaultSchema, + RootClass rootClass) throws MappingException; + + public boolean isIdentityColumn(IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect); public void createForeignKeyOfEntity(String entityName); public boolean isCascadeDeleteEnabled(); - public boolean isIdentityColumn(Dialect dialect); - public String getNullValue(); public boolean isUpdateable(); - - public IdentifierGenerator createIdentifierGenerator( - Dialect dialect, - String defaultCatalog, - String defaultSchema, - RootClass rootClass) throws MappingException; } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/List.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/List.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/List.java 17 Aug 2012 14:33:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/List.java 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,17 +20,15 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import org.hibernate.MappingException; +import org.hibernate.cfg.Mappings; import org.hibernate.type.CollectionType; -import org.hibernate.type.TypeFactory; /** - * A list mapping has a primary key consisting of - * the key columns + index column. + * A list mapping has a primary key consisting of the key columns + index column. + * * @author Gavin King */ public class List extends IndexedCollection { @@ -41,12 +39,14 @@ return true; } - public List(PersistentClass owner) { - super(owner); + public List(Mappings mappings, PersistentClass owner) { + super( mappings, owner ); } public CollectionType getDefaultCollectionType() throws MappingException { - return TypeFactory.list( getRole(), getReferencedPropertyName(), isEmbedded() ); + return getMappings().getTypeResolver() + .getTypeFactory() + .list( getRole(), getReferencedPropertyName() ); } public Object accept(ValueVisitor visitor) { Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/ManyToOne.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/ManyToOne.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/ManyToOne.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/ManyToOne.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,40 +20,39 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.util.ArrayList; import java.util.Iterator; import java.util.Map; import org.hibernate.MappingException; +import org.hibernate.cfg.Mappings; import org.hibernate.type.EntityType; import org.hibernate.type.Type; -import org.hibernate.type.TypeFactory; /** * A many-to-one association mapping * @author Gavin King */ public class ManyToOne extends ToOne { - private boolean ignoreNotFound; + private boolean isLogicalOneToOne; - public ManyToOne(Table table) { - super(table); + public ManyToOne(Mappings mappings, Table table) { + super( mappings, table ); } public Type getType() throws MappingException { - return TypeFactory.manyToOne( - getReferencedEntityName(), + return getMappings().getTypeResolver().getTypeFactory().manyToOne( + getReferencedEntityName(), + referenceToPrimaryKey, getReferencedPropertyName(), isLazy(), isUnwrapProxy(), - isEmbedded(), - isIgnoreNotFound() - ); + isIgnoreNotFound(), + isLogicalOneToOne + ); } public void createForeignKey() throws MappingException { @@ -110,5 +109,11 @@ this.ignoreNotFound = ignoreNotFound; } - + public void markAsLogicalOneToOne() { + this.isLogicalOneToOne = true; + } + + public boolean isLogicalOneToOne() { + return isLogicalOneToOne; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Map.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Map.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Map.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Map.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,22 +20,20 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import org.hibernate.MappingException; +import org.hibernate.cfg.Mappings; import org.hibernate.type.CollectionType; -import org.hibernate.type.TypeFactory; /** * A map has a primary key consisting of * the key columns + index columns. */ public class Map extends IndexedCollection { - public Map(PersistentClass owner) { - super(owner); + public Map(Mappings mappings, PersistentClass owner) { + super( mappings, owner ); } public boolean isMap() { @@ -44,13 +42,19 @@ public CollectionType getDefaultCollectionType() { if ( isSorted() ) { - return TypeFactory.sortedMap( getRole(), getReferencedPropertyName(), isEmbedded(), getComparator() ); + return getMappings().getTypeResolver() + .getTypeFactory() + .sortedMap( getRole(), getReferencedPropertyName(), getComparator() ); } else if ( hasOrder() ) { - return TypeFactory.orderedMap( getRole(), getReferencedPropertyName(), isEmbedded() ); + return getMappings().getTypeResolver() + .getTypeFactory() + .orderedMap( getRole(), getReferencedPropertyName() ); } else { - return TypeFactory.map( getRole(), getReferencedPropertyName(), isEmbedded() ); + return getMappings().getTypeResolver() + .getTypeFactory() + .map( getRole(), getReferencedPropertyName() ); } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/mapping/MappedSuperclass.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/MetaAttributable.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/MetaAttributable.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/MetaAttributable.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/MetaAttributable.java 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,10 +20,10 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; + /** * Common interface for things that can handle meta attributes. * Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/MetaAttribute.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/MetaAttribute.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/MetaAttribute.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/MetaAttribute.java 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,10 +20,8 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/mapping/MetadataSource.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/OneToMany.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/OneToMany.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/OneToMany.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/OneToMany.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,43 +20,45 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.util.Iterator; import org.hibernate.FetchMode; import org.hibernate.MappingException; -import org.hibernate.engine.Mapping; +import org.hibernate.cfg.Mappings; +import org.hibernate.engine.spi.Mapping; import org.hibernate.type.EntityType; import org.hibernate.type.Type; -import org.hibernate.type.TypeFactory; /** * A mapping for a one-to-many association * @author Gavin King */ public class OneToMany implements Value { + private final Mappings mappings; + private final Table referencingTable; + private String referencedEntityName; - private Table referencingTable; private PersistentClass associatedClass; private boolean embedded; private boolean ignoreNotFound; private EntityType getEntityType() { - return TypeFactory.manyToOne( - getReferencedEntityName(), + return mappings.getTypeResolver().getTypeFactory().manyToOne( + getReferencedEntityName(), + true, null, false, false, - isEmbedded(), - isIgnoreNotFound() + isIgnoreNotFound(), + false ); } - public OneToMany(PersistentClass owner) throws MappingException { + public OneToMany(Mappings mappings, PersistentClass owner) throws MappingException { + this.mappings = mappings; this.referencingTable = (owner==null) ? null : owner.getTable(); } @@ -75,7 +77,7 @@ // no foreign key element of for a one-to-many } - public Iterator getColumnIterator() { + public Iterator getColumnIterator() { return associatedClass.getKey().getColumnIterator(); } @@ -148,11 +150,21 @@ //TODO: we could just return all false... throw new UnsupportedOperationException(); } - + + /** + * @deprecated To be removed in 5. Removed as part of removing the notion of DOM entity-mode. + * See Jira issue: HHH-7771 + */ + @Deprecated public boolean isEmbedded() { return embedded; } - + + /** + * @deprecated To be removed in 5. Removed as part of removing the notion of DOM entity-mode. + * See Jira issue: HHH-7771 + */ + @Deprecated public void setEmbedded(boolean embedded) { this.embedded = embedded; } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/OneToOne.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/OneToOne.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/OneToOne.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/OneToOne.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,19 +20,16 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.util.ArrayList; import java.util.Iterator; import org.hibernate.MappingException; +import org.hibernate.cfg.Mappings; import org.hibernate.type.EntityType; import org.hibernate.type.ForeignKeyDirection; -import org.hibernate.type.SpecialOneToOneType; import org.hibernate.type.Type; -import org.hibernate.type.TypeFactory; /** * A one-to-one association mapping @@ -46,8 +43,8 @@ private String propertyName; private String entityName; - public OneToOne(Table table, PersistentClass owner) throws MappingException { - super(table); + public OneToOne(Mappings mappings, Table table, PersistentClass owner) throws MappingException { + super( mappings, table ); this.identifier = owner.getKey(); this.entityName = owner.getEntityName(); } @@ -70,27 +67,28 @@ public Type getType() throws MappingException { if ( getColumnIterator().hasNext() ) { - return new SpecialOneToOneType( + return getMappings().getTypeResolver().getTypeFactory().specialOneToOne( getReferencedEntityName(), - foreignKeyType, + foreignKeyType, + referenceToPrimaryKey, referencedPropertyName, isLazy(), isUnwrapProxy(), entityName, propertyName - ); + ); } else { - return TypeFactory.oneToOne( + return getMappings().getTypeResolver().getTypeFactory().oneToOne( getReferencedEntityName(), - foreignKeyType, + foreignKeyType, + referenceToPrimaryKey, referencedPropertyName, isLazy(), isUnwrapProxy(), - isEmbedded(), entityName, propertyName - ); + ); } } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/PersistentClass.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/PersistentClass.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/PersistentClass.java 17 Aug 2012 14:33:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/PersistentClass.java 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,25 +20,29 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.io.Serializable; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; import java.util.Set; +import java.util.StringTokenizer; -import org.hibernate.MappingException; import org.hibernate.EntityMode; +import org.hibernate.MappingException; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.ExecuteUpdateResultCheckStyle; +import org.hibernate.engine.OptimisticLockStyle; +import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.internal.FilterConfiguration; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.collections.EmptyIterator; +import org.hibernate.internal.util.collections.JoinedIterator; +import org.hibernate.internal.util.collections.SingletonIterator; import org.hibernate.sql.Alias; -import org.hibernate.util.EmptyIterator; -import org.hibernate.util.JoinedIterator; -import org.hibernate.util.ReflectHelper; -import org.hibernate.util.SingletonIterator; -import org.hibernate.util.StringHelper; /** * Mapping for an entity. @@ -55,13 +59,18 @@ private String entityName; private String className; + private transient Class mappedClass; + private String proxyInterfaceName; + private transient Class proxyInterface; private String nodeName; + private String jpaEntityName; private String discriminatorValue; private boolean lazy; private ArrayList properties = new ArrayList(); + private ArrayList declaredProperties = new ArrayList(); private final ArrayList subclasses = new ArrayList(); private final ArrayList subclassProperties = new ArrayList(); private final ArrayList subclassTables = new ArrayList(); @@ -72,7 +81,7 @@ private java.util.Map metaAttributes; private ArrayList joins = new ArrayList(); private final ArrayList subclassJoins = new ArrayList(); - private final java.util.Map filters = new HashMap(); + private final java.util.List filters = new ArrayList(); protected final java.util.Set synchronizedTables = new HashSet(); private String loaderName; private Boolean isAbstract; @@ -95,14 +104,17 @@ private java.util.Map tuplizerImpls; - protected int optimisticLockMode; + private MappedSuperclass superMappedSuperclass; + private Component declaredIdentifierMapper; + private OptimisticLockStyle optimisticLockStyle; public String getClassName() { return className; } public void setClassName(String className) { this.className = className==null ? null : className.intern(); + this.mappedClass = null; } public String getProxyInterfaceName() { @@ -111,12 +123,16 @@ public void setProxyInterfaceName(String proxyInterfaceName) { this.proxyInterfaceName = proxyInterfaceName; + this.proxyInterface = null; } public Class getMappedClass() throws MappingException { if (className==null) return null; try { - return ReflectHelper.classForName(className); + if(mappedClass == null) { + mappedClass = ReflectHelper.classForName(className); + } + return mappedClass; } catch (ClassNotFoundException cnfe) { throw new MappingException("entity class not found: " + className, cnfe); @@ -126,7 +142,10 @@ public Class getProxyInterface() { if (proxyInterfaceName==null) return null; try { - return ReflectHelper.classForName(proxyInterfaceName); + if(proxyInterface == null) { + proxyInterface = ReflectHelper.classForName( proxyInterfaceName ); + } + return proxyInterface; } catch (ClassNotFoundException cnfe) { throw new MappingException("proxy class not found: " + proxyInterfaceName, cnfe); @@ -221,6 +240,7 @@ public void addProperty(Property p) { properties.add(p); + declaredProperties.add(p); p.setPersistentClass(this); } @@ -233,12 +253,15 @@ public abstract boolean isMutable(); public abstract boolean hasIdentifierProperty(); public abstract Property getIdentifierProperty(); + public abstract Property getDeclaredIdentifierProperty(); public abstract KeyValue getIdentifier(); public abstract Property getVersion(); + public abstract Property getDeclaredVersion(); public abstract Value getDiscriminator(); public abstract boolean isInherited(); public abstract boolean isPolymorphic(); public abstract boolean isVersioned(); + public abstract String getNaturalIdCacheRegionName(); public abstract String getCacheConcurrencyStrategy(); public abstract PersistentClass getSuperclass(); public abstract boolean isExplicitPolymorphism(); @@ -423,10 +446,13 @@ } private Property getProperty(String propertyName, Iterator iterator) throws MappingException { - while ( iterator.hasNext() ) { - Property prop = (Property) iterator.next(); - if ( prop.getName().equals( StringHelper.root(propertyName) ) ) { - return prop; + if(iterator.hasNext()) { + String root = StringHelper.root(propertyName); + while ( iterator.hasNext() ) { + Property prop = (Property) iterator.next(); + if ( prop.getName().equals( root ) ) { + return prop; + } } } throw new MappingException( "property [" + propertyName + "] not found on entity [" + getEntityName() + "]" ); @@ -445,12 +471,24 @@ } } - abstract public int getOptimisticLockMode(); + @Deprecated + public int getOptimisticLockMode() { + return getOptimisticLockStyle().getOldCode(); + } + @Deprecated public void setOptimisticLockMode(int optimisticLockMode) { - this.optimisticLockMode = optimisticLockMode; + setOptimisticLockStyle( OptimisticLockStyle.interpretOldCode( optimisticLockMode ) ); } + public OptimisticLockStyle getOptimisticLockStyle() { + return optimisticLockStyle; + } + + public void setOptimisticLockStyle(OptimisticLockStyle optimisticLockStyle) { + this.optimisticLockStyle = optimisticLockStyle; + } + public void validate(Mapping mapping) throws MappingException { Iterator iter = getPropertyIterator(); while ( iter.hasNext() ) { @@ -498,7 +536,8 @@ return metaAttributes==null?null:(MetaAttribute) metaAttributes.get(name); } - public String toString() { + @Override + public String toString() { return getClass().getName() + '(' + getEntityName() + ')'; } @@ -624,11 +663,11 @@ return deleteCheckStyle; } - public void addFilter(String name, String condition) { - filters.put(name, condition); + public void addFilter(String name, String condition, boolean autoAliasInjection, java.util.Map aliasTableMap, java.util.Map aliasEntityMap) { + filters.add(new FilterConfiguration(name, condition, autoAliasInjection, aliasTableMap, aliasEntityMap, this)); } - public java.util.Map getFilterMap() { + public java.util.List getFilters() { return filters; } @@ -730,7 +769,15 @@ public void setNodeName(String nodeName) { this.nodeName = nodeName; } + + public String getJpaEntityName() { + return jpaEntityName; + } + public void setJpaEntityName(String jpaEntityName) { + this.jpaEntityName = jpaEntityName; + } + public boolean hasPojoRepresentation() { return getClassName()!=null; } @@ -748,14 +795,14 @@ } public void prepareTemporaryTables(Mapping mapping, Dialect dialect) { + temporaryIdTableName = dialect.generateTemporaryTableName( getTable().getName() ); if ( dialect.supportsTemporaryTables() ) { - temporaryIdTableName = dialect.generateTemporaryTableName( getTable().getName() ); Table table = new Table(); table.setName( temporaryIdTableName ); Iterator itr = getTable().getPrimaryKey().getColumnIterator(); while( itr.hasNext() ) { Column column = (Column) itr.next(); - table.addColumn( (Column) column.clone() ); + table.addColumn( column.clone() ); } temporaryIdTableDDL = table.sqlTemporaryTableCreateString( dialect, mapping ); } @@ -773,6 +820,14 @@ return identifierMapper; } + public Component getDeclaredIdentifierMapper() { + return declaredIdentifierMapper; + } + + public void setDeclaredIdentifierMapper(Component declaredIdentifierMapper) { + this.declaredIdentifierMapper = declaredIdentifierMapper; + } + public boolean hasIdentifierMapper() { return identifierMapper != null; } @@ -811,4 +866,31 @@ } public abstract boolean isLazyPropertiesCacheable(); -} \ No newline at end of file + + // The following methods are added to support @MappedSuperclass in the metamodel + public Iterator getDeclaredPropertyIterator() { + ArrayList iterators = new ArrayList(); + iterators.add( declaredProperties.iterator() ); + for ( int i = 0; i < joins.size(); i++ ) { + Join join = ( Join ) joins.get( i ); + iterators.add( join.getDeclaredPropertyIterator() ); + } + return new JoinedIterator( iterators ); + } + + public void addMappedsuperclassProperty(Property p) { + properties.add(p); + p.setPersistentClass(this); + } + + public MappedSuperclass getSuperMappedSuperclass() { + return superMappedSuperclass; + } + + public void setSuperMappedSuperclass(MappedSuperclass superMappedSuperclass) { + this.superMappedSuperclass = superMappedSuperclass; + } + + // End of @Mappedsuperclass support + +} Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/PersistentClassVisitor.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/PersistentClassVisitor.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/PersistentClassVisitor.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/PersistentClassVisitor.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,44 +20,28 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; + /** * @author max * */ public interface PersistentClassVisitor { - /** - * @param class1 - * @return - */ + Object accept(RootClass class1); - /** - * @param subclass - * @return - */ + Object accept(UnionSubclass subclass); - /** - * @param subclass - * @return - */ Object accept(SingleTableSubclass subclass); - /** - * @param subclass - * @return - */ + Object accept(JoinedSubclass subclass); - /** - * @param subclass - * @return - */ + Object accept(Subclass subclass); Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/PrimaryKey.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/PrimaryKey.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/PrimaryKey.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/PrimaryKey.java 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,10 +20,8 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.util.Iterator; import org.hibernate.dialect.Dialect; @@ -35,7 +33,7 @@ public class PrimaryKey extends Constraint { public String sqlConstraintString(Dialect dialect) { - StringBuffer buf = new StringBuffer("primary key ("); + StringBuilder buf = new StringBuilder("primary key ("); Iterator iter = getColumnIterator(); while ( iter.hasNext() ) { buf.append( ( (Column) iter.next() ).getQuotedName(dialect) ); @@ -45,7 +43,7 @@ } public String sqlConstraintString(Dialect dialect, String constraintName, String defaultCatalog, String defaultSchema) { - StringBuffer buf = new StringBuffer( + StringBuilder buf = new StringBuilder( dialect.getAddPrimaryKeyConstraintString(constraintName) ).append('('); Iterator iter = getColumnIterator(); @@ -55,4 +53,8 @@ } return buf.append(')').toString(); } + + public String generatedConstraintNamePrefix() { + return "PK_"; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/PrimitiveArray.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/PrimitiveArray.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/PrimitiveArray.java 17 Aug 2012 14:33:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/PrimitiveArray.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,18 +20,17 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; +import org.hibernate.cfg.Mappings; /** - * A primitive array has a primary key consisting - * of the key columns + index column. + * A primitive array has a primary key consisting of the key columns + index column. */ public class PrimitiveArray extends Array { - public PrimitiveArray(PersistentClass owner) { - super(owner); + public PrimitiveArray(Mappings mappings, PersistentClass owner) { + super( mappings, owner ); } public boolean isPrimitiveArray() { @@ -42,10 +41,3 @@ return visitor.accept(this); } } - - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Property.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Property.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Property.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Property.java 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,54 +20,66 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; import java.io.Serializable; import java.util.Iterator; import java.util.StringTokenizer; +import org.hibernate.EntityMode; import org.hibernate.MappingException; import org.hibernate.PropertyNotFoundException; -import org.hibernate.EntityMode; -import org.hibernate.engine.CascadeStyle; -import org.hibernate.engine.Mapping; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.CascadeStyles; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.property.Getter; import org.hibernate.property.PropertyAccessor; import org.hibernate.property.PropertyAccessorFactory; import org.hibernate.property.Setter; -import org.hibernate.type.AbstractComponentType; +import org.hibernate.tuple.ValueGeneration; +import org.hibernate.type.CompositeType; import org.hibernate.type.Type; -import org.hibernate.util.ArrayHelper; /** * Represents a property as part of an entity or a component. * * @author Gavin King */ public class Property implements Serializable, MetaAttributable { - private String name; private Value value; private String cascade; private boolean updateable = true; private boolean insertable = true; private boolean selectable = true; private boolean optimisticLocked = true; - private PropertyGeneration generation = PropertyGeneration.NEVER; + private ValueGeneration valueGenerationStrategy; private String propertyAccessorName; private boolean lazy; private boolean optional; private String nodeName; private java.util.Map metaAttributes; private PersistentClass persistentClass; private boolean naturalIdentifier; - + private boolean lob; + public boolean isBackRef() { return false; } + /** + * Does this property represent a synthetic property? A synthetic property is one we create during + * metamodel binding to represent a collection of columns but which does not represent a property + * physically available on the entity. + * + * @return True if synthetic; false otherwise. + */ + public boolean isSynthetic() { + return false; + } + public Type getType() throws MappingException { return value.getType(); } @@ -98,28 +110,54 @@ public CascadeStyle getCascadeStyle() throws MappingException { Type type = value.getType(); - if ( type.isComponentType() && !type.isAnyType() ) { - AbstractComponentType actype = (AbstractComponentType) type; - int length = actype.getSubtypes().length; - for ( int i=0; i columns = new ArrayList(); + private String typeName; private Properties identifierGeneratorProperties; - private String identifierGeneratorStrategy = "assigned"; + private String identifierGeneratorStrategy = DEFAULT_ID_GEN_STRATEGY; private String nullValue; private Table table; private String foreignKeyName; private boolean alternateUniqueKey; private Properties typeParameters; private boolean cascadeDeleteEnabled; + private AttributeConverterDefinition attributeConverterDefinition; + private Type type; + + public SimpleValue(Mappings mappings) { + this.mappings = mappings; + } + + public SimpleValue(Mappings mappings, Table table) { + this( mappings ); + this.table = table; + } + + public Mappings getMappings() { + return mappings; + } + public boolean isCascadeDeleteEnabled() { return cascadeDeleteEnabled; } @@ -88,7 +124,7 @@ public int getColumnSpan() { return columns.size(); } - public Iterator getColumnIterator() { + public Iterator getColumnIterator() { return columns.iterator(); } public List getConstraintColumns() { @@ -103,13 +139,7 @@ public void setTable(Table table) { this.table = table; } - - public SimpleValue(Table table) { - this.table = table; - } - public SimpleValue() {} - public void createForeignKey() throws MappingException {} public void createForeignKeyOfEntity(String entityName) { @@ -120,11 +150,11 @@ } public IdentifierGenerator createIdentifierGenerator( + IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect, String defaultCatalog, String defaultSchema, - RootClass rootClass) - throws MappingException { + RootClass rootClass) throws MappingException { Properties params = new Properties(); @@ -142,6 +172,7 @@ //pass the entity-name, if not a collection-id if (rootClass!=null) { params.setProperty( IdentifierGenerator.ENTITY_NAME, rootClass.getEntityName() ); + params.setProperty( IdentifierGenerator.JPA_ENTITY_NAME, rootClass.getJpaEntityName() ); } //init the table here instead of earlier, so that we can get a quoted table name @@ -155,7 +186,7 @@ params.setProperty( PersistentIdentifierGenerator.PK, columnName ); if (rootClass!=null) { - StringBuffer tables = new StringBuffer(); + StringBuilder tables = new StringBuilder(); Iterator iter = rootClass.getIdentityTables().iterator(); while ( iter.hasNext() ) { Table table= (Table) iter.next(); @@ -171,14 +202,16 @@ if (identifierGeneratorProperties!=null) { params.putAll(identifierGeneratorProperties); } + + // TODO : we should pass along all settings once "config lifecycle" is hashed out... + params.put( + Environment.PREFER_POOLED_VALUES_LO, + mappings.getConfigurationProperties().getProperty( Environment.PREFER_POOLED_VALUES_LO, "false" ) + ); + + identifierGeneratorFactory.setDialect( dialect ); + return identifierGeneratorFactory.createIdentifierGenerator( identifierGeneratorStrategy, getType(), params ); - return IdentifierGeneratorFactory.create( - identifierGeneratorStrategy, - getType(), - params, - dialect - ); - } public boolean isUpdateable() { @@ -210,9 +243,10 @@ return identifierGeneratorStrategy; } - public boolean isIdentityColumn(Dialect dialect) { - return IdentifierGeneratorFactory.getIdentifierGeneratorClass(identifierGeneratorStrategy, dialect) - .equals(IdentityGenerator.class); + public boolean isIdentityColumn(IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect) { + identifierGeneratorFactory.setDialect( dialect ); + return identifierGeneratorFactory.getIdentifierGeneratorClass( identifierGeneratorStrategy ) + .equals( IdentityGenerator.class ); } /** @@ -277,32 +311,145 @@ } public Type getType() throws MappingException { - if (typeName==null) { - throw new MappingException("No type name"); + if ( type != null ) { + return type; } - Type result = TypeFactory.heuristicType(typeName, typeParameters); - if (result==null) { + + if ( typeName == null ) { + throw new MappingException( "No type name" ); + } + if ( typeParameters != null + && Boolean.valueOf( typeParameters.getProperty( DynamicParameterizedType.IS_DYNAMIC ) ) + && typeParameters.get( DynamicParameterizedType.PARAMETER_TYPE ) == null ) { + createParameterImpl(); + } + + Type result = mappings.getTypeResolver().heuristicType( typeName, typeParameters ); + if ( result == null ) { String msg = "Could not determine type for: " + typeName; - if(table != null){ + if ( table != null ) { msg += ", at table: " + table.getName(); } - if(columns!=null && columns.size()>0) { + if ( columns != null && columns.size() > 0 ) { msg += ", for columns: " + columns; } - throw new MappingException(msg); + throw new MappingException( msg ); } + return result; } public void setTypeUsingReflection(String className, String propertyName) throws MappingException { - if (typeName==null) { - if (className==null) { - throw new MappingException("you must specify types for a dynamic entity: " + propertyName); + // NOTE : this is called as the last piece in setting SimpleValue type information, and implementations + // rely on that fact, using it as a signal that all information it is going to get is defined at this point... + + if ( typeName != null ) { + // assume either (a) explicit type was specified or (b) determine was already performed + return; + } + + if ( type != null ) { + return; + } + + if ( attributeConverterDefinition == null ) { + // this is here to work like legacy. This should change when we integrate with metamodel to + // look for SqlTypeDescriptor and JavaTypeDescriptor individually and create the BasicType (well, really + // keep a registry of [SqlTypeDescriptor,JavaTypeDescriptor] -> BasicType...) + if ( className == null ) { + throw new MappingException( "you must specify types for a dynamic entity: " + propertyName ); } - typeName = ReflectHelper.reflectedPropertyClass(className, propertyName).getName(); + typeName = ReflectHelper.reflectedPropertyClass( className, propertyName ).getName(); + return; } + + // we had an AttributeConverter... + type = buildAttributeConverterTypeAdapter(); } + /** + * Build a Hibernate Type that incorporates the JPA AttributeConverter. AttributeConverter works totally in + * memory, meaning it converts between one Java representation (the entity attribute representation) and another + * (the value bound into JDBC statements or extracted from results). However, the Hibernate Type system operates + * at the lower level of actually dealing directly with those JDBC objects. So even though we have an + * AttributeConverter, we still need to "fill out" the rest of the BasicType data and bridge calls + * to bind/extract through the converter. + *

        + * Essentially the idea here is that an intermediate Java type needs to be used. Let's use an example as a means + * to illustrate... Consider an {@code AttributeConverter}. This tells Hibernate that the domain + * model defines this attribute as an Integer value (the 'entityAttributeJavaType'), but that we need to treat the + * value as a String (the 'databaseColumnJavaType') when dealing with JDBC (aka, the database type is a + * VARCHAR/CHAR):

          + *
        • + * When binding values to PreparedStatements we need to convert the Integer value from the entity + * into a String and pass that String to setString. The conversion is handled by calling + * {@link AttributeConverter#convertToDatabaseColumn(Object)} + *
        • + *
        • + * When extracting values from ResultSets (or CallableStatement parameters) we need to handle the + * value via getString, and convert that returned String to an Integer. That conversion is handled + * by calling {@link AttributeConverter#convertToEntityAttribute(Object)} + *
        • + *
        + * + * @return The built AttributeConverter -> Type adapter + * + * @todo : ultimately I want to see attributeConverterJavaType and attributeConverterJdbcTypeCode specify-able separately + * then we can "play them against each other" in terms of determining proper typing + * + * @todo : see if we already have previously built a custom on-the-fly BasicType for this AttributeConverter; see note below about caching + */ + @SuppressWarnings("unchecked") + private Type buildAttributeConverterTypeAdapter() { + // todo : validate the number of columns present here? + + final Class entityAttributeJavaType = attributeConverterDefinition.getEntityAttributeType(); + final Class databaseColumnJavaType = attributeConverterDefinition.getDatabaseColumnType(); + + + // resolve the JavaTypeDescriptor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // For the JavaTypeDescriptor portion we simply resolve the "entity attribute representation" part of + // the AttributeConverter to resolve the corresponding descriptor. + final JavaTypeDescriptor entityAttributeJavaTypeDescriptor = JavaTypeDescriptorRegistry.INSTANCE.getDescriptor( entityAttributeJavaType ); + + + // build the SqlTypeDescriptor adapter ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Going back to the illustration, this should be a SqlTypeDescriptor that handles the Integer <-> String + // conversions. This is the more complicated piece. First we need to determine the JDBC type code + // corresponding to the AttributeConverter's declared "databaseColumnJavaType" (how we read that value out + // of ResultSets). See JdbcTypeJavaClassMappings for details. Again, given example, this should return + // VARCHAR/CHAR + final int jdbcTypeCode = JdbcTypeJavaClassMappings.INSTANCE.determineJdbcTypeCodeForJavaClass( databaseColumnJavaType ); + // find the standard SqlTypeDescriptor for that JDBC type code. + final SqlTypeDescriptor sqlTypeDescriptor = SqlTypeDescriptorRegistry.INSTANCE.getDescriptor( jdbcTypeCode ); + // find the JavaTypeDescriptor representing the "intermediate database type representation". Back to the + // illustration, this should be the type descriptor for Strings + final JavaTypeDescriptor intermediateJavaTypeDescriptor = JavaTypeDescriptorRegistry.INSTANCE.getDescriptor( databaseColumnJavaType ); + // and finally construct the adapter, which injects the AttributeConverter calls into the binding/extraction + // process... + final SqlTypeDescriptor sqlTypeDescriptorAdapter = new AttributeConverterSqlTypeDescriptorAdapter( + attributeConverterDefinition.getAttributeConverter(), + sqlTypeDescriptor, + intermediateJavaTypeDescriptor + ); + + // todo : cache the AttributeConverterTypeAdapter in case that AttributeConverter is applied multiple times. + + final String name = String.format( + "BasicType adapter for AttributeConverter<%s,%s>", + entityAttributeJavaType.getSimpleName(), + databaseColumnJavaType.getSimpleName() + ); + return new AttributeConverterTypeAdapter( + name, + attributeConverterDefinition.getAttributeConverter(), + sqlTypeDescriptorAdapter, + entityAttributeJavaType, + databaseColumnJavaType, + entityAttributeJavaTypeDescriptor + ); + } + public boolean isTypeSpecified() { return typeName!=null; } @@ -315,7 +462,8 @@ return typeParameters; } - public String toString() { + @Override + public String toString() { return getClass().getName() + '(' + columns.toString() + ')'; } @@ -337,4 +485,98 @@ public boolean[] getColumnUpdateability() { return getColumnInsertability(); } + + public void setJpaAttributeConverterDefinition(AttributeConverterDefinition attributeConverterDefinition) { + this.attributeConverterDefinition = attributeConverterDefinition; + } + + private void createParameterImpl() { + try { + String[] columnsNames = new String[columns.size()]; + for ( int i = 0; i < columns.size(); i++ ) { + columnsNames[i] = ( (Column) columns.get( i ) ).getName(); + } + + final XProperty xProperty = (XProperty) typeParameters.get( DynamicParameterizedType.XPROPERTY ); + // todo : not sure this works for handling @MapKeyEnumerated + final Annotation[] annotations = xProperty == null + ? null + : xProperty.getAnnotations(); + + typeParameters.put( + DynamicParameterizedType.PARAMETER_TYPE, + new ParameterTypeImpl( + ReflectHelper.classForName( + typeParameters.getProperty( DynamicParameterizedType.RETURNED_CLASS ) + ), + annotations, + table.getCatalog(), + table.getSchema(), + table.getName(), + Boolean.valueOf( typeParameters.getProperty( DynamicParameterizedType.IS_PRIMARY_KEY ) ), + columnsNames + ) + ); + } + catch ( ClassNotFoundException cnfe ) { + throw new MappingException( "Could not create DynamicParameterizedType for type: " + typeName, cnfe ); + } + } + + private final class ParameterTypeImpl implements DynamicParameterizedType.ParameterType { + + private final Class returnedClass; + private final Annotation[] annotationsMethod; + private final String catalog; + private final String schema; + private final String table; + private final boolean primaryKey; + private final String[] columns; + + private ParameterTypeImpl(Class returnedClass, Annotation[] annotationsMethod, String catalog, String schema, + String table, boolean primaryKey, String[] columns) { + this.returnedClass = returnedClass; + this.annotationsMethod = annotationsMethod; + this.catalog = catalog; + this.schema = schema; + this.table = table; + this.primaryKey = primaryKey; + this.columns = columns; + } + + @Override + public Class getReturnedClass() { + return returnedClass; + } + + @Override + public Annotation[] getAnnotationsMethod() { + return annotationsMethod; + } + + @Override + public String getCatalog() { + return catalog; + } + + @Override + public String getSchema() { + return schema; + } + + @Override + public String getTable() { + return table; + } + + @Override + public boolean isPrimaryKey() { + return primaryKey; + } + + @Override + public String[] getColumns() { + return columns; + } + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/SingleTableSubclass.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/SingleTableSubclass.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/SingleTableSubclass.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/SingleTableSubclass.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,15 +20,13 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.util.Iterator; import org.hibernate.MappingException; -import org.hibernate.engine.Mapping; -import org.hibernate.util.JoinedIterator; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.internal.util.collections.JoinedIterator; /** * @author Gavin King @@ -40,7 +38,7 @@ } protected Iterator getNonDuplicatedPropertyIterator() { - return new JoinedIterator( + return new JoinedIterator( getSuperclass().getUnjoinedPropertyIterator(), getUnjoinedPropertyIterator() ); Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Subclass.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Subclass.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Subclass.java 17 Aug 2012 14:33:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Subclass.java 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,17 +20,19 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; import java.util.Map; import org.hibernate.AssertionFailure; import org.hibernate.EntityMode; -import org.hibernate.util.JoinedIterator; -import org.hibernate.util.SingletonIterator; +import org.hibernate.engine.OptimisticLockStyle; +import org.hibernate.internal.util.collections.JoinedIterator; +import org.hibernate.internal.util.collections.SingletonIterator; /** * A sublass in a table-per-class-hierarchy mapping @@ -55,6 +57,11 @@ return subclassId; } + @Override + public String getNaturalIdCacheRegionName() { + return getSuperclass().getNaturalIdCacheRegionName(); + } + public String getCacheConcurrencyStrategy() { return getSuperclass().getCacheConcurrencyStrategy(); } @@ -70,6 +77,11 @@ public Property getIdentifierProperty() { return getSuperclass().getIdentifierProperty(); } + + public Property getDeclaredIdentifierProperty() { + return null; + } + public KeyValue getIdentifier() { return getSuperclass().getIdentifier(); } @@ -93,6 +105,12 @@ super.addProperty(p); getSuperclass().addSubclassProperty(p); } + + public void addMappedsuperclassProperty(Property p) { + super.addMappedsuperclassProperty( p ); + getSuperclass().addSubclassProperty(p); + } + public void addJoin(Join j) { super.addJoin(j); getSuperclass().addSubclassJoin(j); @@ -137,6 +155,10 @@ return getSuperclass().getVersion(); } + public Property getDeclaredVersion() { + return null; + } + public boolean hasEmbeddedIdentifier() { return getSuperclass().hasEmbeddedIdentifier(); } @@ -234,8 +256,10 @@ return mv.accept(this); } - public Map getFilterMap() { - return getSuperclass().getFilterMap(); + public java.util.List getFilters() { + java.util.List filters = new ArrayList(super.getFilters()); + filters.addAll(getSuperclass().getFilters()); + return filters; } public boolean hasSubselectLoadableCollections() { @@ -272,9 +296,9 @@ public Component getIdentifierMapper() { return superclass.getIdentifierMapper(); } - - public int getOptimisticLockMode() { - return superclass.getOptimisticLockMode(); - } + @Override + public OptimisticLockStyle getOptimisticLockStyle() { + return superclass.getOptimisticLockStyle(); + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/mapping/SyntheticProperty.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Table.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Table.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Table.java 17 Aug 2012 14:33:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Table.java 30 Jul 2014 16:16:00 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,25 +20,23 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; import java.io.Serializable; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Collections; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.LinkedHashMap; import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.Mapping; +import org.hibernate.engine.spi.Mapping; import org.hibernate.tool.hbm2ddl.ColumnMetadata; import org.hibernate.tool.hbm2ddl.TableMetadata; -import org.hibernate.util.CollectionHelper; /** * A relational table @@ -56,20 +54,20 @@ private Map columns = new LinkedHashMap(); private KeyValue idValue; private PrimaryKey primaryKey; - private Map indexes = new HashMap(); - private Map foreignKeys = new HashMap(); - private Map uniqueKeys = new HashMap(); - private final int uniqueInteger; + private Map indexes = new LinkedHashMap(); + private Map foreignKeys = new LinkedHashMap(); + private Map uniqueKeys = new LinkedHashMap(); + private int uniqueInteger; private boolean quoted; private boolean schemaQuoted; - private static int tableCounter = 0; + private boolean catalogQuoted; private List checkConstraints = new ArrayList(); private String rowId; private String subselect; private boolean isAbstract; - private boolean hasDenormalizedTables = false; + private boolean hasDenormalizedTables; private String comment; - + static class ForeignKeyKey implements Serializable { String referencedClassName; List columns; @@ -84,7 +82,7 @@ this.referencedColumns.addAll( referencedColumns ); } else { - this.referencedColumns = CollectionHelper.EMPTY_LIST; + this.referencedColumns = Collections.EMPTY_LIST; } } @@ -100,9 +98,7 @@ } } - public Table() { - uniqueInteger = tableCounter++; - } + public Table() { } public Table(String name) { this(); @@ -119,12 +115,12 @@ getQuotedSchema( dialect ); String usedCatalog = catalog == null ? defaultCatalog : - catalog; + getQuotedCatalog( dialect ); return qualify( usedCatalog, usedSchema, quotedName ); } public static String qualify(String catalog, String schema, String table) { - StringBuffer qualifiedName = new StringBuffer(); + StringBuilder qualifiedName = new StringBuilder(); if ( catalog != null ) { qualifiedName.append( catalog ).append( '.' ); } @@ -168,6 +164,18 @@ schema; } + public String getQuotedCatalog() { + return catalogQuoted ? + "`" + catalog + "`" : + catalog; + } + + public String getQuotedCatalog(Dialect dialect) { + return catalogQuoted ? + dialect.openQuote() + catalog + dialect.closeQuote() : + catalog; + } + public void setName(String name) { if ( name.charAt( 0 ) == '`' ) { quoted = true; @@ -205,7 +213,7 @@ } public void addColumn(Column column) { - Column old = (Column) getColumn( column ); + Column old = getColumn( column ); if ( old == null ) { columns.put( column.getCanonicalName(), column ); column.uniqueInteger = columns.size(); @@ -223,49 +231,129 @@ return columns.values().iterator(); } - public Iterator getIndexIterator() { + public Iterator getIndexIterator() { return indexes.values().iterator(); } public Iterator getForeignKeyIterator() { return foreignKeys.values().iterator(); } - public Iterator getUniqueKeyIterator() { + public Iterator getUniqueKeyIterator() { return getUniqueKeys().values().iterator(); } - Map getUniqueKeys() { - if ( uniqueKeys.size() > 1 ) { - //deduplicate unique constraints sharing the same columns - //this is needed by Hibernate Annotations since it creates automagically - // unique constraints for the user - Iterator it = uniqueKeys.entrySet().iterator(); - Map finalUniqueKeys = new HashMap( uniqueKeys.size() ); - while ( it.hasNext() ) { - Map.Entry entry = (Map.Entry) it.next(); - UniqueKey uk = (UniqueKey) entry.getValue(); - List columns = uk.getColumns(); - int size = finalUniqueKeys.size(); - boolean skip = false; - Iterator tempUks = finalUniqueKeys.entrySet().iterator(); - while ( tempUks.hasNext() ) { - final UniqueKey currentUk = (UniqueKey) ( (Map.Entry) tempUks.next() ).getValue(); - if ( currentUk.getColumns().containsAll( columns ) && columns - .containsAll( currentUk.getColumns() ) ) { - skip = true; + Map getUniqueKeys() { + cleanseUniqueKeyMapIfNeeded(); + return uniqueKeys; + } + + private int sizeOfUniqueKeyMapOnLastCleanse; + + private void cleanseUniqueKeyMapIfNeeded() { + if ( uniqueKeys.size() == sizeOfUniqueKeyMapOnLastCleanse ) { + // nothing to do + return; + } + cleanseUniqueKeyMap(); + sizeOfUniqueKeyMapOnLastCleanse = uniqueKeys.size(); + } + + private void cleanseUniqueKeyMap() { + // We need to account for a few conditions here... + // 1) If there are multiple unique keys contained in the uniqueKeys Map, we need to deduplicate + // any sharing the same columns as other defined unique keys; this is needed for the annotation + // processor since it creates unique constraints automagically for the user + // 2) Remove any unique keys that share the same columns as the primary key; again, this is + // needed for the annotation processor to handle @Id @OneToOne cases. In such cases the + // unique key is unnecessary because a primary key is already unique by definition. We handle + // this case specifically because some databases fail if you try to apply a unique key to + // the primary key columns which causes schema export to fail in these cases. + if ( uniqueKeys.isEmpty() ) { + // nothing to do + return; + } + else if ( uniqueKeys.size() == 1 ) { + // we have to worry about condition 2 above, but not condition 1 + final Map.Entry uniqueKeyEntry = uniqueKeys.entrySet().iterator().next(); + if ( isSameAsPrimaryKeyColumns( uniqueKeyEntry.getValue() ) ) { + uniqueKeys.remove( uniqueKeyEntry.getKey() ); + } + } + else { + // we have to check both conditions 1 and 2 + final Iterator> uniqueKeyEntries = uniqueKeys.entrySet().iterator(); + while ( uniqueKeyEntries.hasNext() ) { + final Map.Entry uniqueKeyEntry = uniqueKeyEntries.next(); + final UniqueKey uniqueKey = uniqueKeyEntry.getValue(); + boolean removeIt = false; + + // condition 1 : check against other unique keys + for ( UniqueKey otherUniqueKey : uniqueKeys.values() ) { + // make sure its not the same unique key + if ( uniqueKeyEntry.getValue() == otherUniqueKey ) { + continue; + } + if ( otherUniqueKey.getColumns().containsAll( uniqueKey.getColumns() ) + && uniqueKey.getColumns().containsAll( otherUniqueKey.getColumns() ) ) { + removeIt = true; break; } } - if ( !skip ) finalUniqueKeys.put( entry.getKey(), uk ); + + // condition 2 : check against pk + if ( isSameAsPrimaryKeyColumns( uniqueKeyEntry.getValue() ) ) { + removeIt = true; + } + + if ( removeIt ) { + //uniqueKeys.remove( uniqueKeyEntry.getKey() ); + uniqueKeyEntries.remove(); + } } - return finalUniqueKeys; + } - else { - return uniqueKeys; + } + + private boolean isSameAsPrimaryKeyColumns(UniqueKey uniqueKey) { + if ( primaryKey == null || ! primaryKey.columnIterator().hasNext() ) { + // happens for many-to-many tables + return false; } + return primaryKey.getColumns().containsAll( uniqueKey.getColumns() ) + && uniqueKey.getColumns().containsAll( primaryKey.getColumns() ); } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((catalog == null) ? 0 : isCatalogQuoted() ? catalog.hashCode() : catalog.toLowerCase().hashCode()); + result = prime * result + ((name == null) ? 0 : isQuoted() ? name.hashCode() : name.toLowerCase().hashCode()); + result = prime * result + + ((schema == null) ? 0 : isSchemaQuoted() ? schema.hashCode() : schema.toLowerCase().hashCode()); + return result; + } + + @Override + public boolean equals(Object object) { + return object instanceof Table && equals((Table) object); + } + + public boolean equals(Table table) { + if (null == table) { + return false; + } + if (this == table) { + return true; + } + + return isQuoted() ? name.equals(table.getName()) : name.equalsIgnoreCase(table.getName()) + && ((schema == null && table.getSchema() != null) ? false : (schema == null) ? true : isSchemaQuoted() ? schema.equals(table.getSchema()) : schema.equalsIgnoreCase(table.getSchema())) + && ((catalog == null && table.getCatalog() != null) ? false : (catalog == null) ? true : isCatalogQuoted() ? catalog.equals(table.getCatalog()) : catalog.equalsIgnoreCase(table.getCatalog())); + } + public void validateColumns(Dialect dialect, Mapping mapping, TableMetadata tableInfo) { Iterator iter = getColumnIterator(); while ( iter.hasNext() ) { @@ -298,21 +386,22 @@ String defaultSchema) throws HibernateException { - StringBuffer root = new StringBuffer( "alter table " ) + StringBuilder root = new StringBuilder( "alter table " ) .append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) ) .append( ' ' ) .append( dialect.getAddColumnString() ); Iterator iter = getColumnIterator(); List results = new ArrayList(); + while ( iter.hasNext() ) { Column column = (Column) iter.next(); ColumnMetadata columnInfo = tableInfo.getColumnMetadata( column.getName() ); if ( columnInfo == null ) { // the column doesnt exist at all. - StringBuffer alter = new StringBuffer( root.toString() ) + StringBuilder alter = new StringBuilder( root.toString() ) .append( ' ' ) .append( column.getQuotedName( dialect ) ) .append( ' ' ) @@ -321,21 +410,21 @@ String defaultValue = column.getDefaultValue(); if ( defaultValue != null ) { alter.append( " default " ).append( defaultValue ); + } - if ( column.isNullable() ) { - alter.append( dialect.getNullColumnString() ); - } - else { - alter.append( " not null" ); - } - + if ( column.isNullable() ) { + alter.append( dialect.getNullColumnString() ); } + else { + alter.append( " not null" ); + } - boolean useUniqueConstraint = column.isUnique() && - dialect.supportsUnique() && - ( !column.isNullable() || dialect.supportsNotNullUnique() ); - if ( useUniqueConstraint ) { - alter.append( " unique" ); + if ( column.isUnique() ) { + String keyName = Constraint.generateName( "UK_", this, column ); + UniqueKey uk = getOrCreateUniqueKey( keyName ); + uk.addColumn( column ); + alter.append( dialect.getUniqueDelegate() + .getColumnDefinitionUniquenessFragment( column ) ); } if ( column.hasCheckConstraint() && dialect.supportsColumnCheck() ) { @@ -349,6 +438,8 @@ alter.append( dialect.getColumnComment( columnComment ) ); } + alter.append( dialect.getAddColumnSuffixString() ); + results.add( alter.toString() ); } @@ -362,7 +453,7 @@ } public String sqlTemporaryTableCreateString(Dialect dialect, Mapping mapping) throws HibernateException { - StringBuffer buffer = new StringBuffer( dialect.getCreateTemporaryTableString() ) + StringBuilder buffer = new StringBuilder( dialect.getCreateTemporaryTableString() ) .append( ' ' ) .append( name ) .append( " (" ); @@ -387,12 +478,12 @@ } public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) { - StringBuffer buf = new StringBuffer( hasPrimaryKey() ? dialect.getCreateTableString() : dialect.getCreateMultisetTableString() ) + StringBuilder buf = new StringBuilder( hasPrimaryKey() ? dialect.getCreateTableString() : dialect.getCreateMultisetTableString() ) .append( ' ' ) .append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) ) .append( " (" ); - boolean identityColumn = idValue != null && idValue.isIdentityColumn( dialect ); + boolean identityColumn = idValue != null && idValue.isIdentityColumn( p.getIdentifierGeneratorFactory(), dialect ); // Try to find out the name of the primary key to create it as identity if the IdentityGenerator is used String pkname = null; @@ -432,19 +523,15 @@ } } - - boolean useUniqueConstraint = col.isUnique() && - ( !col.isNullable() || dialect.supportsNotNullUnique() ); - if ( useUniqueConstraint ) { - if ( dialect.supportsUnique() ) { - buf.append( " unique" ); - } - else { - UniqueKey uk = getOrCreateUniqueKey( col.getQuotedName( dialect ) + '_' ); - uk.addColumn( col ); - } + + if ( col.isUnique() ) { + String keyName = Constraint.generateName( "UK_", this, col ); + UniqueKey uk = getOrCreateUniqueKey( keyName ); + uk.addColumn( col ); + buf.append( dialect.getUniqueDelegate() + .getColumnDefinitionUniquenessFragment( col ) ); } - + if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) { buf.append( " check (" ) .append( col.getCheckConstraint() ) @@ -466,21 +553,7 @@ .append( getPrimaryKey().sqlConstraintString( dialect ) ); } - if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) { - Iterator ukiter = getUniqueKeyIterator(); - while ( ukiter.hasNext() ) { - UniqueKey uk = (UniqueKey) ukiter.next(); - String constraint = uk.sqlConstraintString( dialect ); - if ( constraint != null ) { - buf.append( ", " ).append( constraint ); - } - } - } - /*Iterator idxiter = getIndexIterator(); - while ( idxiter.hasNext() ) { - Index idx = (Index) idxiter.next(); - buf.append(',').append( idx.sqlConstraintString(dialect) ); - }*/ + buf.append( dialect.getUniqueDelegate().getTableCreationUniqueConstraintsFragment( this ) ); if ( dialect.supportsTableCheck() ) { Iterator chiter = checkConstraints.iterator(); @@ -501,16 +574,7 @@ } public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) { - StringBuffer buf = new StringBuffer( "drop table " ); - if ( dialect.supportsIfExistsBeforeTableName() ) { - buf.append( "if exists " ); - } - buf.append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) ) - .append( dialect.getCascadeConstraintsString() ); - if ( dialect.supportsIfExistsAfterTableName() ) { - buf.append( " if exists" ); - } - return buf.toString(); + return dialect.getDropTableString( getQualifiedName( dialect, defaultCatalog, defaultSchema ) ); } public PrimaryKey getPrimaryKey() { @@ -523,7 +587,7 @@ public Index getOrCreateIndex(String indexName) { - Index index = (Index) indexes.get( indexName ); + Index index = indexes.get( indexName ); if ( index == null ) { index = new Index(); @@ -536,11 +600,11 @@ } public Index getIndex(String indexName) { - return (Index) indexes.get( indexName ); + return indexes.get( indexName ); } public Index addIndex(Index index) { - Index current = (Index) indexes.get( index.getName() ); + Index current = indexes.get( index.getName() ); if ( current != null ) { throw new MappingException( "Index " + index.getName() + " already exists!" ); } @@ -549,7 +613,7 @@ } public UniqueKey addUniqueKey(UniqueKey uniqueKey) { - UniqueKey current = (UniqueKey) uniqueKeys.get( uniqueKey.getName() ); + UniqueKey current = uniqueKeys.get( uniqueKey.getName() ); if ( current != null ) { throw new MappingException( "UniqueKey " + uniqueKey.getName() + " already exists!" ); } @@ -558,18 +622,18 @@ } public UniqueKey createUniqueKey(List keyColumns) { - String keyName = "UK" + uniqueColumnString( keyColumns.iterator() ); + String keyName = Constraint.generateName( "UK_", this, keyColumns ); UniqueKey uk = getOrCreateUniqueKey( keyName ); uk.addColumns( keyColumns.iterator() ); return uk; } public UniqueKey getUniqueKey(String keyName) { - return (UniqueKey) uniqueKeys.get( keyName ); + return uniqueKeys.get( keyName ); } public UniqueKey getOrCreateUniqueKey(String keyName) { - UniqueKey uk = (UniqueKey) uniqueKeys.get( keyName ); + UniqueKey uk = uniqueKeys.get( keyName ); if ( uk == null ) { uk = new UniqueKey(); @@ -594,21 +658,22 @@ ForeignKey fk = (ForeignKey) foreignKeys.get( key ); if ( fk == null ) { fk = new ForeignKey(); - if ( keyName != null ) { - fk.setName( keyName ); - } - else { - fk.setName( "FK" + uniqueColumnString( keyColumns.iterator(), referencedEntityName ) ); - //TODO: add referencedClass to disambiguate to FKs on the same - // columns, pointing to different tables - } fk.setTable( this ); - foreignKeys.put( key, fk ); fk.setReferencedEntityName( referencedEntityName ); fk.addColumns( keyColumns.iterator() ); if ( referencedColumns != null ) { fk.addReferencedColumns( referencedColumns.iterator() ); } + + if ( keyName != null ) { + fk.setName( keyName ); + } + else { + fk.setName( Constraint.generateName( fk.generatedConstraintNamePrefix(), + this, keyColumns ) ); + } + + foreignKeys.put( key, fk ); } if ( keyName != null ) { @@ -619,22 +684,7 @@ } - public String uniqueColumnString(Iterator iterator) { - return uniqueColumnString( iterator, null ); - } - public String uniqueColumnString(Iterator iterator, String referencedEntityName) { - int result = 0; - if ( referencedEntityName != null ) { - result += referencedEntityName.hashCode(); - } - while ( iterator.hasNext() ) { - result += iterator.next().hashCode(); - } - return ( Integer.toHexString( name.hashCode() ) + Integer.toHexString( result ) ).toUpperCase(); - } - - public String getSchema() { return schema; } @@ -654,9 +704,21 @@ } public void setCatalog(String catalog) { - this.catalog = catalog; + if ( catalog != null && catalog.charAt( 0 ) == '`' ) { + catalogQuoted = true; + this.catalog = catalog.substring( 1, catalog.length() - 1 ); + } + else { + this.catalog = catalog; + } } + // This must be done outside of Table, rather than statically, to ensure + // deterministic alias names. See HHH-2448. + public void setUniqueInteger( int uniqueInteger ) { + this.uniqueInteger = uniqueInteger; + } + public int getUniqueInteger() { return uniqueInteger; } @@ -672,6 +734,9 @@ public boolean isSchemaQuoted() { return schemaQuoted; } + public boolean isCatalogQuoted() { + return catalogQuoted; + } public boolean isQuoted() { return quoted; @@ -698,7 +763,7 @@ } public String toString() { - StringBuffer buf = new StringBuffer().append( getClass().getName() ) + StringBuilder buf = new StringBuilder().append( getClass().getName() ) .append( '(' ); if ( getCatalog() != null ) { buf.append( getCatalog() + "." ); @@ -763,7 +828,7 @@ if ( dialect.supportsCommentOn() ) { String tableName = getQualifiedName( dialect, defaultCatalog, defaultSchema ); if ( comment != null ) { - StringBuffer buf = new StringBuffer() + StringBuilder buf = new StringBuilder() .append( "comment on table " ) .append( tableName ) .append( " is '" ) @@ -776,7 +841,7 @@ Column column = (Column) iter.next(); String columnComment = column.getComment(); if ( columnComment != null ) { - StringBuffer buf = new StringBuffer() + StringBuilder buf = new StringBuilder() .append( "comment on column " ) .append( tableName ) .append( '.' ) Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/TableOwner.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/TableOwner.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/TableOwner.java 17 Aug 2012 14:33:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/TableOwner.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,10 +20,10 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; + /** * Interface allowing to differenciate SubClasses * from Classes, JoinedSubClasses and UnionSubClasses Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/ToOne.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/ToOne.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/ToOne.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/ToOne.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,15 +20,14 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import org.hibernate.FetchMode; import org.hibernate.MappingException; -import org.hibernate.engine.Mapping; +import org.hibernate.cfg.Mappings; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.internal.util.ReflectHelper; import org.hibernate.type.Type; -import org.hibernate.util.ReflectHelper; /** * A simple-point association (ie. a reference to another entity). @@ -42,9 +41,10 @@ private boolean embedded; private boolean lazy = true; protected boolean unwrapProxy; + protected boolean referenceToPrimaryKey = true; - protected ToOne(Table table) { - super(table); + protected ToOne(Mappings mappings, Table table) { + super( mappings, table ); } public FetchMode getFetchMode() { @@ -78,7 +78,7 @@ public void setTypeUsingReflection(String className, String propertyName) throws MappingException { if (referencedEntityName==null) { - referencedEntityName = ReflectHelper.reflectedPropertyClass(className, propertyName).getName(); + referencedEntityName = ReflectHelper.reflectedPropertyClass( className, propertyName ).getName(); } } @@ -89,11 +89,21 @@ public Object accept(ValueVisitor visitor) { return visitor.accept(this); } - + + /** + * @deprecated To be removed in 5. Removed as part of removing the notion of DOM entity-mode. + * See Jira issue: HHH-7771 + */ + @Deprecated public boolean isEmbedded() { return embedded; } - + + /** + * @deprecated To be removed in 5. Removed as part of removing the notion of DOM entity-mode. + * See Jira issue: HHH-7771 + */ + @Deprecated public void setEmbedded(boolean embedded) { this.embedded = embedded; } @@ -120,12 +130,13 @@ public void setUnwrapProxy(boolean unwrapProxy) { this.unwrapProxy = unwrapProxy; } - -} + public boolean isReferenceToPrimaryKey() { + return referenceToPrimaryKey; + } - - - - - + public void setReferenceToPrimaryKey(boolean referenceToPrimaryKey) { + this.referenceToPrimaryKey = referenceToPrimaryKey; + } + +} Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/TypeDef.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/TypeDef.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/TypeDef.java 17 Aug 2012 14:33:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/TypeDef.java 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,10 +20,8 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.io.Serializable; import java.util.Properties; Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/UnionSubclass.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/UnionSubclass.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/UnionSubclass.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/UnionSubclass.java 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,14 +20,12 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.util.Iterator; import org.hibernate.MappingException; -import org.hibernate.engine.Mapping; +import org.hibernate.engine.spi.Mapping; /** * A subclass in a table-per-concrete-class mapping Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/UniqueKey.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/UniqueKey.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/UniqueKey.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/UniqueKey.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,86 +20,63 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; -import java.util.Iterator; +import java.util.HashMap; +import java.util.Map; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.Mapping; -import org.hibernate.util.StringHelper; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.internal.util.StringHelper; /** * A relational unique key constraint * - * @author Gavin King + * @author Brett Meyer */ public class UniqueKey extends Constraint { + private java.util.Map columnOrderMap = new HashMap( ); - public String sqlConstraintString(Dialect dialect) { - StringBuffer buf = new StringBuffer( "unique (" ); - Iterator iter = getColumnIterator(); - boolean nullable = false; - while ( iter.hasNext() ) { - Column column = (Column) iter.next(); - if ( !nullable && column.isNullable() ) nullable = true; - buf.append( column.getQuotedName( dialect ) ); - if ( iter.hasNext() ) buf.append( ", " ); - } - //do not add unique constraint on DB not supporting unique and nullable columns - return !nullable || dialect.supportsNotNullUnique() ? - buf.append( ')' ).toString() : - null; + @Override + public String sqlConstraintString( + Dialect dialect, + String constraintName, + String defaultCatalog, + String defaultSchema) { +// return dialect.getUniqueDelegate().uniqueConstraintSql( this ); + // Not used. + return ""; } - public String sqlConstraintString(Dialect dialect, String constraintName, String defaultCatalog, - String defaultSchema) { - StringBuffer buf = new StringBuffer( - dialect.getAddPrimaryKeyConstraintString( constraintName ) - ).append( '(' ); - Iterator iter = getColumnIterator(); - boolean nullable = false; - while ( iter.hasNext() ) { - Column column = (Column) iter.next(); - if ( !nullable && column.isNullable() ) nullable = true; - buf.append( column.getQuotedName( dialect ) ); - if ( iter.hasNext() ) buf.append( ", " ); - } - return !nullable || dialect.supportsNotNullUnique() ? - StringHelper.replace( buf.append( ')' ).toString(), "primary key", "unique" ) : - //TODO: improve this hack! - null; + @Override + public String sqlCreateString(Dialect dialect, Mapping p, + String defaultCatalog, String defaultSchema) { + return dialect.getUniqueDelegate().getAlterTableToAddUniqueKeyCommand( + this, defaultCatalog, defaultSchema + ); } - public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) { - if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) { - return super.sqlCreateString( dialect, p, defaultCatalog, defaultSchema ); - } - else { - return Index.buildSqlCreateIndexString( dialect, getName(), getTable(), getColumnIterator(), true, - defaultCatalog, defaultSchema ); - } + @Override + public String sqlDropString(Dialect dialect, String defaultCatalog, + String defaultSchema) { + return dialect.getUniqueDelegate().getAlterTableToDropUniqueKeyCommand( + this, defaultCatalog, defaultSchema + ); } - public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) { - if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) { - return super.sqlDropString( dialect, defaultCatalog, defaultSchema ); + public void addColumn(Column column, String order) { + addColumn( column ); + if ( StringHelper.isNotEmpty( order ) ) { + columnOrderMap.put( column, order ); } - else { - return Index.buildSqlDropIndexString( dialect, getTable(), getName(), defaultCatalog, defaultSchema ); - } } - public boolean isGenerated(Dialect dialect) { - if ( dialect.supportsNotNullUnique() ) return true; - Iterator iter = getColumnIterator(); - while ( iter.hasNext() ) { - if ( ( (Column) iter.next() ).isNullable() ) { - return false; - } - } - return true; + public Map getColumnOrderMap() { + return columnOrderMap; } - + + public String generatedConstraintNamePrefix() { + return "UK_"; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/Value.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/Value.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/Value.java 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/Value.java 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,16 +20,14 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; - import java.io.Serializable; import java.util.Iterator; import org.hibernate.FetchMode; import org.hibernate.MappingException; -import org.hibernate.engine.Mapping; +import org.hibernate.engine.spi.Mapping; import org.hibernate.type.Type; /** @@ -43,7 +41,7 @@ */ public interface Value extends Serializable { public int getColumnSpan(); - public Iterator getColumnIterator(); + public Iterator getColumnIterator(); public Type getType() throws MappingException; public FetchMode getFetchMode(); public Table getTable(); @@ -57,4 +55,4 @@ public boolean isValid(Mapping mapping) throws MappingException; public void setTypeUsingReflection(String className, String propertyName) throws MappingException; public Object accept(ValueVisitor visitor); -} \ No newline at end of file +} Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/ValueVisitor.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/ValueVisitor.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/ValueVisitor.java 17 Aug 2012 14:33:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/ValueVisitor.java 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,10 +20,10 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.mapping; + /** * @author max * Index: 3rdParty_sources/hibernate-core/org/hibernate/mapping/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/mapping/package.html,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/mapping/package.html 17 Aug 2012 14:33:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/mapping/package.html 30 Jul 2014 16:16:01 -0000 1.1.2.1 @@ -1,10 +1,10 @@ Index: 3rdParty_sources/hibernate-core/org/hibernate/metadata/ClassMetadata.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/metadata/ClassMetadata.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/metadata/ClassMetadata.java 17 Aug 2012 14:34:04 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/metadata/ClassMetadata.java 30 Jul 2014 16:16:25 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,16 +20,14 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.metadata; import java.io.Serializable; import java.util.Map; import org.hibernate.HibernateException; -import org.hibernate.EntityMode; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.type.Type; /** @@ -38,6 +36,7 @@ * @see org.hibernate.SessionFactory#getClassMetadata(Class) * @author Gavin King */ +@SuppressWarnings( {"JavaDoc"}) public interface ClassMetadata { // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -137,7 +136,8 @@ /** * Return the values of the mapped properties of the object */ - public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session) + @SuppressWarnings( {"UnusedDeclaration"}) + public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session) throws HibernateException; @@ -148,62 +148,80 @@ /** * The persistent class, or null */ - public Class getMappedClass(EntityMode entityMode); + public Class getMappedClass(); /** * Create a class instance initialized with the given identifier + * + * @param id The identifier value to use (may be null to represent no value) + * @param session The session from which the request originated. + * + * @return The instantiated entity. */ - public Object instantiate(Serializable id, EntityMode entityMode) throws HibernateException; + public Object instantiate(Serializable id, SessionImplementor session); /** * Get the value of a particular (named) property */ - public Object getPropertyValue(Object object, String propertyName, EntityMode entityMode) throws HibernateException; + public Object getPropertyValue(Object object, String propertyName) throws HibernateException; /** * Extract the property values from the given entity. * * @param entity The entity from which to extract the property values. - * @param entityMode The entity-mode of the given entity * @return The property values. * @throws HibernateException */ - public Object[] getPropertyValues(Object entity, EntityMode entityMode) throws HibernateException; + public Object[] getPropertyValues(Object entity) throws HibernateException; /** * Set the value of a particular (named) property */ - public void setPropertyValue(Object object, String propertyName, Object value, EntityMode entityMode) throws HibernateException; + public void setPropertyValue(Object object, String propertyName, Object value) throws HibernateException; /** * Set the given values to the mapped properties of the given object */ - public void setPropertyValues(Object object, Object[] values, EntityMode entityMode) throws HibernateException; + public void setPropertyValues(Object object, Object[] values) throws HibernateException; /** * Get the identifier of an instance (throw an exception if no identifier property) + * + * @deprecated Use {@link #getIdentifier(Object,SessionImplementor)} instead */ - public Serializable getIdentifier(Object entity, EntityMode entityMode) throws HibernateException; + @SuppressWarnings( {"JavaDoc"}) + public Serializable getIdentifier(Object object) throws HibernateException; /** - * Set the identifier of an instance (or do nothing if no identifier property) + * Get the identifier of an instance (throw an exception if no identifier property) + * + * @param entity The entity for which to get the identifier + * @param session The session from which the request originated + * + * @return The identifier */ - public void setIdentifier(Object object, Serializable id, EntityMode entityMode) throws HibernateException; + public Serializable getIdentifier(Object entity, SessionImplementor session); /** - * Does the class implement the Lifecycle interface? + * Inject the identifier value into the given entity. + * + * @param entity The entity to inject with the identifier value. + * @param id The value to be injected as the identifier. + * @param session The session from which is requests originates */ - public boolean implementsLifecycle(EntityMode entityMode); + public void setIdentifier(Object entity, Serializable id, SessionImplementor session); + /** - * Does the class implement the Validatable interface? + * Does the class implement the Lifecycle interface? */ - public boolean implementsValidatable(EntityMode entityMode); + @SuppressWarnings( {"UnusedDeclaration"}) + public boolean implementsLifecycle(); /** * Get the version number (or timestamp) from the object's version property * (or return null if not versioned) */ - public Object getVersion(Object object, EntityMode entityMode) throws HibernateException; + public Object getVersion(Object object) throws HibernateException; } Index: 3rdParty_sources/hibernate-core/org/hibernate/metadata/CollectionMetadata.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/metadata/CollectionMetadata.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/metadata/CollectionMetadata.java 17 Aug 2012 14:34:04 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/metadata/CollectionMetadata.java 30 Jul 2014 16:16:25 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.metadata; - import org.hibernate.type.Type; /** Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/Metadata.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/MetadataBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/MetadataSourceProcessingOrder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/MetadataSources.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/SessionFactoryBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/ValidationException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/package.html'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/AbstractAttributeBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/AbstractCollectionElement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/AbstractPluralAttributeBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/AbstractSingularAttributeBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/AssociationAttributeBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/AttributeBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/AttributeBindingContainer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/BagBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/BasicAttributeBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/BasicCollectionElement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/Caching.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/CascadeType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/CollectionElementNature.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/CollectionKey.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/CollectionLaziness.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/ComponentAttributeBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/CompositeCollectionElement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/CustomSQL.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/EntityBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/EntityDiscriminator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/EntityIdentifier.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/FetchProfile.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/Helper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/HibernateTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/HierarchyDetails.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/IdGenerator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/InheritanceType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/KeyValueBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/ManyToAnyCollectionElement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/ManyToManyCollectionElement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/ManyToOneAttributeBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/MetaAttribute.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/OneToManyCollectionElement.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/PluralAttributeBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/SetBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/SimpleValueBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/SingularAssociationAttributeBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/SingularAttributeBinding.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/binding/TypeDef.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/AbstractAttributeContainer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/Attribute.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/AttributeContainer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/BasicType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/Component.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/Entity.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/Hierarchical.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/IndexedPluralAttribute.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/JavaType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/NonEntity.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/PluralAttribute.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/PluralAttributeNature.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/SingularAttribute.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/Superclass.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/Type.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/TypeNature.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/domain/package.html'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/AbstractAuxiliaryDatabaseObject.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/AbstractConstraint.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/AbstractSimpleValue.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/AbstractTableSpecification.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/AuxiliaryDatabaseObject.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/BasicAuxiliaryDatabaseObjectImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/CheckConstraint.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/Column.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/Constraint.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/Database.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/Datatype.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/DerivedValue.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/Exportable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/ForeignKey.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/Identifier.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/IllegalIdentifierException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/InLineView.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/Index.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/Loggable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/ObjectName.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/PrimaryKey.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/Schema.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/Sequence.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/SimpleValue.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/Size.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/Table.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/TableSpecification.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/Tuple.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/UniqueKey.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/Value.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/ValueContainer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/package.html'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/state/ColumnRelationalState.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/state/DerivedValueRelationalState.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/state/ManyToOneRelationalState.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/state/SimpleValueRelationalState.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/state/TupleRelationalState.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/relational/state/ValueRelationalState.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/BindingContext.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/LocalBindingContext.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/MappingDefaults.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/MappingException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/MappingNotFoundException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/MetaAttributeContext.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/MetadataImplementor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/MetadataSourceProcessor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/XsdException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/AnnotationBindingContext.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/AnnotationBindingContextImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/AnnotationMetadataSourceProcessorImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/EntityHierarchyBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/EntityHierarchyImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/EnumConversionHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/HibernateDotNames.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/JPADotNames.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/JandexHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/ReflectionHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/UnknownInheritanceTypeException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/AssociationAttribute.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/AttributeNature.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/AttributeOverride.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/BasicAttribute.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/ColumnSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/ColumnValues.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/ColumnValuesSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/DerivedValueSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/DiscriminatorSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/ExplicitHibernateTypeSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/FormulaValue.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/MappedAttribute.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/SimpleIdentifierSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/SingularAttributeSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/ToOneAttributeSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/type/AbstractAttributeTypeResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/type/AttributeTypeResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/type/AttributeTypeResolverImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/type/CompositeAttributeTypeResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/type/EnumeratedTypeResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/type/LobTypeResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/type/TemporalTypeResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/attribute/type/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/entity/ComponentAttributeSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/entity/ConfiguredClass.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/entity/ConfiguredClassType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/entity/EmbeddableClass.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/entity/EmbeddableHierarchy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/entity/EntityBindingContext.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/entity/EntityClass.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/entity/EntitySourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/entity/IdType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/entity/RootEntitySourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/entity/SubclassEntitySourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/entity/TableSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/entity/UniqueConstraintSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/global/FetchProfileBinder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/global/FilterDefBinder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/global/IdGeneratorBinder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/global/QueryBinder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/global/TableBinder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/global/TypeDefBinder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/PseudoJpaDotNames.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/filter/AbstractAnnotationFilter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/filter/ExclusiveAnnotationFilter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/filter/IndexedAnnotationFilter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/filter/NameAnnotationFilter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/filter/NameTargetAnnotationFilter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/AbstractAttributesBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/AbstractEntityObjectMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/AbstractMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/AccessHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/AnnotationMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/AttributesBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/BasicMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/DefaultConfigurationHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/ElementCollectionMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/EmbeddableAttributesBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/EmbeddableMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/EmbeddedIdMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/EmbeddedMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/EntityMappingsMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/EntityMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/GlobalAnnotationMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/GlobalAnnotations.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/IdMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/IndexBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/ListenerMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/ManyToManyMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/ManyToOneMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/MappedSuperclassMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/MockHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/OneToManyMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/OneToOneMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/PersistenceMetadataMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/PropertyMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/SchemaAware.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/TransientMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/annotations/xml/mocker/VersionMocker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/AssociationAttributeSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/AttributeSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/AttributeSourceContainer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/BasicPluralAttributeElementSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/Binder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/ColumnSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/ComponentAttributeSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/ComponentIdentifierSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/CompositePluralAttributeElementSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/ConstraintSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/DerivedValueSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/DiscriminatorSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/EntityHierarchy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/EntitySource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/ExplicitHibernateTypeSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/IdentifierSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/JpaCallbackClass.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/ManyToAnyPluralAttributeElementSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/ManyToManyPluralAttributeElementSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/MetaAttributeSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/OneToManyPluralAttributeElementSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/Orderable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/PluralAttributeElementNature.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/PluralAttributeElementSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/PluralAttributeKeySource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/PluralAttributeNature.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/PluralAttributeSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/RelationalValueSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/RelationalValueSourceContainer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/RootEntitySource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/SimpleIdentifierSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/SingularAttributeNature.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/SingularAttributeSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/Sortable.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/SubclassEntityContainer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/SubclassEntitySource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/TableSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/ToOneAttributeSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/binder/UniqueConstraintSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/AbstractEntitySourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/AbstractPluralAttributeSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/BagAttributeSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/BasicPluralAttributeElementSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/ColumnAttributeSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/ColumnSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/ComponentAttributeSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/CompositePluralAttributeElementSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/EntityHierarchyImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/FormulaImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/HbmBindingContext.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/HbmMetadataSourceProcessorImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/Helper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/HibernateMappingProcessor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/HierarchyBuilder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/ManyToManyPluralAttributeElementSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/ManyToOneAttributeSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/MappingDocument.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/OneToManyPluralAttributeElementSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/PluralAttributeKeySourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/PropertyAttributeSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/RootEntitySourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/SetAttributeSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/SingularIdentifierAttributeSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/SubclassEntitySourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/TimestampAttributeSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/hbm/VersionAttributeSourceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/internal/AssociationResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/internal/HibernateTypeResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/internal/IdentifierGeneratorResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/internal/JaxbHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/internal/MetadataBuilderImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/internal/MetadataImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/internal/OverriddenMappingDefaults.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/source/internal/SessionFactoryBuilderImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/spi/TypeContributions.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/metamodel/spi/TypeContributor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/PersisterFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/AbstractCollectionPersister.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/collection/AbstractCollectionPersister.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/AbstractCollectionPersister.java 17 Aug 2012 14:33:55 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/AbstractCollectionPersister.java 30 Jul 2014 16:16:07 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.persister.collection; @@ -32,35 +31,41 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.AssertionFailure; import org.hibernate.FetchMode; import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.QueryException; import org.hibernate.TransientObjectException; -import org.hibernate.jdbc.Expectation; -import org.hibernate.jdbc.Expectations; import org.hibernate.cache.CacheException; -import org.hibernate.cache.access.CollectionRegionAccessStrategy; -import org.hibernate.cache.entry.CacheEntryStructure; -import org.hibernate.cache.entry.StructuredCollectionCacheEntry; -import org.hibernate.cache.entry.StructuredMapCacheEntry; -import org.hibernate.cache.entry.UnstructuredCacheEntry; +import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; +import org.hibernate.cache.spi.entry.CacheEntryStructure; +import org.hibernate.cache.spi.entry.StructuredCollectionCacheEntry; +import org.hibernate.cache.spi.entry.StructuredMapCacheEntry; +import org.hibernate.cache.spi.entry.UnstructuredCacheEntry; import org.hibernate.cfg.Configuration; -import org.hibernate.collection.PersistentCollection; +import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.EntityKey; -import org.hibernate.engine.PersistenceContext; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.engine.SubselectFetch; -import org.hibernate.engine.ExecuteUpdateResultCheckStyle; -import org.hibernate.exception.JDBCExceptionHelper; -import org.hibernate.exception.SQLExceptionConverter; +import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; +import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; +import org.hibernate.engine.spi.EntityKey; +import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.PersistenceContext; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.engine.spi.SubselectFetch; +import org.hibernate.exception.spi.SQLExceptionConverter; import org.hibernate.id.IdentifierGenerator; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.FilterAliasGenerator; +import org.hibernate.internal.FilterHelper; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.jdbc.Expectation; +import org.hibernate.jdbc.Expectations; import org.hibernate.loader.collection.CollectionInitializer; import org.hibernate.mapping.Collection; import org.hibernate.mapping.Column; @@ -74,20 +79,37 @@ import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Loadable; import org.hibernate.persister.entity.PropertyMapping; +import org.hibernate.persister.entity.Queryable; +import org.hibernate.persister.walking.internal.CompositionSingularSubAttributesHelper; +import org.hibernate.persister.walking.internal.StandardAnyTypeDefinition; +import org.hibernate.persister.walking.spi.AnyMappingDefinition; +import org.hibernate.persister.walking.spi.AttributeDefinition; +import org.hibernate.persister.walking.spi.AttributeSource; +import org.hibernate.persister.walking.spi.CollectionDefinition; +import org.hibernate.persister.walking.spi.CollectionElementDefinition; +import org.hibernate.persister.walking.spi.CollectionIndexDefinition; +import org.hibernate.persister.walking.spi.CompositeCollectionElementDefinition; +import org.hibernate.persister.walking.spi.CompositionDefinition; +import org.hibernate.persister.walking.spi.EntityDefinition; import org.hibernate.pretty.MessageHelper; import org.hibernate.sql.Alias; import org.hibernate.sql.SelectFragment; import org.hibernate.sql.SimpleSelect; import org.hibernate.sql.Template; -import org.hibernate.type.AbstractComponentType; +import org.hibernate.sql.ordering.antlr.ColumnMapper; +import org.hibernate.sql.ordering.antlr.ColumnReference; +import org.hibernate.sql.ordering.antlr.FormulaReference; +import org.hibernate.sql.ordering.antlr.OrderByAliasResolver; +import org.hibernate.sql.ordering.antlr.OrderByTranslation; +import org.hibernate.sql.ordering.antlr.SqlValueReference; +import org.hibernate.type.AnyType; +import org.hibernate.type.AssociationType; import org.hibernate.type.CollectionType; +import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; -import org.hibernate.util.ArrayHelper; -import org.hibernate.util.CollectionHelper; -import org.hibernate.util.FilterHelper; -import org.hibernate.util.StringHelper; +import org.jboss.logging.Logger; /** * Base implementation of the QueryableCollection interface. @@ -98,11 +120,15 @@ */ public abstract class AbstractCollectionPersister implements CollectionMetadata, SQLLoadableCollection { + + private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, + AbstractCollectionPersister.class.getName() ); + // TODO: encapsulate the protected instance variables! private final String role; - //SQL statements + // SQL statements private final String sqlDeleteString; private final String sqlInsertRowString; private final String sqlUpdateRowString; @@ -112,45 +138,53 @@ private final String sqlDetectRowByIndexString; private final String sqlDetectRowByElementString; - private final String sqlOrderByString; + protected final boolean hasWhere; protected final String sqlWhereString; - private final String sqlOrderByStringTemplate; private final String sqlWhereStringTemplate; + private final boolean hasOrder; - protected final boolean hasWhere; + private final OrderByTranslation orderByTranslation; + + private final boolean hasManyToManyOrder; + private final OrderByTranslation manyToManyOrderByTranslation; + private final int baseIndex; - + private final String nodeName; private final String elementNodeName; private final String indexNodeName; + private String mappedByProperty; protected final boolean indexContainsFormula; protected final boolean elementIsPureFormula; - - //types + + // types private final Type keyType; private final Type indexType; protected final Type elementType; private final Type identifierType; - //columns + // columns protected final String[] keyColumnNames; protected final String[] indexColumnNames; protected final String[] indexFormulaTemplates; protected final String[] indexFormulas; protected final boolean[] indexColumnIsSettable; protected final String[] elementColumnNames; + protected final String[] elementColumnWriters; + protected final String[] elementColumnReaders; + protected final String[] elementColumnReaderTemplates; protected final String[] elementFormulaTemplates; protected final String[] elementFormulas; protected final boolean[] elementColumnIsSettable; protected final boolean[] elementColumnIsInPrimaryKey; protected final String[] indexColumnAliases; protected final String[] elementColumnAliases; protected final String[] keyColumnAliases; - + protected final String identifierColumnName; private final String identifierColumnAlias; - //private final String unquotedIdentifierColumnName; + // private final String unquotedIdentifierColumnName; protected final String qualifiedTableName; @@ -162,20 +196,20 @@ protected final boolean hasIdentifier; private final boolean isLazy; private final boolean isExtraLazy; - private final boolean isInverse; + protected final boolean isInverse; private final boolean isMutable; private final boolean isVersioned; protected final int batchSize; private final FetchMode fetchMode; private final boolean hasOrphanDelete; private final boolean subselectLoadable; - //extra information about the element type + // extra information about the element type private final Class elementClass; private final String entityName; private final Dialect dialect; - private final SQLExceptionConverter sqlExceptionConverter; + protected final SqlExceptionHelper sqlExceptionHelper; private final SessionFactoryImplementor factory; private final EntityPersister ownerPersister; private final IdentifierGenerator identifierGenerator; @@ -184,7 +218,7 @@ private final CollectionRegionAccessStrategy cacheAccessStrategy; private final CollectionType collectionType; private CollectionInitializer initializer; - + private final CacheEntryStructure cacheEntryStructure; // dynamic filters for the collection @@ -196,9 +230,6 @@ private final String manyToManyWhereString; private final String manyToManyWhereTemplate; - private final String manyToManyOrderByString; - private final String manyToManyOrderByTemplate; - // custom sql private final boolean insertCallable; private final boolean updateCallable; @@ -214,8 +245,6 @@ private Map collectionPropertyColumnAliases = new HashMap(); private Map collectionPropertyColumnNames = new HashMap(); - private static final Logger log = LoggerFactory.getLogger( AbstractCollectionPersister.class ); - public AbstractCollectionPersister( final Collection collection, final CollectionRegionAccessStrategy cacheAccessStrategy, @@ -225,38 +254,39 @@ this.factory = factory; this.cacheAccessStrategy = cacheAccessStrategy; if ( factory.getSettings().isStructuredCacheEntriesEnabled() ) { - cacheEntryStructure = collection.isMap() ? - ( CacheEntryStructure ) new StructuredMapCacheEntry() : - ( CacheEntryStructure ) new StructuredCollectionCacheEntry(); + cacheEntryStructure = collection.isMap() + ? StructuredMapCacheEntry.INSTANCE + : StructuredCollectionCacheEntry.INSTANCE; } else { - cacheEntryStructure = new UnstructuredCacheEntry(); + cacheEntryStructure = UnstructuredCacheEntry.INSTANCE; } - + dialect = factory.getDialect(); - sqlExceptionConverter = factory.getSQLExceptionConverter(); + sqlExceptionHelper = factory.getSQLExceptionHelper(); collectionType = collection.getCollectionType(); role = collection.getRole(); entityName = collection.getOwnerEntityName(); - ownerPersister = factory.getEntityPersister(entityName); + ownerPersister = factory.getEntityPersister( entityName ); queryLoaderName = collection.getLoaderName(); nodeName = collection.getNodeName(); isMutable = collection.isMutable(); + mappedByProperty = collection.getMappedByProperty(); Table table = collection.getCollectionTable(); fetchMode = collection.getElement().getFetchMode(); elementType = collection.getElement().getType(); - //isSet = collection.isSet(); - //isSorted = collection.isSorted(); + // isSet = collection.isSet(); + // isSorted = collection.isSorted(); isPrimitiveArray = collection.isPrimitiveArray(); isArray = collection.isArray(); subselectLoadable = collection.isSubselectLoadable(); - - qualifiedTableName = table.getQualifiedName( + + qualifiedTableName = table.getQualifiedName( dialect, factory.getSettings().getDefaultCatalogName(), - factory.getSettings().getDefaultSchemaName() - ); + factory.getSettings().getDefaultSchemaName() + ); int spacesSize = 1 + collection.getSynchronizedTables().size(); spaces = new String[spacesSize]; @@ -265,16 +295,11 @@ for ( int i = 1; i < spacesSize; i++ ) { spaces[i] = (String) iter.next(); } - - sqlOrderByString = collection.getOrderBy(); - hasOrder = sqlOrderByString != null; - sqlOrderByStringTemplate = hasOrder ? - Template.renderOrderByStringTemplate(sqlOrderByString, dialect, factory.getSqlFunctionRegistry()) : - null; + sqlWhereString = StringHelper.isNotEmpty( collection.getWhere() ) ? "( " + collection.getWhere() + ") " : null; hasWhere = sqlWhereString != null; sqlWhereStringTemplate = hasWhere ? - Template.renderWhereStringTemplate(sqlWhereString, dialect, factory.getSqlFunctionRegistry()) : + Template.renderWhereStringTemplate( sqlWhereString, dialect, factory.getSqlFunctionRegistry() ) : null; hasOrphanDelete = collection.hasOrphanDelete(); @@ -286,7 +311,7 @@ batchSize = batch; isVersioned = collection.isOptimisticLocked(); - + // KEY keyType = collection.getKey().getType(); @@ -298,33 +323,36 @@ while ( iter.hasNext() ) { // NativeSQL: collect key column and auto-aliases Column col = ( (Column) iter.next() ); - keyColumnNames[k] = col.getQuotedName(dialect); - keyColumnAliases[k] = col.getAlias(dialect); + keyColumnNames[k] = col.getQuotedName( dialect ); + keyColumnAliases[k] = col.getAlias( dialect, collection.getOwner().getRootTable() ); k++; } - - //unquotedKeyColumnNames = StringHelper.unQuote(keyColumnAliases); - //ELEMENT + // unquotedKeyColumnNames = StringHelper.unQuote(keyColumnAliases); + // ELEMENT + String elemNode = collection.getElementNodeName(); if ( elementType.isEntityType() ) { String entityName = ( (EntityType) elementType ).getAssociatedEntityName(); - elementPersister = factory.getEntityPersister(entityName); - if ( elemNode==null ) { - elemNode = cfg.getClassMapping(entityName).getNodeName(); + elementPersister = factory.getEntityPersister( entityName ); + if ( elemNode == null ) { + elemNode = cfg.getClassMapping( entityName ).getNodeName(); } // NativeSQL: collect element column and auto-aliases - + } else { elementPersister = null; - } + } elementNodeName = elemNode; int elementSpan = collection.getElement().getColumnSpan(); elementColumnAliases = new String[elementSpan]; elementColumnNames = new String[elementSpan]; + elementColumnWriters = new String[elementSpan]; + elementColumnReaders = new String[elementSpan]; + elementColumnReaderTemplates = new String[elementSpan]; elementFormulaTemplates = new String[elementSpan]; elementFormulas = new String[elementSpan]; elementColumnIsSettable = new boolean[elementSpan]; @@ -335,15 +363,18 @@ iter = collection.getElement().getColumnIterator(); while ( iter.hasNext() ) { Selectable selectable = (Selectable) iter.next(); - elementColumnAliases[j] = selectable.getAlias(dialect); + elementColumnAliases[j] = selectable.getAlias( dialect, table ); if ( selectable.isFormula() ) { Formula form = (Formula) selectable; - elementFormulaTemplates[j] = form.getTemplate(dialect, factory.getSqlFunctionRegistry()); + elementFormulaTemplates[j] = form.getTemplate( dialect, factory.getSqlFunctionRegistry() ); elementFormulas[j] = form.getFormula(); } else { Column col = (Column) selectable; - elementColumnNames[j] = col.getQuotedName(dialect); + elementColumnNames[j] = col.getQuotedName( dialect ); + elementColumnWriters[j] = col.getWriteExpr(); + elementColumnReaders[j] = col.getReadExpr( dialect ); + elementColumnReaderTemplates[j] = col.getTemplate( dialect, factory.getSqlFunctionRegistry() ); elementColumnIsSettable[j] = true; elementColumnIsInPrimaryKey[j] = !col.isNullable(); if ( !col.isNullable() ) { @@ -354,19 +385,18 @@ j++; } elementIsPureFormula = isPureFormula; - - //workaround, for backward compatibility of sets with no - //not-null columns, assume all columns are used in the - //row locator SQL + + // workaround, for backward compatibility of sets with no + // not-null columns, assume all columns are used in the + // row locator SQL if ( !hasNotNullableColumns ) { Arrays.fill( elementColumnIsInPrimaryKey, true ); } - // INDEX AND ROW SELECT hasIndex = collection.isIndexed(); - if (hasIndex) { + if ( hasIndex ) { // NativeSQL: collect index column and auto-aliases IndexedCollection indexedCollection = (IndexedCollection) collection; indexType = indexedCollection.getIndex().getType(); @@ -381,25 +411,25 @@ boolean hasFormula = false; while ( iter.hasNext() ) { Selectable s = (Selectable) iter.next(); - indexColumnAliases[i] = s.getAlias(dialect); + indexColumnAliases[i] = s.getAlias( dialect ); if ( s.isFormula() ) { Formula indexForm = (Formula) s; - indexFormulaTemplates[i] = indexForm.getTemplate(dialect, factory.getSqlFunctionRegistry()); + indexFormulaTemplates[i] = indexForm.getTemplate( dialect, factory.getSqlFunctionRegistry() ); indexFormulas[i] = indexForm.getFormula(); hasFormula = true; } else { Column indexCol = (Column) s; - indexColumnNames[i] = indexCol.getQuotedName(dialect); + indexColumnNames[i] = indexCol.getQuotedName( dialect ); indexColumnIsSettable[i] = true; } i++; } indexContainsFormula = hasFormula; - baseIndex = indexedCollection.isList() ? + baseIndex = indexedCollection.isList() ? ( (List) indexedCollection ).getBaseIndex() : 0; - indexNodeName = indexedCollection.getIndexNodeName(); + indexNodeName = indexedCollection.getIndexNodeName(); } else { @@ -413,39 +443,40 @@ baseIndex = 0; indexNodeName = null; } - + hasIdentifier = collection.isIdentified(); - if (hasIdentifier) { + if ( hasIdentifier ) { if ( collection.isOneToMany() ) { throw new MappingException( "one-to-many collections with identifiers are not supported" ); } IdentifierCollection idColl = (IdentifierCollection) collection; identifierType = idColl.getIdentifier().getType(); iter = idColl.getIdentifier().getColumnIterator(); - Column col = ( Column ) iter.next(); - identifierColumnName = col.getQuotedName(dialect); - identifierColumnAlias = col.getAlias(dialect); - //unquotedIdentifierColumnName = identifierColumnAlias; - identifierGenerator = idColl.getIdentifier().createIdentifierGenerator( + Column col = (Column) iter.next(); + identifierColumnName = col.getQuotedName( dialect ); + identifierColumnAlias = col.getAlias( dialect ); + // unquotedIdentifierColumnName = identifierColumnAlias; + identifierGenerator = idColl.getIdentifier().createIdentifierGenerator( + cfg.getIdentifierGeneratorFactory(), factory.getDialect(), factory.getSettings().getDefaultCatalogName(), factory.getSettings().getDefaultSchemaName(), null - ); + ); } else { identifierType = null; identifierColumnName = null; identifierColumnAlias = null; - //unquotedIdentifierColumnName = null; + // unquotedIdentifierColumnName = null; identifierGenerator = null; } - - //GENERATE THE SQL: - - //sqlSelectString = sqlSelectString(); - //sqlSelectRowString = sqlSelectRowString(); + // GENERATE THE SQL: + + // sqlSelectString = sqlSelectString(); + // sqlSelectRowString = sqlSelectRowString(); + if ( collection.getCustomSQLInsert() == null ) { sqlInsertRowString = generateInsertRowString(); insertCallable = false; @@ -456,7 +487,7 @@ insertCallable = collection.isCustomInsertCallable(); insertCheckStyle = collection.getCustomSQLInsertCheckStyle() == null ? ExecuteUpdateResultCheckStyle.determineDefault( collection.getCustomSQLInsert(), insertCallable ) - : collection.getCustomSQLInsertCheckStyle(); + : collection.getCustomSQLInsertCheckStyle(); } if ( collection.getCustomSQLUpdate() == null ) { @@ -469,7 +500,7 @@ updateCallable = collection.isCustomUpdateCallable(); updateCheckStyle = collection.getCustomSQLUpdateCheckStyle() == null ? ExecuteUpdateResultCheckStyle.determineDefault( collection.getCustomSQLUpdate(), insertCallable ) - : collection.getCustomSQLUpdateCheckStyle(); + : collection.getCustomSQLUpdateCheckStyle(); } if ( collection.getCustomSQLDelete() == null ) { @@ -494,13 +525,13 @@ deleteAllCheckStyle = ExecuteUpdateResultCheckStyle.NONE; } - sqlSelectSizeString = generateSelectSizeString( collection.isIndexed() && !collection.isMap() ); + sqlSelectSizeString = generateSelectSizeString( collection.isIndexed() && !collection.isMap() ); sqlDetectRowByIndexString = generateDetectRowByIndexString(); sqlDetectRowByElementString = generateDetectRowByElementString(); sqlSelectRowByIndexString = generateSelectRowByIndexString(); - + logStaticSQL(); - + isLazy = collection.isLazy(); isExtraLazy = collection.isExtraLazy(); @@ -511,86 +542,161 @@ } else { // for non-arrays, we don't need to know the element class - elementClass = null; //elementType.returnedClass(); + elementClass = null; // elementType.returnedClass(); } if ( elementType.isComponentType() ) { - elementPropertyMapping = new CompositeElementPropertyMapping( + elementPropertyMapping = new CompositeElementPropertyMapping( elementColumnNames, + elementColumnReaders, + elementColumnReaderTemplates, elementFormulaTemplates, - (AbstractComponentType) elementType, - factory - ); + (CompositeType) elementType, + factory + ); } else if ( !elementType.isEntityType() ) { - elementPropertyMapping = new ElementPropertyMapping( + elementPropertyMapping = new ElementPropertyMapping( elementColumnNames, - elementType - ); + elementType + ); } else { - if ( elementPersister instanceof PropertyMapping ) { //not all classpersisters implement PropertyMapping! + if ( elementPersister instanceof PropertyMapping ) { // not all classpersisters implement PropertyMapping! elementPropertyMapping = (PropertyMapping) elementPersister; } else { - elementPropertyMapping = new ElementPropertyMapping( + elementPropertyMapping = new ElementPropertyMapping( elementColumnNames, - elementType - ); + elementType + ); } } - + + hasOrder = collection.getOrderBy() != null; + if ( hasOrder ) { + orderByTranslation = Template.translateOrderBy( + collection.getOrderBy(), + new ColumnMapperImpl(), + factory, + dialect, + factory.getSqlFunctionRegistry() + ); + } + else { + orderByTranslation = null; + } + // Handle any filters applied to this collection - filterHelper = new FilterHelper( collection.getFilterMap(), dialect, factory.getSqlFunctionRegistry() ); + filterHelper = new FilterHelper( collection.getFilters(), factory); // Handle any filters applied to this collection for many-to-many - manyToManyFilterHelper = new FilterHelper( collection.getManyToManyFilterMap(), dialect, factory.getSqlFunctionRegistry() ); + manyToManyFilterHelper = new FilterHelper( collection.getManyToManyFilters(), factory); manyToManyWhereString = StringHelper.isNotEmpty( collection.getManyToManyWhere() ) ? "( " + collection.getManyToManyWhere() + ")" : null; manyToManyWhereTemplate = manyToManyWhereString == null ? null : Template.renderWhereStringTemplate( manyToManyWhereString, factory.getDialect(), factory.getSqlFunctionRegistry() ); - manyToManyOrderByString = collection.getManyToManyOrdering(); - manyToManyOrderByTemplate = manyToManyOrderByString == null - ? null - : Template.renderOrderByStringTemplate( manyToManyOrderByString, factory.getDialect(), factory.getSqlFunctionRegistry() ); + hasManyToManyOrder = collection.getManyToManyOrdering() != null; + if ( hasManyToManyOrder ) { + manyToManyOrderByTranslation = Template.translateOrderBy( + collection.getManyToManyOrdering(), + new ColumnMapperImpl(), + factory, + dialect, + factory.getSqlFunctionRegistry() + ); + } + else { + manyToManyOrderByTranslation = null; + } + initCollectionPropertyMap(); } + private class ColumnMapperImpl implements ColumnMapper { + @Override + public SqlValueReference[] map(String reference) { + final String[] columnNames; + final String[] formulaTemplates; + + // handle the special "$element$" property name... + if ( "$element$".equals( reference ) ) { + columnNames = elementColumnNames; + formulaTemplates = elementFormulaTemplates; + } + else { + columnNames = elementPropertyMapping.toColumns( reference ); + formulaTemplates = formulaTemplates( reference, columnNames.length ); + } + + final SqlValueReference[] result = new SqlValueReference[ columnNames.length ]; + int i = 0; + for ( final String columnName : columnNames ) { + if ( columnName == null ) { + // if the column name is null, it indicates that this index in the property value mapping is + // actually represented by a formula. +// final int propertyIndex = elementPersister.getEntityMetamodel().getPropertyIndex( reference ); + final String formulaTemplate = formulaTemplates[i]; + result[i] = new FormulaReference() { + @Override + public String getFormulaFragment() { + return formulaTemplate; + } + }; + } + else { + result[i] = new ColumnReference() { + @Override + public String getColumnName() { + return columnName; + } + }; + } + i++; + } + return result; + } + } + + private String[] formulaTemplates(String reference, int expectedSize) { + try { + final int propertyIndex = elementPersister.getEntityMetamodel().getPropertyIndex( reference ); + return ( (Queryable) elementPersister ).getSubclassPropertyFormulaTemplateClosure()[propertyIndex]; + } + catch (Exception e) { + return new String[expectedSize]; + } + } + + @Override public void postInstantiate() throws MappingException { initializer = queryLoaderName == null ? - createCollectionInitializer( CollectionHelper.EMPTY_MAP ) : + createCollectionInitializer( LoadQueryInfluencers.NONE ) : new NamedQueryCollectionInitializer( queryLoaderName, this ); } protected void logStaticSQL() { - if ( log.isDebugEnabled() ) { - log.debug( "Static SQL for collection: " + getRole() ); - if ( getSQLInsertRowString() != null ) { - log.debug( " Row insert: " + getSQLInsertRowString() ); - } - if ( getSQLUpdateRowString() != null ) { - log.debug( " Row update: " + getSQLUpdateRowString() ); - } - if ( getSQLDeleteRowString() != null ) { - log.debug( " Row delete: " + getSQLDeleteRowString() ); - } - if ( getSQLDeleteString() != null ) { - log.debug( " One-shot delete: " + getSQLDeleteString() ); - } + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Static SQL for collection: %s", getRole() ); + if ( getSQLInsertRowString() != null ) LOG.debugf( " Row insert: %s", getSQLInsertRowString() ); + if ( getSQLUpdateRowString() != null ) LOG.debugf( " Row update: %s", getSQLUpdateRowString() ); + if ( getSQLDeleteRowString() != null ) LOG.debugf( " Row delete: %s", getSQLDeleteRowString() ); + if ( getSQLDeleteString() != null ) LOG.debugf( " One-shot delete: %s", getSQLDeleteString() ); } } + @Override public void initialize(Serializable key, SessionImplementor session) throws HibernateException { getAppropriateInitializer( key, session ).initialize( key, session ); } protected CollectionInitializer getAppropriateInitializer(Serializable key, SessionImplementor session) { if ( queryLoaderName != null ) { - //if there is a user-specified loader, return that - //TODO: filters!? + // if there is a user-specified loader, return that + // TODO: filters!? return initializer; } CollectionInitializer subselectInitializer = getSubselectInitializer( key, session ); @@ -601,7 +707,7 @@ return initializer; } else { - return createCollectionInitializer( session.getEnabledFilters() ); + return createCollectionInitializer( session.getLoadQueryInfluencers() ); } } @@ -610,44 +716,47 @@ if ( !isSubselectLoadable() ) { return null; } - + final PersistenceContext persistenceContext = session.getPersistenceContext(); - + SubselectFetch subselect = persistenceContext.getBatchFetchQueue() - .getSubselect( new EntityKey( key, getOwnerEntityPersister(), session.getEntityMode() ) ); - - if (subselect == null) { + .getSubselect( session.generateEntityKey( key, getOwnerEntityPersister() ) ); + + if ( subselect == null ) { return null; } else { - + // Take care of any entities that might have - // been evicted! + // been evicted! Iterator iter = subselect.getResult().iterator(); while ( iter.hasNext() ) { if ( !persistenceContext.containsEntity( (EntityKey) iter.next() ) ) { iter.remove(); } - } - + } + // Run a subquery loader return createSubselectInitializer( subselect, session ); } } protected abstract CollectionInitializer createSubselectInitializer(SubselectFetch subselect, SessionImplementor session); - protected abstract CollectionInitializer createCollectionInitializer(Map enabledFilters) + protected abstract CollectionInitializer createCollectionInitializer(LoadQueryInfluencers loadQueryInfluencers) throws MappingException; + @Override public CollectionRegionAccessStrategy getCacheAccessStrategy() { return cacheAccessStrategy; } + @Override public boolean hasCache() { return cacheAccessStrategy != null; } + @Override public CollectionType getCollectionType() { return collectionType; } @@ -656,31 +765,36 @@ return StringHelper.replace( sqlWhereStringTemplate, Template.TEMPLATE, alias ); } + @Override public String getSQLOrderByString(String alias) { - return hasOrdering() ? - StringHelper.replace( sqlOrderByStringTemplate, Template.TEMPLATE, alias ) : ""; + return hasOrdering() + ? orderByTranslation.injectAliases( new StandardOrderByAliasResolver( alias ) ) + : ""; } + @Override public String getManyToManyOrderByString(String alias) { - if ( isManyToMany() && manyToManyOrderByString != null ) { - return StringHelper.replace( manyToManyOrderByTemplate, Template.TEMPLATE, alias ); - } - else { - return ""; - } + return hasManyToManyOrdering() + ? manyToManyOrderByTranslation.injectAliases( new StandardOrderByAliasResolver( alias ) ) + : ""; } + + @Override public FetchMode getFetchMode() { return fetchMode; } + @Override public boolean hasOrdering() { return hasOrder; } + @Override public boolean hasManyToManyOrdering() { - return isManyToMany() && manyToManyOrderByTemplate != null; + return isManyToMany() && hasManyToManyOrder; } + @Override public boolean hasWhere() { return hasWhere; } @@ -701,32 +815,38 @@ return sqlDeleteRowString; } + @Override public Type getKeyType() { return keyType; } + @Override public Type getIndexType() { return indexType; } + @Override public Type getElementType() { return elementType; } /** - * Return the element class of an array, or null otherwise + * Return the element class of an array, or null otherwise. needed by arrays */ - public Class getElementClass() { //needed by arrays + @Override + public Class getElementClass() { return elementClass; } - public Object readElement(ResultSet rs, Object owner, String[] aliases, SessionImplementor session) - throws HibernateException, SQLException { + @Override + public Object readElement(ResultSet rs, Object owner, String[] aliases, SessionImplementor session) + throws HibernateException, SQLException { return getElementType().nullSafeGet( rs, aliases, session, owner ); } - public Object readIndex(ResultSet rs, String[] aliases, SessionImplementor session) - throws HibernateException, SQLException { + @Override + public Object readIndex(ResultSet rs, String[] aliases, SessionImplementor session) + throws HibernateException, SQLException { Object index = getIndexType().nullSafeGet( rs, aliases, session, null ); if ( index == null ) { throw new HibernateException( "null index column for collection: " + role ); @@ -736,23 +856,25 @@ } protected Object decrementIndexByBase(Object index) { - if (baseIndex!=0) { - index = new Integer( ( (Integer) index ).intValue() - baseIndex ); + if ( baseIndex != 0 ) { + index = (Integer)index - baseIndex; } return index; } - public Object readIdentifier(ResultSet rs, String alias, SessionImplementor session) - throws HibernateException, SQLException { + @Override + public Object readIdentifier(ResultSet rs, String alias, SessionImplementor session) + throws HibernateException, SQLException { Object id = getIdentifierType().nullSafeGet( rs, alias, session, null ); if ( id == null ) { throw new HibernateException( "null identifier column for collection: " + role ); } return id; } - public Object readKey(ResultSet rs, String[] aliases, SessionImplementor session) - throws HibernateException, SQLException { + @Override + public Object readKey(ResultSet rs, String[] aliases, SessionImplementor session) + throws HibernateException, SQLException { return getKeyType().nullSafeGet( rs, aliases, session, null ); } @@ -761,9 +883,9 @@ */ protected int writeKey(PreparedStatement st, Serializable key, int i, SessionImplementor session) throws HibernateException, SQLException { - + if ( key == null ) { - throw new NullPointerException( "null key for collection: " + role ); //an assertion + throw new NullPointerException( "null key for collection: " + role ); // an assertion } getKeyType().nullSafeSet( st, key, i, session ); return i + keyColumnAliases.length; @@ -774,8 +896,8 @@ */ protected int writeElement(PreparedStatement st, Object elt, int i, SessionImplementor session) throws HibernateException, SQLException { - getElementType().nullSafeSet(st, elt, i, elementColumnIsSettable, session); - return i + ArrayHelper.countTrue(elementColumnIsSettable); + getElementType().nullSafeSet( st, elt, i, elementColumnIsSettable, session ); + return i + ArrayHelper.countTrue( elementColumnIsSettable ); } @@ -784,13 +906,13 @@ */ protected int writeIndex(PreparedStatement st, Object index, int i, SessionImplementor session) throws HibernateException, SQLException { - getIndexType().nullSafeSet( st, incrementIndexByBase(index), i, indexColumnIsSettable, session ); - return i + ArrayHelper.countTrue(indexColumnIsSettable); + getIndexType().nullSafeSet( st, incrementIndexByBase( index ), i, indexColumnIsSettable, session ); + return i + ArrayHelper.countTrue( indexColumnIsSettable ); } protected Object incrementIndexByBase(Object index) { - if (baseIndex!=0) { - index = new Integer( ( (Integer) index ).intValue() + baseIndex ); + if ( baseIndex != 0 ) { + index = (Integer)index + baseIndex; } return index; } @@ -800,10 +922,10 @@ */ protected int writeElementToWhere(PreparedStatement st, Object elt, int i, SessionImplementor session) throws HibernateException, SQLException { - if (elementIsPureFormula) { - throw new AssertionFailure("cannot use a formula-based element in the where condition"); + if ( elementIsPureFormula ) { + throw new AssertionFailure( "cannot use a formula-based element in the where condition" ); } - getElementType().nullSafeSet(st, elt, i, elementColumnIsInPrimaryKey, session); + getElementType().nullSafeSet( st, elt, i, elementColumnIsInPrimaryKey, session ); return i + elementColumnAliases.length; } @@ -813,10 +935,10 @@ */ protected int writeIndexToWhere(PreparedStatement st, Object index, int i, SessionImplementor session) throws HibernateException, SQLException { - if (indexContainsFormula) { - throw new AssertionFailure("cannot use a formula-based index in the where condition"); + if ( indexContainsFormula ) { + throw new AssertionFailure( "cannot use a formula-based index in the where condition" ); } - getIndexType().nullSafeSet( st, incrementIndexByBase(index), i, session ); + getIndexType().nullSafeSet( st, incrementIndexByBase( index ), i, session ); return i + indexColumnAliases.length; } @@ -825,27 +947,32 @@ */ public int writeIdentifier(PreparedStatement st, Object id, int i, SessionImplementor session) throws HibernateException, SQLException { - + getIdentifierType().nullSafeSet( st, id, i, session ); return i + 1; } + @Override public boolean isPrimitiveArray() { return isPrimitiveArray; } + @Override public boolean isArray() { return isArray; } + @Override public String[] getKeyColumnAliases(String suffix) { return new Alias( suffix ).toAliasStrings( keyColumnAliases ); } + @Override public String[] getElementColumnAliases(String suffix) { return new Alias( suffix ).toAliasStrings( elementColumnAliases ); } + @Override public String[] getIndexColumnAliases(String suffix) { if ( hasIndex ) { return new Alias( suffix ).toAliasStrings( indexColumnAliases ); @@ -855,6 +982,7 @@ } } + @Override public String getIdentifierColumnAlias(String suffix) { if ( hasIdentifier ) { return new Alias( suffix ).toAliasString( identifierColumnAlias ); @@ -863,57 +991,60 @@ return null; } } - + + @Override public String getIdentifierColumnName() { if ( hasIdentifier ) { return identifierColumnName; - } else { + } + else { return null; } } /** * Generate a list of collection index, key and element columns */ + @Override public String selectFragment(String alias, String columnSuffix) { SelectFragment frag = generateSelectFragment( alias, columnSuffix ); appendElementColumns( frag, alias ); appendIndexColumns( frag, alias ); appendIdentifierColumns( frag, alias ); return frag.toFragmentString() - .substring( 2 ); //strip leading ',' + .substring( 2 ); // strip leading ',' } protected String generateSelectSizeString(boolean isIntegerIndexed) { - String selectValue = isIntegerIndexed ? - "max(" + getIndexColumnNames()[0] + ") + 1": //lists, arrays - "count(" + getElementColumnNames()[0] + ")"; //sets, maps, bags - return new SimpleSelect(dialect) + String selectValue = isIntegerIndexed ? + "max(" + getIndexColumnNames()[0] + ") + 1" : // lists, arrays + "count(" + getElementColumnNames()[0] + ")"; // sets, maps, bags + return new SimpleSelect( dialect ) .setTableName( getTableName() ) .addCondition( getKeyColumnNames(), "=?" ) - .addColumn(selectValue) + .addColumn( selectValue ) .toStatementString(); } protected String generateDetectRowByIndexString() { if ( !hasIndex() ) { return null; } - return new SimpleSelect(dialect) + return new SimpleSelect( dialect ) .setTableName( getTableName() ) .addCondition( getKeyColumnNames(), "=?" ) .addCondition( getIndexColumnNames(), "=?" ) .addCondition( indexFormulas, "=?" ) - .addColumn("1") + .addColumn( "1" ) .toStatementString(); } protected String generateSelectRowByIndexString() { if ( !hasIndex() ) { return null; } - return new SimpleSelect(dialect) + return new SimpleSelect( dialect ) .setTableName( getTableName() ) .addCondition( getKeyColumnNames(), "=?" ) .addCondition( getIndexColumnNames(), "=?" ) @@ -924,12 +1055,12 @@ } protected String generateDetectRowByElementString() { - return new SimpleSelect(dialect) + return new SimpleSelect( dialect ) .setTableName( getTableName() ) .addCondition( getKeyColumnNames(), "=?" ) .addCondition( getElementColumnNames(), "=?" ) .addCondition( elementFormulas, "=?" ) - .addColumn("1") + .addColumn( "1" ) .toStatementString(); } @@ -940,9 +1071,9 @@ } protected void appendElementColumns(SelectFragment frag, String elemAlias) { - for ( int i=0; i treatAsDeclarations) throws MappingException { + return hasWhere() ? " and " + getSQLWhereString( alias ) : ""; + } + + @Override public String filterFragment(String alias, Map enabledFilters) throws MappingException { + StringBuilder sessionFilterFragment = new StringBuilder(); + filterHelper.render( sessionFilterFragment, getFilterAliasGenerator(alias), enabledFilters ); - StringBuffer sessionFilterFragment = new StringBuffer(); - filterHelper.render( sessionFilterFragment, alias, enabledFilters ); - return sessionFilterFragment.append( filterFragment( alias ) ).toString(); } + @Override + public String filterFragment( + String alias, + Map enabledFilters, + Set treatAsDeclarations) { + StringBuilder sessionFilterFragment = new StringBuilder(); + filterHelper.render( sessionFilterFragment, getFilterAliasGenerator(alias), enabledFilters ); + + return sessionFilterFragment.append( filterFragment( alias, treatAsDeclarations ) ).toString(); + } + + @Override public String oneToManyFilterFragment(String alias) throws MappingException { return ""; } + @Override + public String oneToManyFilterFragment(String alias, Set treatAsDeclarations) { + return oneToManyFilterFragment( alias ); + } + protected boolean isInsertCallable() { return insertCallable; } @@ -1605,203 +1791,425 @@ return deleteAllCheckStyle; } + @Override public String toString() { return StringHelper.unqualify( getClass().getName() ) + '(' + role + ')'; } + @Override public boolean isVersioned() { return isVersioned && getOwnerEntityPersister().isVersioned(); } - + + @Override public String getNodeName() { return nodeName; } + @Override public String getElementNodeName() { return elementNodeName; } + @Override public String getIndexNodeName() { return indexNodeName; } + // TODO: deprecate??? protected SQLExceptionConverter getSQLExceptionConverter() { - return sqlExceptionConverter; + return getSQLExceptionHelper().getSqlExceptionConverter(); } + // TODO: needed??? + protected SqlExceptionHelper getSQLExceptionHelper() { + return sqlExceptionHelper; + } + + @Override public CacheEntryStructure getCacheEntryStructure() { return cacheEntryStructure; } + @Override public boolean isAffectedByEnabledFilters(SessionImplementor session) { return filterHelper.isAffectedBy( session.getEnabledFilters() ) || - ( isManyToMany() && manyToManyFilterHelper.isAffectedBy( session.getEnabledFilters() ) ); + ( isManyToMany() && manyToManyFilterHelper.isAffectedBy( session.getEnabledFilters() ) ); } public boolean isSubselectLoadable() { return subselectLoadable; } - + + @Override public boolean isMutable() { return isMutable; } + @Override public String[] getCollectionPropertyColumnAliases(String propertyName, String suffix) { - String rawAliases[] = (String[]) collectionPropertyColumnAliases.get(propertyName); + String[] rawAliases = (String[]) collectionPropertyColumnAliases.get( propertyName ); if ( rawAliases == null ) { return null; } - - String result[] = new String[rawAliases.length]; - for ( int i=0; i getAttributes() { + return CompositionSingularSubAttributesHelper.getCompositeCollectionIndexSubAttributes( this ); + } + @Override + public CollectionDefinition getCollectionDefinition() { + return AbstractCollectionPersister.this; + } + }; + } + + @Override + public AnyMappingDefinition toAnyMappingDefinition() { + final Type type = getType(); + if ( ! type.isAnyType() ) { + throw new IllegalStateException( "Cannot treat collection index type as ManyToAny" ); + } + return new StandardAnyTypeDefinition( (AnyType) type, isLazy() || isExtraLazy() ); + } + }; + } + + @Override + public CollectionElementDefinition getElementDefinition() { + return new CollectionElementDefinition() { + @Override + public CollectionDefinition getCollectionDefinition() { + return AbstractCollectionPersister.this; + } + + @Override + public Type getType() { + return getElementType(); + } + + @Override + public AnyMappingDefinition toAnyMappingDefinition() { + final Type type = getType(); + if ( ! type.isAnyType() ) { + throw new IllegalStateException( "Cannot treat collection element type as ManyToAny" ); + } + return new StandardAnyTypeDefinition( (AnyType) type, isLazy() || isExtraLazy() ); + } + + @Override + public EntityDefinition toEntityDefinition() { + if ( !getType().isEntityType() ) { + throw new IllegalStateException( "Cannot treat collection element type as entity" ); + } + return getElementPersister(); + } + + @Override + public CompositeCollectionElementDefinition toCompositeElementDefinition() { + + if ( ! getType().isComponentType() ) { + throw new IllegalStateException( "Cannot treat entity collection element type as composite" ); + } + + return new CompositeCollectionElementDefinition() { + @Override + public String getName() { + return ""; + } + + @Override + public CompositeType getType() { + return (CompositeType) getElementType(); + } + + @Override + public boolean isNullable() { + return false; + } + + @Override + public AttributeSource getSource() { + // TODO: what if this is a collection w/in an encapsulated composition attribute? + // should return the encapsulated composition attribute instead??? + return getOwnerEntityPersister(); + } + + @Override + public Iterable getAttributes() { + return CompositionSingularSubAttributesHelper.getCompositeCollectionElementSubAttributes( this ); + } + + @Override + public CollectionDefinition getCollectionDefinition() { + return AbstractCollectionPersister.this; + } + }; + } + }; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/BasicCollectionPersister.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/collection/BasicCollectionPersister.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/BasicCollectionPersister.java 17 Aug 2012 14:33:55 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/BasicCollectionPersister.java 30 Jul 2014 16:16:07 -0000 1.1.2.1 @@ -28,31 +28,35 @@ import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Iterator; +import java.util.Set; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.jdbc.Expectations; -import org.hibernate.jdbc.Expectation; -import org.hibernate.type.AssociationType; -import org.hibernate.persister.entity.Joinable; import org.hibernate.cache.CacheException; -import org.hibernate.cache.access.CollectionRegionAccessStrategy; +import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cfg.Configuration; -import org.hibernate.collection.PersistentCollection; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.engine.SubselectFetch; -import org.hibernate.exception.JDBCExceptionHelper; -import org.hibernate.loader.collection.BatchingCollectionInitializer; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.engine.spi.SubselectFetch; +import org.hibernate.internal.FilterAliasGenerator; +import org.hibernate.internal.StaticFilterAliasGenerator; +import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.jdbc.Expectation; +import org.hibernate.jdbc.Expectations; +import org.hibernate.loader.collection.BatchingCollectionInitializerBuilder; import org.hibernate.loader.collection.CollectionInitializer; import org.hibernate.loader.collection.SubselectCollectionLoader; import org.hibernate.mapping.Collection; +import org.hibernate.persister.entity.Joinable; import org.hibernate.pretty.MessageHelper; import org.hibernate.sql.Delete; import org.hibernate.sql.Insert; -import org.hibernate.sql.Update; import org.hibernate.sql.SelectFragment; -import org.hibernate.util.ArrayHelper; +import org.hibernate.sql.Update; +import org.hibernate.type.AssociationType; /** * Collection persister for collections of values and many-to-many associations. @@ -76,11 +80,12 @@ /** * Generate the SQL DELETE that deletes all rows */ - protected String generateDeleteString() { + @Override + protected String generateDeleteString() { Delete delete = new Delete() .setTableName( qualifiedTableName ) - .setPrimaryKeyColumnNames( keyColumnNames ); + .addPrimaryKeyColumns( keyColumnNames ); if ( hasWhere ) delete.setWhere( sqlWhereString ); @@ -94,7 +99,8 @@ /** * Generate the SQL INSERT that creates a new row */ - protected String generateInsertRowString() { + @Override + protected String generateInsertRowString() { Insert insert = new Insert( getDialect() ) .setTableName( qualifiedTableName ) @@ -111,7 +117,7 @@ } //if ( !elementIsFormula ) { - insert.addColumns( elementColumnNames, elementColumnIsSettable ); + insert.addColumns( elementColumnNames, elementColumnIsSettable, elementColumnWriters ); //} return insert.toStatementString(); @@ -120,23 +126,25 @@ /** * Generate the SQL UPDATE that updates a row */ - protected String generateUpdateRowString() { + @Override + protected String generateUpdateRowString() { Update update = new Update( getDialect() ) .setTableName( qualifiedTableName ); //if ( !elementIsFormula ) { - update.addColumns( elementColumnNames, elementColumnIsSettable ); + update.addColumns( elementColumnNames, elementColumnIsSettable, elementColumnWriters ); //} if ( hasIdentifier ) { - update.setPrimaryKeyColumnNames( new String[]{ identifierColumnName } ); + update.addPrimaryKeyColumns( new String[]{ identifierColumnName } ); } else if ( hasIndex && !indexContainsFormula ) { - update.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, indexColumnNames ) ); + update.addPrimaryKeyColumns( ArrayHelper.join( keyColumnNames, indexColumnNames ) ); } else { - update.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, elementColumnNames, elementColumnIsInPrimaryKey ) ); + update.addPrimaryKeyColumns( keyColumnNames ); + update.addPrimaryKeyColumns( elementColumnNames, elementColumnIsInPrimaryKey, elementColumnWriters ); } if ( getFactory().getSettings().isCommentsEnabled() ) { @@ -145,23 +153,32 @@ return update.toStatementString(); } + + @Override + protected void doProcessQueuedOps(PersistentCollection collection, Serializable id, + int nextIndex, SessionImplementor session) + throws HibernateException { + // nothing to do + } /** * Generate the SQL DELETE that deletes a particular row */ - protected String generateDeleteRowString() { + @Override + protected String generateDeleteRowString() { Delete delete = new Delete() .setTableName( qualifiedTableName ); if ( hasIdentifier ) { - delete.setPrimaryKeyColumnNames( new String[]{ identifierColumnName } ); + delete.addPrimaryKeyColumns( new String[]{ identifierColumnName } ); } else if ( hasIndex && !indexContainsFormula ) { - delete.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, indexColumnNames ) ); + delete.addPrimaryKeyColumns( ArrayHelper.join( keyColumnNames, indexColumnNames ) ); } else { - delete.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, elementColumnNames, elementColumnIsInPrimaryKey ) ); + delete.addPrimaryKeyColumns( keyColumnNames ); + delete.addPrimaryKeyColumns( elementColumnNames, elementColumnIsInPrimaryKey, elementColumnWriters ); } if ( getFactory().getSettings().isCommentsEnabled() ) { @@ -184,11 +201,15 @@ return false; } - public boolean isManyToMany() { + @Override + public boolean isManyToMany() { return elementType.isEntityType(); //instanceof AssociationType; } - protected int doUpdateRows(Serializable id, PersistentCollection collection, SessionImplementor session) + private BasicBatchKey updateBatchKey; + + @Override + protected int doUpdateRows(Serializable id, PersistentCollection collection, SessionImplementor session) throws HibernateException { if ( ArrayHelper.isAllFalse(elementColumnIsSettable) ) return 0; @@ -208,22 +229,22 @@ int offset = 1; if ( useBatch ) { - if ( st == null ) { - if ( callable ) { - st = session.getBatcher().prepareBatchCallableStatement( sql ); - } - else { - st = session.getBatcher().prepareBatchStatement( sql ); - } + if ( updateBatchKey == null ) { + updateBatchKey = new BasicBatchKey( + getRole() + "#UPDATE", + expectation + ); } + st = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getBatch( updateBatchKey ) + .getBatchStatement( sql, callable ); } else { - if ( callable ) { - st = session.getBatcher().prepareCallableStatement( sql ); - } - else { - st = session.getBatcher().prepareStatement( sql ); - } + st = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( sql, callable ); } try { @@ -243,21 +264,24 @@ } if ( useBatch ) { - session.getBatcher().addToBatch( expectation ); + session.getTransactionCoordinator() + .getJdbcCoordinator() + .getBatch( updateBatchKey ) + .addToBatch(); } else { - expectation.verifyOutcome( st.executeUpdate(), st, -1 ); + expectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 ); } } catch ( SQLException sqle ) { if ( useBatch ) { - session.getBatcher().abortBatch( sqle ); + session.getTransactionCoordinator().getJdbcCoordinator().abortBatch(); } throw sqle; } finally { if ( !useBatch ) { - session.getBatcher().closeStatement( st ); + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } } count++; @@ -267,10 +291,9 @@ return count; } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - getSQLExceptionConverter(), + throw getSQLExceptionHelper().convert( sqle, - "could not update collection rows: " + MessageHelper.collectionInfoString( this, id, getFactory() ), + "could not update collection rows: " + MessageHelper.collectionInfoString( this, collection, id, session ), getSQLUpdateRowString() ); } @@ -315,29 +338,49 @@ * * @see org.hibernate.loader.collection.BasicCollectionLoader */ - protected CollectionInitializer createCollectionInitializer(java.util.Map enabledFilters) + @Override + protected CollectionInitializer createCollectionInitializer(LoadQueryInfluencers loadQueryInfluencers) throws MappingException { - return BatchingCollectionInitializer.createBatchingCollectionInitializer( this, batchSize, getFactory(), enabledFilters ); + return BatchingCollectionInitializerBuilder.getBuilder( getFactory() ) + .createBatchingCollectionInitializer( this, batchSize, getFactory(), loadQueryInfluencers ); } + @Override public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) { return ""; } + @Override + public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses, Set treatAsDeclarations) { + return ""; + } + + @Override public String whereJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) { return ""; } - protected CollectionInitializer createSubselectInitializer(SubselectFetch subselect, SessionImplementor session) { + @Override + public String whereJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses, Set treatAsDeclarations) { + return ""; + } + + @Override + protected CollectionInitializer createSubselectInitializer(SubselectFetch subselect, SessionImplementor session) { return new SubselectCollectionLoader( this, subselect.toSubselectString( getCollectionType().getLHSPropertyName() ), subselect.getResult(), subselect.getQueryParameters(), subselect.getNamedParameterLocMap(), session.getFactory(), - session.getEnabledFilters() - ); + session.getLoadQueryInfluencers() + ); } + @Override + public FilterAliasGenerator getFilterAliasGenerator(String rootAlias) { + return new StaticFilterAliasGenerator(rootAlias); + } + } Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CollectionPersister.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CollectionPersister.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CollectionPersister.java 17 Aug 2012 14:33:55 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CollectionPersister.java 30 Jul 2014 16:16:07 -0000 1.1.2.1 @@ -23,22 +23,22 @@ * */ package org.hibernate.persister.collection; - import java.io.Serializable; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.cache.access.CollectionRegionAccessStrategy; -import org.hibernate.cache.entry.CacheEntryStructure; -import org.hibernate.collection.PersistentCollection; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; +import org.hibernate.cache.spi.entry.CacheEntryStructure; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.id.IdentifierGenerator; import org.hibernate.metadata.CollectionMetadata; import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.persister.walking.spi.CollectionDefinition; import org.hibernate.type.CollectionType; import org.hibernate.type.Type; @@ -58,10 +58,10 @@ * May be considered an immutable view of the mapping object * * @see QueryableCollection - * @see PersistentCollection + * @see org.hibernate.collection.spi.PersistentCollection * @author Gavin King */ -public interface CollectionPersister { +public interface CollectionPersister extends CollectionDefinition { /** * Initialize the given collection with the given key */ @@ -199,7 +199,17 @@ Serializable key, SessionImplementor session) throws HibernateException; + /** + * Process queued operations within the PersistentCollection. + */ + public void processQueuedOps( + PersistentCollection collection, + Serializable key, + SessionImplementor session) + throws HibernateException; + + /** * Get the name of this collection role (the fully qualified class name, * extended by a "property path") */ @@ -308,4 +318,10 @@ public boolean indexExists(Serializable key, Object index, SessionImplementor session); public boolean elementExists(Serializable key, Object element, SessionImplementor session); public Object getElementByIndex(Serializable key, Object index, SessionImplementor session, Object owner); + public int getBatchSize(); + + /** + * @return the name of the property this collection is mapped by + */ + public String getMappedByProperty(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CollectionPropertyMapping.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CollectionPropertyMapping.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CollectionPropertyMapping.java 17 Aug 2012 14:33:55 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CollectionPropertyMapping.java 30 Jul 2014 16:16:07 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,13 +20,12 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.persister.collection; -import org.hibernate.Hibernate; import org.hibernate.QueryException; import org.hibernate.persister.entity.PropertyMapping; +import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.Type; /** @@ -49,7 +48,7 @@ return memberPersister.getIndexType(); } else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_SIZE) ) { - return Hibernate.INTEGER; + return StandardBasicTypes.INTEGER; } else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MAX_INDEX) ) { return memberPersister.getIndexType(); Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CollectionPropertyNames.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CollectionPropertyNames.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CollectionPropertyNames.java 17 Aug 2012 14:33:55 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CollectionPropertyNames.java 30 Jul 2014 16:16:07 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2013, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.persister.collection; @@ -29,7 +28,9 @@ * * @author josh */ -public class CollectionPropertyNames { +public final class CollectionPropertyNames { + private CollectionPropertyNames() { + } public static final String COLLECTION_SIZE = "size"; public static final String COLLECTION_ELEMENTS = "elements"; Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CompositeElementPropertyMapping.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CompositeElementPropertyMapping.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CompositeElementPropertyMapping.java 17 Aug 2012 14:33:55 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/CompositeElementPropertyMapping.java 30 Jul 2014 16:16:07 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,33 +20,34 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.persister.collection; - import org.hibernate.MappingException; -import org.hibernate.engine.Mapping; +import org.hibernate.engine.spi.Mapping; import org.hibernate.persister.entity.AbstractPropertyMapping; -import org.hibernate.type.AbstractComponentType; +import org.hibernate.type.CompositeType; import org.hibernate.type.Type; /** * @author Gavin King */ public class CompositeElementPropertyMapping extends AbstractPropertyMapping { - private final AbstractComponentType compositeType; + private final CompositeType compositeType; public CompositeElementPropertyMapping( - String[] elementColumns, + String[] elementColumns, + String[] elementColumnReaders, + String[] elementColumnReaderTemplates, String[] elementFormulaTemplates, - AbstractComponentType compositeType, + CompositeType compositeType, Mapping factory) throws MappingException { this.compositeType = compositeType; - initComponentPropertyPaths(null, compositeType, elementColumns, elementFormulaTemplates, factory); + initComponentPropertyPaths(null, compositeType, elementColumns, elementColumnReaders, + elementColumnReaderTemplates, elementFormulaTemplates, factory); } @@ -58,4 +59,4 @@ return compositeType.getName(); } -} \ No newline at end of file +} Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/ElementPropertyMapping.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/collection/ElementPropertyMapping.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/ElementPropertyMapping.java 17 Aug 2012 14:33:55 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/ElementPropertyMapping.java 30 Jul 2014 16:16:07 -0000 1.1.2.1 @@ -23,12 +23,11 @@ * */ package org.hibernate.persister.collection; - import org.hibernate.MappingException; import org.hibernate.QueryException; +import org.hibernate.internal.util.StringHelper; import org.hibernate.persister.entity.PropertyMapping; import org.hibernate.type.Type; -import org.hibernate.util.StringHelper; /** * @author Gavin King @@ -55,7 +54,7 @@ public String[] toColumns(String alias, String propertyName) throws QueryException { if (propertyName==null || "id".equals(propertyName) ) { - return StringHelper.qualify(alias, elementColumns); + return StringHelper.qualify( alias, elementColumns ); } else { throw new QueryException("cannot dereference scalar collection element: " + propertyName); @@ -73,4 +72,4 @@ return type; } -} \ No newline at end of file +} Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/NamedQueryCollectionInitializer.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/collection/NamedQueryCollectionInitializer.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/NamedQueryCollectionInitializer.java 17 Aug 2012 14:33:55 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/NamedQueryCollectionInitializer.java 30 Jul 2014 16:16:07 -0000 1.1.2.1 @@ -26,49 +26,45 @@ import java.io.Serializable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.FlushMode; import org.hibernate.HibernateException; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.impl.AbstractQueryImpl; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.AbstractQueryImpl; +import org.hibernate.internal.CoreMessageLogger; import org.hibernate.loader.collection.CollectionInitializer; +import org.jboss.logging.Logger; + /** * A wrapper around a named query. * @author Gavin King */ public final class NamedQueryCollectionInitializer implements CollectionInitializer { - private final String queryName; + + private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, + NamedQueryCollectionInitializer.class.getName()); + + private final String queryName; private final CollectionPersister persister; - - private static final Logger log = LoggerFactory.getLogger(NamedQueryCollectionInitializer.class); public NamedQueryCollectionInitializer(String queryName, CollectionPersister persister) { super(); this.queryName = queryName; this.persister = persister; } - public void initialize(Serializable key, SessionImplementor session) + public void initialize(Serializable key, SessionImplementor session) throws HibernateException { - - if ( log.isDebugEnabled() ) { - log.debug( - "initializing collection: " + - persister.getRole() + - " using named query: " + - queryName - ); - } - + + LOG.debugf("Initializing collection: %s using named query: %s", persister.getRole(), queryName); + //TODO: is there a more elegant way than downcasting? - AbstractQueryImpl query = (AbstractQueryImpl) session.getNamedSQLQuery(queryName); + AbstractQueryImpl query = (AbstractQueryImpl) session.getNamedSQLQuery(queryName); if ( query.getNamedParameters().length>0 ) { - query.setParameter( - query.getNamedParameters()[0], - key, - persister.getKeyType() + query.setParameter( + query.getNamedParameters()[0], + key, + persister.getKeyType() ); } else { @@ -79,4 +75,4 @@ .list(); } -} \ No newline at end of file +} Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/OneToManyPersister.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/collection/OneToManyPersister.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/OneToManyPersister.java 17 Aug 2012 14:33:55 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/OneToManyPersister.java 30 Jul 2014 16:16:07 -0000 1.1.2.1 @@ -28,20 +28,24 @@ import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Iterator; +import java.util.Set; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.jdbc.Expectation; -import org.hibernate.jdbc.Expectations; import org.hibernate.cache.CacheException; -import org.hibernate.cache.access.CollectionRegionAccessStrategy; +import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cfg.Configuration; -import org.hibernate.collection.PersistentCollection; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.engine.SubselectFetch; -import org.hibernate.exception.JDBCExceptionHelper; -import org.hibernate.loader.collection.BatchingCollectionInitializer; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.engine.spi.SubselectFetch; +import org.hibernate.internal.FilterAliasGenerator; +import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.jdbc.Expectation; +import org.hibernate.jdbc.Expectations; +import org.hibernate.loader.collection.BatchingCollectionInitializerBuilder; import org.hibernate.loader.collection.CollectionInitializer; import org.hibernate.loader.collection.SubselectOneToManyLoader; import org.hibernate.loader.entity.CollectionElementLoader; @@ -50,24 +54,26 @@ import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.pretty.MessageHelper; import org.hibernate.sql.Update; -import org.hibernate.util.ArrayHelper; /** * Collection persister for one-to-many associations. * * @author Gavin King + * @author Brett Meyer */ public class OneToManyPersister extends AbstractCollectionPersister { private final boolean cascadeDeleteEnabled; private final boolean keyIsNullable; private final boolean keyIsUpdateable; - protected boolean isRowDeleteEnabled() { + @Override + protected boolean isRowDeleteEnabled() { return keyIsUpdateable && keyIsNullable; } - protected boolean isRowInsertEnabled() { + @Override + protected boolean isRowInsertEnabled() { return keyIsUpdateable; } @@ -90,12 +96,13 @@ /** * Generate the SQL UPDATE that updates all the foreign keys to null */ - protected String generateDeleteString() { + @Override + protected String generateDeleteString() { Update update = new Update( getDialect() ) .setTableName( qualifiedTableName ) .addColumns( keyColumnNames, "null" ) - .setPrimaryKeyColumnNames( keyColumnNames ); + .addPrimaryKeyColumns( keyColumnNames ); if ( hasIndex && !indexContainsFormula ) update.addColumns( indexColumnNames, "null" ); @@ -111,7 +118,8 @@ /** * Generate the SQL UPDATE that updates a foreign key to a value */ - protected String generateInsertRowString() { + @Override + protected String generateInsertRowString() { Update update = new Update( getDialect() ) .setTableName( qualifiedTableName ) @@ -124,22 +132,33 @@ update.setComment( "create one-to-many row " + getRole() ); } - return update.setPrimaryKeyColumnNames( elementColumnNames ) + return update.addPrimaryKeyColumns( elementColumnNames, elementColumnWriters ) .toStatementString(); } /** - * Not needed for one-to-many association + * Generate the SQL UPDATE that inserts a collection index */ - protected String generateUpdateRowString() { - return null; + @Override + protected String generateUpdateRowString() { + Update update = new Update( getDialect() ).setTableName( qualifiedTableName ); + update.addPrimaryKeyColumns( elementColumnNames, elementColumnIsSettable, elementColumnWriters ); + if ( hasIdentifier ) { + update.addPrimaryKeyColumns( new String[]{ identifierColumnName } ); + } + if ( hasIndex && !indexContainsFormula ) { + update.addColumns( indexColumnNames ); + } + + return update.toStatementString(); } /** * Generate the SQL UPDATE that updates a particular row's foreign * key to null */ - protected String generateDeleteRowString() { + @Override + protected String generateDeleteRowString() { Update update = new Update( getDialect() ) .setTableName( qualifiedTableName ) @@ -154,11 +173,113 @@ //use a combination of foreign key columns and pk columns, since //the ordering of removal and addition is not guaranteed when //a child moves from one parent to another - String[] rowSelectColumnNames = ArrayHelper.join(keyColumnNames, elementColumnNames); - return update.setPrimaryKeyColumnNames( rowSelectColumnNames ) + String[] rowSelectColumnNames = ArrayHelper.join( keyColumnNames, elementColumnNames ); + return update.addPrimaryKeyColumns( rowSelectColumnNames ) .toStatementString(); } + + @Override + public void recreate(PersistentCollection collection, Serializable id, SessionImplementor session) + throws HibernateException { + super.recreate( collection, id, session ); + writeIndex( collection, collection.entries( this ), id, 0, session ); + } + + @Override + public void insertRows(PersistentCollection collection, Serializable id, SessionImplementor session) + throws HibernateException { + super.insertRows( collection, id, session ); + writeIndex( collection, collection.entries( this ), id, 0, session ); + } + + @Override + protected void doProcessQueuedOps(PersistentCollection collection, Serializable id, + int nextIndex, SessionImplementor session) throws HibernateException { + writeIndex( collection, collection.queuedAdditionIterator(), id, nextIndex, session ); + } + + private void writeIndex(PersistentCollection collection, Iterator entries, Serializable id, + int nextIndex, SessionImplementor session) { + // If one-to-many and inverse, still need to create the index. See HHH-5732. + if ( isInverse && hasIndex && !indexContainsFormula ) { + try { + if ( entries.hasNext() ) { + Expectation expectation = Expectations.appropriateExpectation( getUpdateCheckStyle() ); + while ( entries.hasNext() ) { + final Object entry = entries.next(); + if ( entry != null && collection.entryExists( entry, nextIndex ) ) { + int offset = 1; + PreparedStatement st = null; + boolean callable = isUpdateCallable(); + boolean useBatch = expectation.canBeBatched(); + String sql = getSQLUpdateRowString(); + + if ( useBatch ) { + if ( recreateBatchKey == null ) { + recreateBatchKey = new BasicBatchKey( + getRole() + "#RECREATE", + expectation + ); + } + st = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getBatch( recreateBatchKey ) + .getBatchStatement( sql, callable ); + } + else { + st = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( sql, callable ); + } + + try { + offset += expectation.prepare( st ); + if ( hasIdentifier ) { + offset = writeIdentifier( st, collection.getIdentifier( entry, nextIndex ), offset, session ); + } + offset = writeIndex( st, collection.getIndex( entry, nextIndex, this ), offset, session ); + offset = writeElement( st, collection.getElement( entry ), offset, session ); + + if ( useBatch ) { + session.getTransactionCoordinator() + .getJdbcCoordinator() + .getBatch( recreateBatchKey ) + .addToBatch(); + } + else { + expectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 ); + } + } + catch ( SQLException sqle ) { + if ( useBatch ) { + session.getTransactionCoordinator().getJdbcCoordinator().abortBatch(); + } + throw sqle; + } + finally { + if ( !useBatch ) { + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); + } + } + + } + nextIndex++; + } + } + } + catch ( SQLException sqle ) { + throw sqlExceptionHelper.convert( + sqle, + "could not update collection: " + + MessageHelper.collectionInfoString( this, collection, id, session ), + getSQLUpdateRowString() + ); + } + } + } + public boolean consumesEntityAlias() { return true; } @@ -170,77 +291,95 @@ return true; } - public boolean isManyToMany() { + @Override + public boolean isManyToMany() { return false; } - protected int doUpdateRows(Serializable id, PersistentCollection collection, SessionImplementor session) - throws HibernateException { + private BasicBatchKey deleteRowBatchKey; + private BasicBatchKey insertRowBatchKey; + @Override + protected int doUpdateRows(Serializable id, PersistentCollection collection, SessionImplementor session) { + // we finish all the "removes" first to take care of possible unique // constraints and so that we can take better advantage of batching try { int count = 0; if ( isRowDeleteEnabled() ) { - boolean useBatch = true; + final Expectation deleteExpectation = Expectations.appropriateExpectation( getDeleteCheckStyle() ); + final boolean useBatch = deleteExpectation.canBeBatched(); + if ( useBatch && deleteRowBatchKey == null ) { + deleteRowBatchKey = new BasicBatchKey( + getRole() + "#DELETEROW", + deleteExpectation + ); + } + final String sql = getSQLDeleteRowString(); + PreparedStatement st = null; // update removed rows fks to null try { int i = 0; - Iterator entries = collection.entries( this ); int offset = 1; - Expectation expectation = Expectations.NONE; while ( entries.hasNext() ) { - Object entry = entries.next(); if ( collection.needsUpdating( entry, i, elementType ) ) { // will still be issued when it used to be null - if ( st == null ) { - String sql = getSQLDeleteRowString(); - if ( isDeleteCallable() ) { - expectation = Expectations.appropriateExpectation( getDeleteCheckStyle() ); - useBatch = expectation.canBeBatched(); - st = useBatch - ? session.getBatcher().prepareBatchCallableStatement( sql ) - : session.getBatcher().prepareCallableStatement( sql ); - offset += expectation.prepare( st ); - } - else { - st = session.getBatcher().prepareBatchStatement( getSQLDeleteRowString() ); - } + if ( useBatch ) { + st = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getBatch( deleteRowBatchKey ) + .getBatchStatement( sql, isDeleteCallable() ); } + else { + st = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( sql, isDeleteCallable() ); + } int loc = writeKey( st, id, offset, session ); writeElementToWhere( st, collection.getSnapshotElement(entry, i), loc, session ); if ( useBatch ) { - session.getBatcher().addToBatch( expectation ); + session.getTransactionCoordinator() + .getJdbcCoordinator() + .getBatch( deleteRowBatchKey ) + .addToBatch(); } else { - expectation.verifyOutcome( st.executeUpdate(), st, -1 ); + deleteExpectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 ); } count++; } i++; } } - catch ( SQLException sqle ) { + catch ( SQLException e ) { if ( useBatch ) { - session.getBatcher().abortBatch( sqle ); + session.getTransactionCoordinator().getJdbcCoordinator().abortBatch(); } - throw sqle; + throw e; } finally { if ( !useBatch ) { - session.getBatcher().closeStatement( st ); + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } } } if ( isRowInsertEnabled() ) { - Expectation expectation = Expectations.appropriateExpectation( getInsertCheckStyle() ); + final Expectation insertExpectation = Expectations.appropriateExpectation( getInsertCheckStyle() ); + boolean useBatch = insertExpectation.canBeBatched(); boolean callable = isInsertCallable(); - boolean useBatch = expectation.canBeBatched(); - String sql = getSQLInsertRowString(); + if ( useBatch && insertRowBatchKey == null ) { + insertRowBatchKey = new BasicBatchKey( + getRole() + "#INSERTROW", + insertExpectation + ); + } + final String sql = getSQLInsertRowString(); + PreparedStatement st = null; // now update all changed or added rows fks try { @@ -251,25 +390,19 @@ int offset = 1; if ( collection.needsUpdating( entry, i, elementType ) ) { if ( useBatch ) { - if ( st == null ) { - if ( callable ) { - st = session.getBatcher().prepareBatchCallableStatement( sql ); - } - else { - st = session.getBatcher().prepareBatchStatement( sql ); - } - } + st = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getBatch( insertRowBatchKey ) + .getBatchStatement( sql, callable ); } else { - if ( callable ) { - st = session.getBatcher().prepareCallableStatement( sql ); - } - else { - st = session.getBatcher().prepareStatement( sql ); - } + st = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( sql, callable ); } - offset += expectation.prepare( st ); + offset += insertExpectation.prepare( st ); int loc = writeKey( st, id, offset, session ); if ( hasIndex && !indexContainsFormula ) { @@ -279,10 +412,10 @@ writeElementToWhere( st, collection.getElement( entry ), loc, session ); if ( useBatch ) { - session.getBatcher().addToBatch( expectation ); + session.getTransactionCoordinator().getJdbcCoordinator().getBatch( insertRowBatchKey ).addToBatch(); } else { - expectation.verifyOutcome( st.executeUpdate(), st, -1 ); + insertExpectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 ); } count++; } @@ -291,25 +424,24 @@ } catch ( SQLException sqle ) { if ( useBatch ) { - session.getBatcher().abortBatch( sqle ); + session.getTransactionCoordinator().getJdbcCoordinator().abortBatch(); } throw sqle; } finally { if ( !useBatch ) { - session.getBatcher().closeStatement( st ); + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } } } return count; } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - getSQLExceptionConverter(), + throw getFactory().getSQLExceptionHelper().convert( sqle, "could not update collection rows: " + - MessageHelper.collectionInfoString( this, id, getFactory() ), + MessageHelper.collectionInfoString( this, collection, id, session ), getSQLInsertRowString() ); } @@ -322,7 +454,7 @@ String entitySuffix, String collectionSuffix, boolean includeCollectionColumns) { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); if ( includeCollectionColumns ) { // buf.append( selectFragment( lhsAlias, "" ) )//ignore suffix for collection columns! buf.append( selectFragment( lhsAlias, collectionSuffix ) ) @@ -338,27 +470,48 @@ * * @see org.hibernate.loader.collection.OneToManyLoader */ - protected CollectionInitializer createCollectionInitializer(java.util.Map enabledFilters) throws MappingException { - return BatchingCollectionInitializer.createBatchingOneToManyInitializer( this, batchSize, getFactory(), enabledFilters ); + @Override + protected CollectionInitializer createCollectionInitializer(LoadQueryInfluencers loadQueryInfluencers) + throws MappingException { + return BatchingCollectionInitializerBuilder.getBuilder( getFactory() ) + .createBatchingOneToManyInitializer( this, batchSize, getFactory(), loadQueryInfluencers ); } - public String fromJoinFragment(String alias, - boolean innerJoin, - boolean includeSubclasses) { - return ( ( Joinable ) getElementPersister() ).fromJoinFragment( alias, innerJoin, includeSubclasses ); + @Override + public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) { + return ( (Joinable) getElementPersister() ).fromJoinFragment( alias, innerJoin, includeSubclasses ); } - public String whereJoinFragment(String alias, - boolean innerJoin, - boolean includeSubclasses) { - return ( ( Joinable ) getElementPersister() ).whereJoinFragment( alias, innerJoin, includeSubclasses ); + @Override + public String fromJoinFragment( + String alias, + boolean innerJoin, + boolean includeSubclasses, + Set treatAsDeclarations) { + return ( (Joinable) getElementPersister() ).fromJoinFragment( alias, innerJoin, includeSubclasses, treatAsDeclarations ); } - public String getTableName() { - return ( ( Joinable ) getElementPersister() ).getTableName(); + @Override + public String whereJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) { + return ( (Joinable) getElementPersister() ).whereJoinFragment( alias, innerJoin, includeSubclasses ); } - public String filterFragment(String alias) throws MappingException { + @Override + public String whereJoinFragment( + String alias, + boolean innerJoin, + boolean includeSubclasses, + Set treatAsDeclarations) { + return ( (Joinable) getElementPersister() ).whereJoinFragment( alias, innerJoin, includeSubclasses, treatAsDeclarations ); + } + + @Override + public String getTableName() { + return ( (Joinable) getElementPersister() ).getTableName(); + } + + @Override + public String filterFragment(String alias) throws MappingException { String result = super.filterFragment( alias ); if ( getElementPersister() instanceof Joinable ) { result += ( ( Joinable ) getElementPersister() ).oneToManyFilterFragment( alias ); @@ -367,21 +520,37 @@ } - protected CollectionInitializer createSubselectInitializer(SubselectFetch subselect, SessionImplementor session) { + @Override + protected String filterFragment(String alias, Set treatAsDeclarations) throws MappingException { + String result = super.filterFragment( alias ); + if ( getElementPersister() instanceof Joinable ) { + result += ( ( Joinable ) getElementPersister() ).oneToManyFilterFragment( alias, treatAsDeclarations ); + } + return result; + } + + @Override + protected CollectionInitializer createSubselectInitializer(SubselectFetch subselect, SessionImplementor session) { return new SubselectOneToManyLoader( this, subselect.toSubselectString( getCollectionType().getLHSPropertyName() ), subselect.getResult(), subselect.getQueryParameters(), subselect.getNamedParameterLocMap(), session.getFactory(), - session.getEnabledFilters() + session.getLoadQueryInfluencers() ); } - public Object getElementByIndex(Serializable key, Object index, SessionImplementor session, Object owner) { - return new CollectionElementLoader( this, getFactory(), session.getEnabledFilters() ) + @Override + public Object getElementByIndex(Serializable key, Object index, SessionImplementor session, Object owner) { + return new CollectionElementLoader( this, getFactory(), session.getLoadQueryInfluencers() ) .loadElement( session, key, incrementIndexByBase(index) ); } + @Override + public FilterAliasGenerator getFilterAliasGenerator(String rootAlias) { + return getElementPersister().getFilterAliasGenerator(rootAlias); + } + } Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/QueryableCollection.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/collection/QueryableCollection.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/QueryableCollection.java 17 Aug 2012 14:33:55 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/QueryableCollection.java 30 Jul 2014 16:16:07 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.persister.collection; - import org.hibernate.FetchMode; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Joinable; Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/SQLLoadableCollection.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/collection/SQLLoadableCollection.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/SQLLoadableCollection.java 17 Aug 2012 14:33:55 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/collection/SQLLoadableCollection.java 30 Jul 2014 16:16:07 -0000 1.1.2.1 @@ -24,6 +24,7 @@ */ package org.hibernate.persister.collection; + public interface SQLLoadableCollection extends QueryableCollection { public abstract String[] getCollectionPropertyColumnAliases(String propertyName, String string); Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/AbstractEntityPersister.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/entity/AbstractEntityPersister.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/AbstractEntityPersister.java 17 Aug 2012 14:33:33 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/AbstractEntityPersister.java 30 Jul 2014 16:16:32 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.persister.entity; @@ -30,55 +29,73 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Set; -import java.util.Comparator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.AssertionFailure; import org.hibernate.EntityMode; import org.hibernate.FetchMode; import org.hibernate.HibernateException; import org.hibernate.LockMode; +import org.hibernate.LockOptions; import org.hibernate.MappingException; import org.hibernate.QueryException; +import org.hibernate.Session; import org.hibernate.StaleObjectStateException; import org.hibernate.StaleStateException; -import org.hibernate.jdbc.Expectation; -import org.hibernate.jdbc.Expectations; -import org.hibernate.jdbc.TooManyRowsAffectedException; +import org.hibernate.bytecode.instrumentation.spi.FieldInterceptor; +import org.hibernate.bytecode.instrumentation.spi.LazyPropertyInitializer; +import org.hibernate.bytecode.spi.EntityInstrumentationMetadata; +import org.hibernate.cache.spi.CacheKey; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; +import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; +import org.hibernate.cache.spi.entry.CacheEntry; +import org.hibernate.cache.spi.entry.CacheEntryStructure; +import org.hibernate.cache.spi.entry.ReferenceCacheEntryImpl; +import org.hibernate.cache.spi.entry.StandardCacheEntryImpl; +import org.hibernate.cache.spi.entry.StructuredCacheEntry; +import org.hibernate.cache.spi.entry.UnstructuredCacheEntry; import org.hibernate.dialect.lock.LockingStrategy; -import org.hibernate.cache.CacheConcurrencyStrategy; -import org.hibernate.cache.CacheKey; -import org.hibernate.cache.access.EntityRegionAccessStrategy; -import org.hibernate.cache.entry.CacheEntry; -import org.hibernate.cache.entry.CacheEntryStructure; -import org.hibernate.cache.entry.StructuredCacheEntry; -import org.hibernate.cache.entry.UnstructuredCacheEntry; -import org.hibernate.engine.CascadeStyle; -import org.hibernate.engine.CascadingAction; -import org.hibernate.engine.EntityEntry; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.engine.Versioning; -import org.hibernate.engine.ExecuteUpdateResultCheckStyle; -import org.hibernate.engine.EntityKey; -import org.hibernate.engine.ValueInclusion; -import org.hibernate.exception.JDBCExceptionHelper; +import org.hibernate.engine.OptimisticLockStyle; +import org.hibernate.engine.internal.CacheHelper; +import org.hibernate.engine.internal.StatefulPersistenceContext; +import org.hibernate.engine.internal.Versioning; +import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; +import org.hibernate.engine.spi.CachedNaturalIdValueSource; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.CascadeStyles; +import org.hibernate.engine.spi.CascadingActions; +import org.hibernate.engine.spi.EntityEntry; +import org.hibernate.engine.spi.EntityKey; +import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle; +import org.hibernate.engine.spi.FilterDefinition; +import org.hibernate.engine.spi.LoadQueryInfluencers; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.PersistenceContext.NaturalIdHelper; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.engine.spi.ValueInclusion; import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.PostInsertIdentifierGenerator; import org.hibernate.id.PostInsertIdentityPersister; -import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate; import org.hibernate.id.insert.Binder; -import org.hibernate.intercept.LazyPropertyInitializer; -import org.hibernate.intercept.FieldInterceptionHelper; -import org.hibernate.intercept.FieldInterceptor; -import org.hibernate.loader.entity.BatchingEntityLoader; +import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.FilterConfiguration; +import org.hibernate.internal.FilterHelper; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.jdbc.Expectation; +import org.hibernate.jdbc.Expectations; +import org.hibernate.jdbc.TooManyRowsAffectedException; +import org.hibernate.loader.entity.BatchingEntityLoaderBuilder; import org.hibernate.loader.entity.CascadeEntityLoader; import org.hibernate.loader.entity.EntityLoader; import org.hibernate.loader.entity.UniqueEntityLoader; @@ -88,31 +105,44 @@ import org.hibernate.mapping.Property; import org.hibernate.mapping.Selectable; import org.hibernate.metadata.ClassMetadata; +import org.hibernate.metamodel.binding.AssociationAttributeBinding; +import org.hibernate.metamodel.binding.AttributeBinding; +import org.hibernate.metamodel.binding.EntityBinding; +import org.hibernate.metamodel.binding.SimpleValueBinding; +import org.hibernate.metamodel.binding.SingularAttributeBinding; +import org.hibernate.metamodel.relational.DerivedValue; +import org.hibernate.metamodel.relational.Value; +import org.hibernate.persister.walking.internal.EntityIdentifierDefinitionHelper; +import org.hibernate.persister.walking.spi.AttributeDefinition; +import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; import org.hibernate.pretty.MessageHelper; import org.hibernate.property.BackrefPropertyAccessor; import org.hibernate.sql.Alias; import org.hibernate.sql.Delete; import org.hibernate.sql.Insert; import org.hibernate.sql.JoinFragment; +import org.hibernate.sql.JoinType; import org.hibernate.sql.Select; import org.hibernate.sql.SelectFragment; import org.hibernate.sql.SimpleSelect; import org.hibernate.sql.Template; import org.hibernate.sql.Update; +import org.hibernate.tuple.GenerationTiming; +import org.hibernate.tuple.InDatabaseValueGenerationStrategy; +import org.hibernate.tuple.InMemoryValueGenerationStrategy; +import org.hibernate.tuple.NonIdentifierAttribute; +import org.hibernate.tuple.ValueGeneration; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; -import org.hibernate.tuple.Tuplizer; -import org.hibernate.type.AbstractComponentType; import org.hibernate.type.AssociationType; +import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; -import org.hibernate.type.TypeFactory; +import org.hibernate.type.TypeHelper; import org.hibernate.type.VersionType; -import org.hibernate.util.ArrayHelper; -import org.hibernate.util.CollectionHelper; -import org.hibernate.util.FilterHelper; -import org.hibernate.util.StringHelper; +import org.jboss.logging.Logger; + /** * Basic functionality for persisting an entity via JDBC * through either generated or custom SQL @@ -123,20 +153,23 @@ implements OuterJoinLoadable, Queryable, ClassMetadata, UniqueKeyLoadable, SQLLoadable, LazyPropertyInitializer, PostInsertIdentityPersister, Lockable { - private static final Logger log = LoggerFactory.getLogger( AbstractEntityPersister.class ); + private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, AbstractEntityPersister.class.getName() ); public static final String ENTITY_CLASS = "class"; // moved up from AbstractEntityPersister ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private final SessionFactoryImplementor factory; private final EntityRegionAccessStrategy cacheAccessStrategy; + private final NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy; private final boolean isLazyPropertiesCacheable; - private final CacheEntryStructure cacheEntryStructure; + private final CacheEntryHelper cacheEntryHelper; private final EntityMetamodel entityMetamodel; - private final Map entityNameBySubclass = new HashMap(); + private final EntityTuplizer entityTuplizer; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private final String[] rootTableKeyColumnNames; + private final String[] rootTableKeyColumnReaders; + private final String[] rootTableKeyColumnReaderTemplates; private final String[] identifierAliases; private final int identifierColumnSpan; private final String versionColumnName; @@ -159,10 +192,14 @@ private final String[][] propertyColumnAliases; private final String[][] propertyColumnNames; private final String[][] propertyColumnFormulaTemplates; + private final String[][] propertyColumnReaderTemplates; + private final String[][] propertyColumnWriters; private final boolean[][] propertyColumnUpdateable; private final boolean[][] propertyColumnInsertable; private final boolean[] propertyUniqueness; private final boolean[] propertySelectable; + + private final List lobProperties = new ArrayList(); //information about lazy properties of this class private final String[] lazyPropertyNames; @@ -176,6 +213,8 @@ private final Type[] subclassPropertyTypeClosure; private final String[][] subclassPropertyFormulaTemplateClosure; private final String[][] subclassPropertyColumnNameClosure; + private final String[][] subclassPropertyColumnReaderClosure; + private final String[][] subclassPropertyColumnReaderTemplateClosure; private final FetchMode[] subclassPropertyFetchModeClosure; private final boolean[] subclassPropertyNullabilityClosure; private final boolean[] propertyDefinedOnSubclass; @@ -188,6 +227,7 @@ private final boolean[] subclassColumnLazyClosure; private final String[] subclassColumnAliasClosure; private final boolean[] subclassColumnSelectableClosure; + private final String[] subclassColumnReaderTemplateClosure; private final String[] subclassFormulaClosure; private final String[] subclassFormulaTemplateClosure; private final String[] subclassFormulaAliasClosure; @@ -196,6 +236,8 @@ // dynamic filters attached to the class-level private final FilterHelper filterHelper; + private final Set affectingFetchProfileNames = new HashSet(); + private final Map uniqueKeyLoaders = new HashMap(); private final Map lockers = new HashMap(); private final Map loaders = new HashMap(); @@ -278,12 +320,22 @@ protected abstract String filterFragment(String alias) throws MappingException; + protected abstract String filterFragment(String alias, Set treatAsDeclarations); + private static final String DISCRIMINATOR_ALIAS = "clazz_"; public String getDiscriminatorColumnName() { return DISCRIMINATOR_ALIAS; } + public String getDiscriminatorColumnReaders() { + return DISCRIMINATOR_ALIAS; + } + + public String getDiscriminatorColumnReaderTemplate() { + return DISCRIMINATOR_ALIAS; + } + protected String getDiscriminatorAlias() { return DISCRIMINATOR_ALIAS; } @@ -368,7 +420,7 @@ /** * The query that inserts a row, letting the database generate an id - * + * * @return The IDENTITY-based insertion query. */ protected String getSQLIdentityInsertString() { @@ -441,29 +493,32 @@ return rowIdName != null; } + protected boolean[][] getPropertyColumnUpdateable() { + return propertyColumnUpdateable; + } + + protected boolean[][] getPropertyColumnInsertable() { + return propertyColumnInsertable; + } + + protected boolean[] getPropertySelectable() { + return propertySelectable; + } + public AbstractEntityPersister( final PersistentClass persistentClass, final EntityRegionAccessStrategy cacheAccessStrategy, + final NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy, final SessionFactoryImplementor factory) throws HibernateException { // moved up from AbstractEntityPersister ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ this.factory = factory; this.cacheAccessStrategy = cacheAccessStrategy; + this.naturalIdRegionAccessStrategy = naturalIdRegionAccessStrategy; isLazyPropertiesCacheable = persistentClass.isLazyPropertiesCacheable(); - this.cacheEntryStructure = factory.getSettings().isStructuredCacheEntriesEnabled() ? - (CacheEntryStructure) new StructuredCacheEntry(this) : - (CacheEntryStructure) new UnstructuredCacheEntry(); - this.entityMetamodel = new EntityMetamodel( persistentClass, factory ); - - if ( persistentClass.hasPojoRepresentation() ) { - //TODO: this is currently specific to pojos, but need to be available for all entity-modes - Iterator iter = persistentClass.getSubclassIterator(); - while ( iter.hasNext() ) { - PersistentClass pc = ( PersistentClass ) iter.next(); - entityNameBySubclass.put( pc.getMappedClass(), pc.getEntityName() ); - } - } + this.entityMetamodel = new EntityMetamodel( persistentClass, this, factory ); + this.entityTuplizer = this.entityMetamodel.getTuplizer(); // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int batch = persistentClass.getBatchSize(); @@ -479,6 +534,8 @@ identifierColumnSpan = persistentClass.getIdentifier().getColumnSpan(); rootTableKeyColumnNames = new String[identifierColumnSpan]; + rootTableKeyColumnReaders = new String[identifierColumnSpan]; + rootTableKeyColumnReaderTemplates = new String[identifierColumnSpan]; identifierAliases = new String[identifierColumnSpan]; rowIdName = persistentClass.getRootTable().getRowId(); @@ -490,6 +547,8 @@ while ( iter.hasNext() ) { Column col = ( Column ) iter.next(); rootTableKeyColumnNames[i] = col.getQuotedName( factory.getDialect() ); + rootTableKeyColumnReaders[i] = col.getReadExpr( factory.getDialect() ); + rootTableKeyColumnReaderTemplates[i] = col.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() ); identifierAliases[i] = col.getAlias( factory.getDialect(), persistentClass.getRootTable() ); i++; } @@ -512,14 +571,16 @@ // PROPERTIES - final boolean lazyAvailable = isInstrumented(EntityMode.POJO); + final boolean lazyAvailable = isInstrumented(); int hydrateSpan = entityMetamodel.getPropertySpan(); propertyColumnSpans = new int[hydrateSpan]; propertySubclassNames = new String[hydrateSpan]; propertyColumnAliases = new String[hydrateSpan][]; propertyColumnNames = new String[hydrateSpan][]; propertyColumnFormulaTemplates = new String[hydrateSpan][]; + propertyColumnReaderTemplates = new String[hydrateSpan][]; + propertyColumnWriters = new String[hydrateSpan][]; propertyUniqueness = new boolean[hydrateSpan]; propertySelectable = new boolean[hydrateSpan]; propertyColumnUpdateable = new boolean[hydrateSpan][]; @@ -544,29 +605,36 @@ propertySubclassNames[i] = prop.getPersistentClass().getEntityName(); String[] colNames = new String[span]; String[] colAliases = new String[span]; - String[] templates = new String[span]; + String[] colReaderTemplates = new String[span]; + String[] colWriters = new String[span]; + String[] formulaTemplates = new String[span]; Iterator colIter = prop.getColumnIterator(); int k = 0; while ( colIter.hasNext() ) { Selectable thing = ( Selectable ) colIter.next(); colAliases[k] = thing.getAlias( factory.getDialect() , prop.getValue().getTable() ); if ( thing.isFormula() ) { foundFormula = true; - templates[k] = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() ); + formulaTemplates[k] = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() ); } else { - colNames[k] = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() ); + Column col = (Column)thing; + colNames[k] = col.getQuotedName( factory.getDialect() ); + colReaderTemplates[k] = col.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() ); + colWriters[k] = col.getWriteExpr(); } k++; } propertyColumnNames[i] = colNames; - propertyColumnFormulaTemplates[i] = templates; + propertyColumnFormulaTemplates[i] = formulaTemplates; + propertyColumnReaderTemplates[i] = colReaderTemplates; + propertyColumnWriters[i] = colWriters; propertyColumnAliases[i] = colAliases; if ( lazyAvailable && prop.isLazy() ) { lazyProperties.add( prop.getName() ); lazyNames.add( prop.getName() ); - lazyNumbers.add( new Integer( i ) ); + lazyNumbers.add( i ); lazyTypes.add( prop.getValue().getType() ); lazyColAliases.add( colAliases ); } @@ -577,6 +645,10 @@ propertySelectable[i] = prop.isSelectable(); propertyUniqueness[i] = prop.getValue().isAlternateUniqueKey(); + + if (prop.isLob() && getFactory().getDialect().forceLobAsLastValue() ) { + lobProperties.add( i ); + } i++; @@ -591,6 +663,7 @@ ArrayList columns = new ArrayList(); ArrayList columnsLazy = new ArrayList(); + ArrayList columnReaderTemplates = new ArrayList(); ArrayList aliases = new ArrayList(); ArrayList formulas = new ArrayList(); ArrayList formulaAliases = new ArrayList(); @@ -601,6 +674,8 @@ ArrayList classes = new ArrayList(); ArrayList templates = new ArrayList(); ArrayList propColumns = new ArrayList(); + ArrayList propColumnReaders = new ArrayList(); + ArrayList propColumnReaderTemplates = new ArrayList(); ArrayList joinedFetchesList = new ArrayList(); ArrayList cascades = new ArrayList(); ArrayList definedBySubclass = new ArrayList(); @@ -621,6 +696,8 @@ Iterator colIter = prop.getColumnIterator(); String[] cols = new String[prop.getColumnSpan()]; + String[] readers = new String[prop.getColumnSpan()]; + String[] readerTemplates = new String[prop.getColumnSpan()]; String[] forms = new String[prop.getColumnSpan()]; int[] colnos = new int[prop.getColumnSpan()]; int[] formnos = new int[prop.getColumnSpan()]; @@ -639,18 +716,26 @@ formulasLazy.add( lazy ); } else { - String colName = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() ); + Column col = (Column)thing; + String colName = col.getQuotedName( factory.getDialect() ); colnos[l] = columns.size(); //before add :-) formnos[l] = -1; columns.add( colName ); cols[l] = colName; aliases.add( thing.getAlias( factory.getDialect(), prop.getValue().getTable() ) ); columnsLazy.add( lazy ); columnSelectables.add( Boolean.valueOf( prop.isSelectable() ) ); + + readers[l] = col.getReadExpr( factory.getDialect() ); + String readerTemplate = col.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() ); + readerTemplates[l] = readerTemplate; + columnReaderTemplates.add( readerTemplate ); } l++; } propColumns.add( cols ); + propColumnReaders.add( readers ); + propColumnReaderTemplates.add( readerTemplates ); templates.add( forms ); propColumnNumbers.add( colnos ); propFormulaNumbers.add( formnos ); @@ -662,6 +747,7 @@ subclassColumnAliasClosure = ArrayHelper.toStringArray( aliases ); subclassColumnLazyClosure = ArrayHelper.toBooleanArray( columnsLazy ); subclassColumnSelectableClosure = ArrayHelper.toBooleanArray( columnSelectables ); + subclassColumnReaderTemplateClosure = ArrayHelper.toStringArray( columnReaderTemplates ); subclassFormulaClosure = ArrayHelper.toStringArray( formulas ); subclassFormulaTemplateClosure = ArrayHelper.toStringArray( formulaTemplates ); @@ -674,6 +760,8 @@ subclassPropertyNullabilityClosure = ArrayHelper.toBooleanArray( propNullables ); subclassPropertyFormulaTemplateClosure = ArrayHelper.to2DStringArray( templates ); subclassPropertyColumnNameClosure = ArrayHelper.to2DStringArray( propColumns ); + subclassPropertyColumnReaderClosure = ArrayHelper.to2DStringArray( propColumnReaders ); + subclassPropertyColumnReaderTemplateClosure = ArrayHelper.to2DStringArray( propColumnReaderTemplates ); subclassPropertyColumnNumberClosure = ArrayHelper.to2DIntArray( propColumnNumbers ); subclassPropertyFormulaNumberClosure = ArrayHelper.to2DIntArray( propFormulaNumbers ); @@ -694,16 +782,400 @@ iter = definedBySubclass.iterator(); j = 0; while ( iter.hasNext() ) { - propertyDefinedOnSubclass[j++] = ( ( Boolean ) iter.next() ).booleanValue(); + propertyDefinedOnSubclass[j++] = (Boolean) iter.next(); } // Handle any filters applied to the class level - filterHelper = new FilterHelper( persistentClass.getFilterMap(), factory.getDialect(), factory.getSqlFunctionRegistry() ); + filterHelper = new FilterHelper( persistentClass.getFilters(), factory ); temporaryIdTableName = persistentClass.getTemporaryIdTableName(); temporaryIdTableDDL = persistentClass.getTemporaryIdTableDDL(); + + this.cacheEntryHelper = buildCacheEntryHelper(); } + protected CacheEntryHelper buildCacheEntryHelper() { + if ( cacheAccessStrategy == null ) { + // the entity defined no caching... + return NoopCacheEntryHelper.INSTANCE; + } + + if ( canUseReferenceCacheEntries() ) { + entityMetamodel.setLazy( false ); + // todo : do we also need to unset proxy factory? + return new ReferenceCacheEntryHelper( this ); + } + + return factory.getSettings().isStructuredCacheEntriesEnabled() + ? new StructuredCacheEntryHelper( this ) + : new StandardCacheEntryHelper( this ); + } + + public boolean canUseReferenceCacheEntries() { + // todo : should really validate that the cache access type is read-only + + if ( ! factory.getSettings().isDirectReferenceCacheEntriesEnabled() ) { + return false; + } + + // for now, limit this to just entities that: + // 1) are immutable + if ( entityMetamodel.isMutable() ) { + return false; + } + + // 2) have no associations. Eventually we want to be a little more lenient with associations. + for ( Type type : getSubclassPropertyTypeClosure() ) { + if ( type.isAssociationType() ) { + return false; + } + } + + return true; + } + + + public AbstractEntityPersister( + final EntityBinding entityBinding, + final EntityRegionAccessStrategy cacheAccessStrategy, + final NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy, + final SessionFactoryImplementor factory) throws HibernateException { + this.factory = factory; + this.cacheAccessStrategy = cacheAccessStrategy; + this.naturalIdRegionAccessStrategy = naturalIdRegionAccessStrategy; + this.isLazyPropertiesCacheable = + entityBinding.getHierarchyDetails().getCaching() == null ? + false : + entityBinding.getHierarchyDetails().getCaching().isCacheLazyProperties(); + this.entityMetamodel = new EntityMetamodel( entityBinding, this, factory ); + this.entityTuplizer = this.entityMetamodel.getTuplizer(); + int batch = entityBinding.getBatchSize(); + if ( batch == -1 ) { + batch = factory.getSettings().getDefaultBatchFetchSize(); + } + batchSize = batch; + hasSubselectLoadableCollections = entityBinding.hasSubselectLoadableCollections(); + + propertyMapping = new BasicEntityPropertyMapping( this ); + + // IDENTIFIER + + identifierColumnSpan = entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding().getSimpleValueSpan(); + rootTableKeyColumnNames = new String[identifierColumnSpan]; + rootTableKeyColumnReaders = new String[identifierColumnSpan]; + rootTableKeyColumnReaderTemplates = new String[identifierColumnSpan]; + identifierAliases = new String[identifierColumnSpan]; + + rowIdName = entityBinding.getRowId(); + + loaderName = entityBinding.getCustomLoaderName(); + + int i = 0; + for ( org.hibernate.metamodel.relational.Column col : entityBinding.getPrimaryTable().getPrimaryKey().getColumns() ) { + rootTableKeyColumnNames[i] = col.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() ); + if ( col.getReadFragment() == null ) { + rootTableKeyColumnReaders[i] = rootTableKeyColumnNames[i]; + rootTableKeyColumnReaderTemplates[i] = getTemplateFromColumn( col, factory ); + } + else { + rootTableKeyColumnReaders[i] = col.getReadFragment(); + rootTableKeyColumnReaderTemplates[i] = getTemplateFromString( rootTableKeyColumnReaders[i], factory ); + } + identifierAliases[i] = col.getAlias( factory.getDialect() ); + i++; + } + + // VERSION + + if ( entityBinding.isVersioned() ) { + final Value versioningValue = entityBinding.getHierarchyDetails().getVersioningAttributeBinding().getValue(); + if ( ! org.hibernate.metamodel.relational.Column.class.isInstance( versioningValue ) ) { + throw new AssertionFailure( "Bad versioning attribute binding : " + versioningValue ); + } + org.hibernate.metamodel.relational.Column versionColumn = org.hibernate.metamodel.relational.Column.class.cast( versioningValue ); + versionColumnName = versionColumn.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() ); + } + else { + versionColumnName = null; + } + + //WHERE STRING + + sqlWhereString = StringHelper.isNotEmpty( entityBinding.getWhereFilter() ) ? "( " + entityBinding.getWhereFilter() + ") " : null; + sqlWhereStringTemplate = getTemplateFromString( sqlWhereString, factory ); + + // PROPERTIES + + final boolean lazyAvailable = isInstrumented(); + + int hydrateSpan = entityMetamodel.getPropertySpan(); + propertyColumnSpans = new int[hydrateSpan]; + propertySubclassNames = new String[hydrateSpan]; + propertyColumnAliases = new String[hydrateSpan][]; + propertyColumnNames = new String[hydrateSpan][]; + propertyColumnFormulaTemplates = new String[hydrateSpan][]; + propertyColumnReaderTemplates = new String[hydrateSpan][]; + propertyColumnWriters = new String[hydrateSpan][]; + propertyUniqueness = new boolean[hydrateSpan]; + propertySelectable = new boolean[hydrateSpan]; + propertyColumnUpdateable = new boolean[hydrateSpan][]; + propertyColumnInsertable = new boolean[hydrateSpan][]; + HashSet thisClassProperties = new HashSet(); + + lazyProperties = new HashSet(); + ArrayList lazyNames = new ArrayList(); + ArrayList lazyNumbers = new ArrayList(); + ArrayList lazyTypes = new ArrayList(); + ArrayList lazyColAliases = new ArrayList(); + + i = 0; + boolean foundFormula = false; + for ( AttributeBinding attributeBinding : entityBinding.getAttributeBindingClosure() ) { + if ( attributeBinding == entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() ) { + // entity identifier is not considered a "normal" property + continue; + } + + if ( ! attributeBinding.getAttribute().isSingular() ) { + // collections handled separately + continue; + } + + final SingularAttributeBinding singularAttributeBinding = (SingularAttributeBinding) attributeBinding; + + thisClassProperties.add( singularAttributeBinding ); + + propertySubclassNames[i] = ( (EntityBinding) singularAttributeBinding.getContainer() ).getEntity().getName(); + + int span = singularAttributeBinding.getSimpleValueSpan(); + propertyColumnSpans[i] = span; + + String[] colNames = new String[span]; + String[] colAliases = new String[span]; + String[] colReaderTemplates = new String[span]; + String[] colWriters = new String[span]; + String[] formulaTemplates = new String[span]; + boolean[] propertyColumnInsertability = new boolean[span]; + boolean[] propertyColumnUpdatability = new boolean[span]; + + int k = 0; + + for ( SimpleValueBinding valueBinding : singularAttributeBinding.getSimpleValueBindings() ) { + colAliases[k] = valueBinding.getSimpleValue().getAlias( factory.getDialect() ); + if ( valueBinding.isDerived() ) { + foundFormula = true; + formulaTemplates[ k ] = getTemplateFromString( ( (DerivedValue) valueBinding.getSimpleValue() ).getExpression(), factory ); + } + else { + org.hibernate.metamodel.relational.Column col = ( org.hibernate.metamodel.relational.Column ) valueBinding.getSimpleValue(); + colNames[k] = col.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() ); + colReaderTemplates[k] = getTemplateFromColumn( col, factory ); + colWriters[k] = col.getWriteFragment() == null ? "?" : col.getWriteFragment(); + } + propertyColumnInsertability[k] = valueBinding.isIncludeInInsert(); + propertyColumnUpdatability[k] = valueBinding.isIncludeInUpdate(); + k++; + } + propertyColumnNames[i] = colNames; + propertyColumnFormulaTemplates[i] = formulaTemplates; + propertyColumnReaderTemplates[i] = colReaderTemplates; + propertyColumnWriters[i] = colWriters; + propertyColumnAliases[i] = colAliases; + + propertyColumnUpdateable[i] = propertyColumnUpdatability; + propertyColumnInsertable[i] = propertyColumnInsertability; + + if ( lazyAvailable && singularAttributeBinding.isLazy() ) { + lazyProperties.add( singularAttributeBinding.getAttribute().getName() ); + lazyNames.add( singularAttributeBinding.getAttribute().getName() ); + lazyNumbers.add( i ); + lazyTypes.add( singularAttributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping()); + lazyColAliases.add( colAliases ); + } + + + // TODO: fix this when backrefs are working + //propertySelectable[i] = singularAttributeBinding.isBackRef(); + propertySelectable[i] = true; + + propertyUniqueness[i] = singularAttributeBinding.isAlternateUniqueKey(); + + // TODO: Does this need AttributeBindings wired into lobProperties? Currently in Property only. + + i++; + + } + hasFormulaProperties = foundFormula; + lazyPropertyColumnAliases = ArrayHelper.to2DStringArray( lazyColAliases ); + lazyPropertyNames = ArrayHelper.toStringArray( lazyNames ); + lazyPropertyNumbers = ArrayHelper.toIntArray( lazyNumbers ); + lazyPropertyTypes = ArrayHelper.toTypeArray( lazyTypes ); + + // SUBCLASS PROPERTY CLOSURE + + List columns = new ArrayList(); + List columnsLazy = new ArrayList(); + List columnReaderTemplates = new ArrayList(); + List aliases = new ArrayList(); + List formulas = new ArrayList(); + List formulaAliases = new ArrayList(); + List formulaTemplates = new ArrayList(); + List formulasLazy = new ArrayList(); + List types = new ArrayList(); + List names = new ArrayList(); + List classes = new ArrayList(); + List templates = new ArrayList(); + List propColumns = new ArrayList(); + List propColumnReaders = new ArrayList(); + List propColumnReaderTemplates = new ArrayList(); + List joinedFetchesList = new ArrayList(); + List cascades = new ArrayList(); + List definedBySubclass = new ArrayList(); + List propColumnNumbers = new ArrayList(); + List propFormulaNumbers = new ArrayList(); + List columnSelectables = new ArrayList(); + List propNullables = new ArrayList(); + + for ( AttributeBinding attributeBinding : entityBinding.getSubEntityAttributeBindingClosure() ) { + if ( attributeBinding == entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() ) { + // entity identifier is not considered a "normal" property + continue; + } + + if ( ! attributeBinding.getAttribute().isSingular() ) { + // collections handled separately + continue; + } + + final SingularAttributeBinding singularAttributeBinding = (SingularAttributeBinding) attributeBinding; + + names.add( singularAttributeBinding.getAttribute().getName() ); + classes.add( ( (EntityBinding) singularAttributeBinding.getContainer() ).getEntity().getName() ); + boolean isDefinedBySubclass = ! thisClassProperties.contains( singularAttributeBinding ); + definedBySubclass.add( isDefinedBySubclass ); + propNullables.add( singularAttributeBinding.isNullable() || isDefinedBySubclass ); //TODO: is this completely correct? + types.add( singularAttributeBinding.getHibernateTypeDescriptor().getResolvedTypeMapping() ); + + final int span = singularAttributeBinding.getSimpleValueSpan(); + String[] cols = new String[ span ]; + String[] readers = new String[ span ]; + String[] readerTemplates = new String[ span ]; + String[] forms = new String[ span ]; + int[] colnos = new int[ span ]; + int[] formnos = new int[ span ]; + int l = 0; + Boolean lazy = singularAttributeBinding.isLazy() && lazyAvailable; + for ( SimpleValueBinding valueBinding : singularAttributeBinding.getSimpleValueBindings() ) { + if ( valueBinding.isDerived() ) { + DerivedValue derivedValue = DerivedValue.class.cast( valueBinding.getSimpleValue() ); + String template = getTemplateFromString( derivedValue.getExpression(), factory ); + formnos[l] = formulaTemplates.size(); + colnos[l] = -1; + formulaTemplates.add( template ); + forms[l] = template; + formulas.add( derivedValue.getExpression() ); + formulaAliases.add( derivedValue.getAlias( factory.getDialect() ) ); + formulasLazy.add( lazy ); + } + else { + org.hibernate.metamodel.relational.Column col = org.hibernate.metamodel.relational.Column.class.cast( valueBinding.getSimpleValue() ); + String colName = col.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() ); + colnos[l] = columns.size(); //before add :-) + formnos[l] = -1; + columns.add( colName ); + cols[l] = colName; + aliases.add( col.getAlias( factory.getDialect() ) ); + columnsLazy.add( lazy ); + // TODO: properties only selectable if they are non-plural??? + columnSelectables.add( singularAttributeBinding.getAttribute().isSingular() ); + + readers[l] = + col.getReadFragment() == null ? + col.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() ) : + col.getReadFragment(); + String readerTemplate = getTemplateFromColumn( col, factory ); + readerTemplates[l] = readerTemplate; + columnReaderTemplates.add( readerTemplate ); + } + l++; + } + propColumns.add( cols ); + propColumnReaders.add( readers ); + propColumnReaderTemplates.add( readerTemplates ); + templates.add( forms ); + propColumnNumbers.add( colnos ); + propFormulaNumbers.add( formnos ); + + if ( singularAttributeBinding.isAssociation() ) { + AssociationAttributeBinding associationAttributeBinding = + ( AssociationAttributeBinding ) singularAttributeBinding; + cascades.add( associationAttributeBinding.getCascadeStyle() ); + joinedFetchesList.add( associationAttributeBinding.getFetchMode() ); + } + else { + cascades.add( CascadeStyles.NONE ); + joinedFetchesList.add( FetchMode.SELECT ); + } + } + + subclassColumnClosure = ArrayHelper.toStringArray( columns ); + subclassColumnAliasClosure = ArrayHelper.toStringArray( aliases ); + subclassColumnLazyClosure = ArrayHelper.toBooleanArray( columnsLazy ); + subclassColumnSelectableClosure = ArrayHelper.toBooleanArray( columnSelectables ); + subclassColumnReaderTemplateClosure = ArrayHelper.toStringArray( columnReaderTemplates ); + + subclassFormulaClosure = ArrayHelper.toStringArray( formulas ); + subclassFormulaTemplateClosure = ArrayHelper.toStringArray( formulaTemplates ); + subclassFormulaAliasClosure = ArrayHelper.toStringArray( formulaAliases ); + subclassFormulaLazyClosure = ArrayHelper.toBooleanArray( formulasLazy ); + + subclassPropertyNameClosure = ArrayHelper.toStringArray( names ); + subclassPropertySubclassNameClosure = ArrayHelper.toStringArray( classes ); + subclassPropertyTypeClosure = ArrayHelper.toTypeArray( types ); + subclassPropertyNullabilityClosure = ArrayHelper.toBooleanArray( propNullables ); + subclassPropertyFormulaTemplateClosure = ArrayHelper.to2DStringArray( templates ); + subclassPropertyColumnNameClosure = ArrayHelper.to2DStringArray( propColumns ); + subclassPropertyColumnReaderClosure = ArrayHelper.to2DStringArray( propColumnReaders ); + subclassPropertyColumnReaderTemplateClosure = ArrayHelper.to2DStringArray( propColumnReaderTemplates ); + subclassPropertyColumnNumberClosure = ArrayHelper.to2DIntArray( propColumnNumbers ); + subclassPropertyFormulaNumberClosure = ArrayHelper.to2DIntArray( propFormulaNumbers ); + + subclassPropertyCascadeStyleClosure = cascades.toArray( new CascadeStyle[ cascades.size() ] ); + subclassPropertyFetchModeClosure = joinedFetchesList.toArray( new FetchMode[ joinedFetchesList.size() ] ); + + propertyDefinedOnSubclass = ArrayHelper.toBooleanArray( definedBySubclass ); + + List filterDefaultConditions = new ArrayList(); + for ( FilterDefinition filterDefinition : entityBinding.getFilterDefinitions() ) { + filterDefaultConditions.add(new FilterConfiguration(filterDefinition.getFilterName(), + filterDefinition.getDefaultFilterCondition(), true, null, null, null)); + } + filterHelper = new FilterHelper( filterDefaultConditions, factory); + + temporaryIdTableName = null; + temporaryIdTableDDL = null; + + this.cacheEntryHelper = buildCacheEntryHelper(); + } + + protected static String getTemplateFromString(String string, SessionFactoryImplementor factory) { + return string == null ? + null : + Template.renderWhereStringTemplate( string, factory.getDialect(), factory.getSqlFunctionRegistry() ); + } + + public String getTemplateFromColumn(org.hibernate.metamodel.relational.Column column, SessionFactoryImplementor factory) { + String templateString; + if ( column.getReadFragment() != null ) { + templateString = getTemplateFromString( column.getReadFragment(), factory ); + } + else { + String columnName = column.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() ); + templateString = Template.TEMPLATE + '.' + columnName; + } + return templateString; + } + protected String generateLazySelectString() { if ( !entityMetamodel.hasLazyProperties() ) { @@ -721,18 +1193,18 @@ int propertyNumber = getSubclassPropertyIndex( lazyPropertyNames[i] ); int tableNumber = getSubclassPropertyTableNumber( propertyNumber ); - tableNumbers.add( new Integer( tableNumber ) ); + tableNumbers.add( tableNumber ); int[] colNumbers = subclassPropertyColumnNumberClosure[propertyNumber]; for ( int j = 0; j < colNumbers.length; j++ ) { if ( colNumbers[j]!=-1 ) { - columnNumbers.add( new Integer( colNumbers[j] ) ); + columnNumbers.add( colNumbers[j] ); } } int[] formNumbers = subclassPropertyFormulaNumberClosure[propertyNumber]; for ( int j = 0; j < formNumbers.length; j++ ) { if ( formNumbers[j]!=-1 ) { - formulaNumbers.add( new Integer( formNumbers[j] ) ); + formulaNumbers.add( formNumbers[j] ); } } } @@ -758,19 +1230,15 @@ throw new HibernateException( "entity is not associated with the session: " + id ); } - if ( log.isTraceEnabled() ) { - log.trace( - "initializing lazy properties of: " + - MessageHelper.infoString( this, id, getFactory() ) + - ", field access: " + fieldName - ); + if ( LOG.isTraceEnabled() ) { + LOG.tracev( "Initializing lazy properties of: {0}, field access: {1}", MessageHelper.infoString( this, id, getFactory() ), fieldName ); } if ( hasCache() ) { - CacheKey cacheKey = new CacheKey(id, getIdentifierType(), getEntityName(), session.getEntityMode(), getFactory() ); - Object ce = getCacheAccessStrategy().get( cacheKey, session.getTimestamp() ); - if (ce!=null) { - CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure(ce, factory); + final CacheKey cacheKey = session.generateCacheKey( id, getIdentifierType(), getEntityName() ); + final Object ce = CacheHelper.fromSharedCache( session, cacheKey, getCacheAccessStrategy() ); + if ( ce != null ) { + final CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure(ce, factory); if ( !cacheEntry.areLazyPropertiesUnfetched() ) { //note early exit here: return initializeLazyPropertiesFromCache( fieldName, entity, session, entry, cacheEntry ); @@ -789,11 +1257,9 @@ final Serializable id, final EntityEntry entry) { - if ( !hasLazyProperties() ) { - throw new AssertionFailure("no lazy properties"); - } + if ( !hasLazyProperties() ) throw new AssertionFailure( "no lazy properties" ); - log.trace("initializing lazy properties from datastore"); + LOG.trace( "Initializing lazy properties from datastore" ); try { @@ -807,9 +1273,12 @@ // null sql means that the only lazy properties // are shared PK one-to-one associations which are // handled differently in the Type#nullSafeGet code... - ps = session.getBatcher().prepareSelectStatement(lazySelect); + ps = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( lazySelect ); getIdentifierType().nullSafeSet( ps, id, 1, session ); - rs = ps.executeQuery(); + rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( ps ); rs.next(); } final Object[] snapshot = entry.getLoadedState(); @@ -822,24 +1291,23 @@ } finally { if ( rs != null ) { - rs.close(); + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, ps ); } } } finally { if ( ps != null ) { - session.getBatcher().closeStatement( ps ); + session.getTransactionCoordinator().getJdbcCoordinator().release( ps ); } } - log.trace( "done initializing lazy properties" ); + LOG.trace( "Done initializing lazy properties" ); return result; } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - getFactory().getSQLExceptionConverter(), + throw getFactory().getSQLExceptionHelper().convert( sqle, "could not initialize lazy properties: " + MessageHelper.infoString( this, id, getFactory() ), @@ -856,7 +1324,7 @@ final CacheEntry cacheEntry ) { - log.trace("initializing lazy properties from second-level cache"); + LOG.trace( "Initializing lazy properties from second-level cache" ); Object result = null; Serializable[] disassembledValues = cacheEntry.getDisassembledState(); @@ -872,7 +1340,7 @@ } } - log.trace( "done initializing lazy properties" ); + LOG.trace( "Done initializing lazy properties" ); return result; } @@ -884,18 +1352,18 @@ final Object[] snapshot, final int j, final Object propValue) { - setPropertyValue( entity, lazyPropertyNumbers[j], propValue, session.getEntityMode() ); - if (snapshot != null) { + setPropertyValue( entity, lazyPropertyNumbers[j], propValue ); + if ( snapshot != null ) { // object have been loaded with setReadOnly(true); HHH-2236 - snapshot[ lazyPropertyNumbers[j] ] = lazyPropertyTypes[j].deepCopy( propValue, session.getEntityMode(), factory ); + snapshot[ lazyPropertyNumbers[j] ] = lazyPropertyTypes[j].deepCopy( propValue, factory ); } return fieldName.equals( lazyPropertyNames[j] ); } public boolean isBatchable() { - return optimisticLockMode()==Versioning.OPTIMISTIC_LOCK_NONE || - ( !isVersioned() && optimisticLockMode()==Versioning.OPTIMISTIC_LOCK_VERSION ) || - getFactory().getSettings().isJdbcBatchVersionedData(); + return optimisticLockStyle() == OptimisticLockStyle.NONE + || ( !isVersioned() && optimisticLockStyle() == OptimisticLockStyle.VERSION ) + || getFactory().getSettings().isJdbcBatchVersionedData(); } public Serializable[] getQuerySpaces() { @@ -914,6 +1382,14 @@ return rootTableKeyColumnNames; } + public String[] getIdentifierColumnReaders() { + return rootTableKeyColumnReaders; + } + + public String[] getIdentifierColumnReaderTemplates() { + return rootTableKeyColumnReaderTemplates; + } + protected int getIdentifierColumnSpan() { return identifierColumnSpan; } @@ -991,22 +1467,28 @@ } - public String propertySelectFragment(String name, String suffix, boolean allProperties) { + public String propertySelectFragment(String tableAlias, String suffix, boolean allProperties) { + return propertySelectFragmentFragment( tableAlias, suffix, allProperties ).toFragmentString(); + } + public SelectFragment propertySelectFragmentFragment( + String tableAlias, + String suffix, + boolean allProperties) { SelectFragment select = new SelectFragment() .setSuffix( suffix ) .setUsedAliases( getIdentifierAliases() ); int[] columnTableNumbers = getSubclassColumnTableNumberClosure(); String[] columnAliases = getSubclassColumnAliasClosure(); - String[] columns = getSubclassColumnClosure(); + String[] columnReaderTemplates = getSubclassColumnReaderTemplateClosure(); for ( int i = 0; i < getSubclassColumnClosure().length; i++ ) { boolean selectable = ( allProperties || !subclassColumnLazyClosure[i] ) && !isSubclassTableSequentialSelect( columnTableNumbers[i] ) && subclassColumnSelectableClosure[i]; if ( selectable ) { - String subalias = generateTableAlias( name, columnTableNumbers[i] ); - select.addColumn( subalias, columns[i], columnAliases[i] ); + String subalias = generateTableAlias( tableAlias, columnTableNumbers[i] ); + select.addColumnTemplate( subalias, columnReaderTemplates[i], columnAliases[i] ); } } @@ -1017,41 +1499,43 @@ boolean selectable = ( allProperties || !subclassFormulaLazyClosure[i] ) && !isSubclassTableSequentialSelect( formulaTableNumbers[i] ); if ( selectable ) { - String subalias = generateTableAlias( name, formulaTableNumbers[i] ); + String subalias = generateTableAlias( tableAlias, formulaTableNumbers[i] ); select.addFormula( subalias, formulaTemplates[i], formulaAliases[i] ); } } if ( entityMetamodel.hasSubclasses() ) { - addDiscriminatorToSelect( select, name, suffix ); + addDiscriminatorToSelect( select, tableAlias, suffix ); } if ( hasRowId() ) { - select.addColumn( name, rowIdName, ROWID_ALIAS ); + select.addColumn( tableAlias, rowIdName, ROWID_ALIAS ); } - return select.toFragmentString(); + return select; } public Object[] getDatabaseSnapshot(Serializable id, SessionImplementor session) throws HibernateException { - if ( log.isTraceEnabled() ) { - log.trace( "Getting current persistent state for: " + MessageHelper.infoString( this, id, getFactory() ) ); + if ( LOG.isTraceEnabled() ) { + LOG.tracev( "Getting current persistent state for: {0}", MessageHelper.infoString( this, id, getFactory() ) ); } try { - PreparedStatement ps = session.getBatcher().prepareSelectStatement( getSQLSnapshotSelectString() ); + PreparedStatement ps = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( getSQLSnapshotSelectString() ); try { getIdentifierType().nullSafeSet( ps, id, 1, session ); //if ( isVersioned() ) getVersionType().nullSafeSet( ps, version, getIdentifierColumnSpan()+1, session ); - ResultSet rs = ps.executeQuery(); + ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( ps ); try { //if there is no resulting row, return null if ( !rs.next() ) { return null; } - //otherwise return the "hydrated" state (ie. associations are not resolved) Type[] types = getPropertyTypes(); Object[] values = new Object[types.length]; @@ -1064,25 +1548,124 @@ return values; } finally { - rs.close(); + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, ps ); } } finally { - session.getBatcher().closeStatement( ps ); + session.getTransactionCoordinator().getJdbcCoordinator().release( ps ); } } - catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - getFactory().getSQLExceptionConverter(), - sqle, - "could not retrieve snapshot: " + - MessageHelper.infoString( this, id, getFactory() ), + catch ( SQLException e ) { + throw getFactory().getSQLExceptionHelper().convert( + e, + "could not retrieve snapshot: " + MessageHelper.infoString( this, id, getFactory() ), getSQLSnapshotSelectString() - ); + ); } } + @Override + public Serializable getIdByUniqueKey(Serializable key, String uniquePropertyName, SessionImplementor session) throws HibernateException { + if ( LOG.isTraceEnabled() ) { + LOG.tracef( + "resolving unique key [%s] to identifier for entity [%s]", + key, + getEntityName() + ); + } + + int propertyIndex = getSubclassPropertyIndex( uniquePropertyName ); + if ( propertyIndex < 0 ) { + throw new HibernateException( + "Could not determine Type for property [" + uniquePropertyName + "] on entity [" + getEntityName() + "]" + ); + } + Type propertyType = getSubclassPropertyType( propertyIndex ); + + try { + PreparedStatement ps = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( generateIdByUniqueKeySelectString( uniquePropertyName ) ); + try { + propertyType.nullSafeSet( ps, key, 1, session ); + ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( ps ); + try { + //if there is no resulting row, return null + if ( !rs.next() ) { + return null; + } + return (Serializable) getIdentifierType().nullSafeGet( rs, getIdentifierAliases(), session, null ); + } + finally { + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, ps ); + } + } + finally { + session.getTransactionCoordinator().getJdbcCoordinator().release( ps ); + } + } + catch ( SQLException e ) { + throw getFactory().getSQLExceptionHelper().convert( + e, + String.format( + "could not resolve unique property [%s] to identifier for entity [%s]", + uniquePropertyName, + getEntityName() + ), + getSQLSnapshotSelectString() + ); + } + + } + + protected String generateIdByUniqueKeySelectString(String uniquePropertyName) { + Select select = new Select( getFactory().getDialect() ); + + if ( getFactory().getSettings().isCommentsEnabled() ) { + select.setComment( "resolve id by unique property [" + getEntityName() + "." + uniquePropertyName + "]" ); + } + + final String rooAlias = getRootAlias(); + + select.setFromClause( fromTableFragment( rooAlias ) + fromJoinFragment( rooAlias, true, false ) ); + + SelectFragment selectFragment = new SelectFragment(); + selectFragment.addColumns( rooAlias, getIdentifierColumnNames(), getIdentifierAliases() ); + select.setSelectClause( selectFragment ); + + StringBuilder whereClauseBuffer = new StringBuilder(); + final int uniquePropertyIndex = getSubclassPropertyIndex( uniquePropertyName ); + final String uniquePropertyTableAlias = generateTableAlias( + rooAlias, + getSubclassPropertyTableNumber( uniquePropertyIndex ) + ); + String sep = ""; + for ( String columnTemplate : getSubclassPropertyColumnReaderTemplateClosure()[uniquePropertyIndex] ) { + if ( columnTemplate == null ) { + continue; + } + final String columnReference = StringHelper.replace( columnTemplate, Template.TEMPLATE, uniquePropertyTableAlias ); + whereClauseBuffer.append( sep ).append( columnReference ).append( "=?" ); + sep = " and "; + } + for ( String formulaTemplate : getSubclassPropertyFormulaTemplateClosure()[uniquePropertyIndex] ) { + if ( formulaTemplate == null ) { + continue; + } + final String formulaReference = StringHelper.replace( formulaTemplate, Template.TEMPLATE, uniquePropertyTableAlias ); + whereClauseBuffer.append( sep ).append( formulaReference ).append( "=?" ); + sep = " and "; + } + whereClauseBuffer.append( whereJoinFragment( rooAlias, true, false ) ); + + select.setWhereClause( whereClauseBuffer.toString() ); + + return select.setOuterJoins( "", "" ).toStatementString(); + } + + /** * Generate the SQL that selects the version number by id */ @@ -1101,15 +1684,19 @@ return select.addCondition( rootTableKeyColumnNames, "=?" ).toStatementString(); } + public boolean[] getPropertyUniqueness() { + return propertyUniqueness; + } + protected String generateInsertGeneratedValuesSelectString() { - return generateGeneratedValuesSelectString( getPropertyInsertGenerationInclusions() ); + return generateGeneratedValuesSelectString( GenerationTiming.INSERT ); } protected String generateUpdateGeneratedValuesSelectString() { - return generateGeneratedValuesSelectString( getPropertyUpdateGenerationInclusions() ); + return generateGeneratedValuesSelectString( GenerationTiming.ALWAYS ); } - private String generateGeneratedValuesSelectString(ValueInclusion[] inclusions) { + private String generateGeneratedValuesSelectString(final GenerationTiming generationTimingToMatch) { Select select = new Select( getFactory().getDialect() ); if ( getFactory().getSettings().isCommentsEnabled() ) { @@ -1121,17 +1708,28 @@ // Here we render the select column list based on the properties defined as being generated. // For partial component generation, we currently just re-select the whole component // rather than trying to handle the individual generated portions. - String selectClause = concretePropertySelectFragment( getRootAlias(), inclusions ); + String selectClause = concretePropertySelectFragment( + getRootAlias(), + new InclusionChecker() { + @Override + public boolean includeProperty(int propertyNumber) { + final InDatabaseValueGenerationStrategy generationStrategy + = entityMetamodel.getInDatabaseValueGenerationStrategies()[propertyNumber]; + return generationStrategy != null + && timingsMatch( generationStrategy.getGenerationTiming(), generationTimingToMatch ); + } + } + ); selectClause = selectClause.substring( 2 ); String fromClause = fromTableFragment( getRootAlias() ) + fromJoinFragment( getRootAlias(), true, false ); - String whereClause = new StringBuffer() - .append( StringHelper.join( "=? and ", aliasedIdColumns ) ) - .append( "=?" ) - .append( whereJoinFragment( getRootAlias(), true, false ) ) - .toString(); + String whereClause = new StringBuilder() + .append( StringHelper.join( "=? and ", aliasedIdColumns ) ) + .append( "=?" ) + .append( whereJoinFragment( getRootAlias(), true, false ) ) + .toString(); return select.setSelectClause( selectClause ) .setFromClause( fromClause ) @@ -1144,21 +1742,6 @@ public boolean includeProperty(int propertyNumber); } - protected String concretePropertySelectFragment(String alias, final ValueInclusion[] inclusions) { - return concretePropertySelectFragment( - alias, - new InclusionChecker() { - // TODO : currently we really do not handle ValueInclusion.PARTIAL... - // ValueInclusion.PARTIAL would indicate parts of a component need to - // be included in the select; currently we then just render the entire - // component into the select clause in that case. - public boolean includeProperty(int propertyNumber) { - return inclusions[propertyNumber] != ValueInclusion.NONE; - } - } - ); - } - protected String concretePropertySelectFragment(String alias, final boolean[] includeProperty) { return concretePropertySelectFragment( alias, @@ -1176,9 +1759,9 @@ SelectFragment frag = new SelectFragment(); for ( int i = 0; i < propertyCount; i++ ) { if ( inclusionChecker.includeProperty( i ) ) { - frag.addColumns( + frag.addColumnTemplates( generateTableAlias( alias, propertyTableNumbers[i] ), - propertyColumnNames[i], + propertyColumnReaderTemplates[i], propertyColumnAliases[i] ); frag.addFormulas( @@ -1208,7 +1791,7 @@ String fromClause = fromTableFragment( getRootAlias() ) + fromJoinFragment( getRootAlias(), true, false ); - String whereClause = new StringBuffer() + String whereClause = new StringBuilder() .append( StringHelper.join( "=? and ", aliasedIdColumns ) ) .append( "=?" ) @@ -1240,35 +1823,33 @@ } Object nextVersion = getVersionType().next( currentVersion, session ); - if ( log.isTraceEnabled() ) { - log.trace( - "Forcing version increment [" + MessageHelper.infoString( this, id, getFactory() ) + - "; " + getVersionType().toLoggableString( currentVersion, getFactory() ) + - " -> " + getVersionType().toLoggableString( nextVersion, getFactory() ) + "]" - ); - } + if (LOG.isTraceEnabled()) LOG.trace("Forcing version increment [" + MessageHelper.infoString(this, id, getFactory()) + "; " + + getVersionType().toLoggableString(currentVersion, getFactory()) + " -> " + + getVersionType().toLoggableString(nextVersion, getFactory()) + "]"); // todo : cache this sql... String versionIncrementString = generateVersionIncrementUpdateString(); PreparedStatement st = null; try { + st = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( versionIncrementString, false ); try { - st = session.getBatcher().prepareStatement( versionIncrementString ); getVersionType().nullSafeSet( st, nextVersion, 1, session ); getIdentifierType().nullSafeSet( st, id, 2, session ); getVersionType().nullSafeSet( st, currentVersion, 2 + getIdentifierColumnSpan(), session ); - int rows = st.executeUpdate(); + int rows = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ); if ( rows != 1 ) { throw new StaleObjectStateException( getEntityName(), id ); } } finally { - session.getBatcher().closeStatement( st ); + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - getFactory().getSQLExceptionConverter(), + throw getFactory().getSQLExceptionHelper().convert( sqle, "could not retrieve version: " + MessageHelper.infoString( this, id, getFactory() ), @@ -1286,7 +1867,7 @@ update.setComment( "forced version increment" ); } update.addColumn( getVersionColumnName() ); - update.setPrimaryKeyColumnNames( getIdentifierColumnNames() ); + update.addPrimaryKeyColumns( getIdentifierColumnNames() ); update.setVersionColumnName( getVersionColumnName() ); return update.toStatementString(); } @@ -1296,17 +1877,18 @@ */ public Object getCurrentVersion(Serializable id, SessionImplementor session) throws HibernateException { - if ( log.isTraceEnabled() ) { - log.trace( "Getting version: " + MessageHelper.infoString( this, id, getFactory() ) ); + if ( LOG.isTraceEnabled() ) { + LOG.tracev( "Getting version: {0}", MessageHelper.infoString( this, id, getFactory() ) ); } try { - - PreparedStatement st = session.getBatcher().prepareSelectStatement( getVersionSelectString() ); + PreparedStatement st = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( getVersionSelectString() ); try { getIdentifierType().nullSafeSet( st, id, 1, session ); - - ResultSet rs = st.executeQuery(); + ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st ); try { if ( !rs.next() ) { return null; @@ -1317,31 +1899,33 @@ return getVersionType().nullSafeGet( rs, getVersionColumnName(), session, null ); } finally { - rs.close(); + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st ); } } finally { - session.getBatcher().closeStatement( st ); + session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } - } - catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - getFactory().getSQLExceptionConverter(), - sqle, - "could not retrieve version: " + - MessageHelper.infoString( this, id, getFactory() ), + catch ( SQLException e ) { + throw getFactory().getSQLExceptionHelper().convert( + e, + "could not retrieve version: " + MessageHelper.infoString( this, id, getFactory() ), getVersionSelectString() - ); + ); } - } protected void initLockers() { lockers.put( LockMode.READ, generateLocker( LockMode.READ ) ); lockers.put( LockMode.UPGRADE, generateLocker( LockMode.UPGRADE ) ); lockers.put( LockMode.UPGRADE_NOWAIT, generateLocker( LockMode.UPGRADE_NOWAIT ) ); + lockers.put( LockMode.UPGRADE_SKIPLOCKED, generateLocker( LockMode.UPGRADE_SKIPLOCKED ) ); lockers.put( LockMode.FORCE, generateLocker( LockMode.FORCE ) ); + lockers.put( LockMode.PESSIMISTIC_READ, generateLocker( LockMode.PESSIMISTIC_READ ) ); + lockers.put( LockMode.PESSIMISTIC_WRITE, generateLocker( LockMode.PESSIMISTIC_WRITE ) ); + lockers.put( LockMode.PESSIMISTIC_FORCE_INCREMENT, generateLocker( LockMode.PESSIMISTIC_FORCE_INCREMENT ) ); + lockers.put( LockMode.OPTIMISTIC, generateLocker( LockMode.OPTIMISTIC ) ); + lockers.put( LockMode.OPTIMISTIC_FORCE_INCREMENT, generateLocker( LockMode.OPTIMISTIC_FORCE_INCREMENT ) ); } protected LockingStrategy generateLocker(LockMode lockMode) { @@ -1358,9 +1942,18 @@ Object object, LockMode lockMode, SessionImplementor session) throws HibernateException { - getLocker( lockMode ).lock( id, version, object, session ); + getLocker( lockMode ).lock( id, version, object, LockOptions.WAIT_FOREVER, session ); } + public void lock( + Serializable id, + Object version, + Object object, + LockOptions lockOptions, + SessionImplementor session) throws HibernateException { + getLocker( lockOptions.getLockMode() ).lock( id, version, object, lockOptions.getTimeOut(), session ); + } + public String getRootTableName() { return getSubclassTableName( 0 ); } @@ -1436,11 +2029,32 @@ } } - protected String generateTableAlias(String rootAlias, int tableNumber) { + private DiscriminatorMetadata discriminatorMetadata; + + public DiscriminatorMetadata getTypeDiscriminatorMetadata() { + if ( discriminatorMetadata == null ) { + discriminatorMetadata = buildTypeDiscriminatorMetadata(); + } + return discriminatorMetadata; + } + + private DiscriminatorMetadata buildTypeDiscriminatorMetadata() { + return new DiscriminatorMetadata() { + public String getSqlFragment(String sqlQualificationAlias) { + return toColumns( sqlQualificationAlias, ENTITY_CLASS )[0]; + } + + public Type getResolutionType() { + return new DiscriminatorType( getDiscriminatorType(), AbstractEntityPersister.this ); + } + }; + } + + public static String generateTableAlias(String rootAlias, int tableNumber) { if ( tableNumber == 0 ) { return rootAlias; } - StringBuffer buf = new StringBuffer().append( rootAlias ); + StringBuilder buf = new StringBuilder().append( rootAlias ); if ( !rootAlias.endsWith( "_" ) ) { buf.append( '_' ); } @@ -1475,6 +2089,10 @@ return propertyColumnNames[i]; } + public String[] getPropertyColumnWriters(int i) { + return propertyColumnWriters[i]; + } + protected int getPropertyColumnSpan(int i) { return propertyColumnSpans[i]; } @@ -1511,7 +2129,8 @@ return propertyDefinedOnSubclass[i]; } - protected String[][] getSubclassPropertyFormulaTemplateClosure() { + @Override + public String[][] getSubclassPropertyFormulaTemplateClosure() { return subclassPropertyFormulaTemplateClosure; } @@ -1523,10 +2142,31 @@ return subclassPropertyColumnNameClosure; } + public String[][] getSubclassPropertyColumnReaderClosure() { + return subclassPropertyColumnReaderClosure; + } + + public String[][] getSubclassPropertyColumnReaderTemplateClosure() { + return subclassPropertyColumnReaderTemplateClosure; + } + protected String[] getSubclassPropertyNameClosure() { return subclassPropertyNameClosure; } + @Override + public int[] resolveAttributeIndexes(Set properties) { + Iterator iter = properties.iterator(); + int[] fields = new int[properties.size()]; + int counter = 0; + while(iter.hasNext()) { + Integer index = entityMetamodel.getPropertyIndexOrNull( iter.next() ); + if ( index != null ) + fields[counter++] = index; + } + return fields; + } + protected String[] getSubclassPropertySubclassNameClosure() { return subclassPropertySubclassNameClosure; } @@ -1539,6 +2179,10 @@ return subclassColumnAliasClosure; } + public String[] getSubclassColumnReaderTemplateClosure() { + return subclassColumnReaderTemplateClosure; + } + protected String[] getSubclassFormulaClosure() { return subclassFormulaClosure; } @@ -1552,13 +2196,13 @@ } public String[] getSubclassPropertyColumnAliases(String propertyName, String suffix) { - String rawAliases[] = ( String[] ) subclassPropertyAliases.get( propertyName ); + String[] rawAliases = ( String[] ) subclassPropertyAliases.get( propertyName ); if ( rawAliases == null ) { return null; } - String result[] = new String[rawAliases.length]; + String[] result = new String[rawAliases.length]; for ( int i = 0; i < rawAliases.length; i++ ) { result[i] = new Alias( suffix ).toUnquotedAliasString( rawAliases[i] ); } @@ -1596,7 +2240,7 @@ // aliases for composite-id's if ( getIdentifierType().isComponentType() ) { // Fetch embedded identifiers propertynames from the "virtual" identifier component - AbstractComponentType componentId = ( AbstractComponentType ) getIdentifierType(); + CompositeType componentId = ( CompositeType ) getIdentifierType(); String[] idPropertyNames = componentId.getPropertyNames(); String[] idAliases = getIdentifierAliases(); String[] idColumnNames = getIdentifierColumnNames(); @@ -1638,6 +2282,73 @@ } + /** + * Must be called by subclasses, at the end of their constructors + */ + protected void initSubclassPropertyAliasesMap(EntityBinding model) throws MappingException { + + // ALIASES + + // TODO: Fix when subclasses are working (HHH-6337) + //internalInitSubclassPropertyAliasesMap( null, model.getSubclassPropertyClosureIterator() ); + + // aliases for identifier ( alias.id ); skip if the entity defines a non-id property named 'id' + if ( ! entityMetamodel.hasNonIdentifierPropertyNamedId() ) { + subclassPropertyAliases.put( ENTITY_ID, getIdentifierAliases() ); + subclassPropertyColumnNames.put( ENTITY_ID, getIdentifierColumnNames() ); + } + + // aliases named identifier ( alias.idname ) + if ( hasIdentifierProperty() ) { + subclassPropertyAliases.put( getIdentifierPropertyName(), getIdentifierAliases() ); + subclassPropertyColumnNames.put( getIdentifierPropertyName(), getIdentifierColumnNames() ); + } + + // aliases for composite-id's + if ( getIdentifierType().isComponentType() ) { + // Fetch embedded identifiers propertynames from the "virtual" identifier component + CompositeType componentId = ( CompositeType ) getIdentifierType(); + String[] idPropertyNames = componentId.getPropertyNames(); + String[] idAliases = getIdentifierAliases(); + String[] idColumnNames = getIdentifierColumnNames(); + + for ( int i = 0; i < idPropertyNames.length; i++ ) { + if ( entityMetamodel.hasNonIdentifierPropertyNamedId() ) { + subclassPropertyAliases.put( + ENTITY_ID + "." + idPropertyNames[i], + new String[] { idAliases[i] } + ); + subclassPropertyColumnNames.put( + ENTITY_ID + "." + getIdentifierPropertyName() + "." + idPropertyNames[i], + new String[] { idColumnNames[i] } + ); + } +// if (hasIdentifierProperty() && !ENTITY_ID.equals( getIdentifierPropertyName() ) ) { + if ( hasIdentifierProperty() ) { + subclassPropertyAliases.put( + getIdentifierPropertyName() + "." + idPropertyNames[i], + new String[] { idAliases[i] } + ); + subclassPropertyColumnNames.put( + getIdentifierPropertyName() + "." + idPropertyNames[i], + new String[] { idColumnNames[i] } + ); + } + else { + // embedded composite ids ( alias.idname1, alias.idname2 ) + subclassPropertyAliases.put( idPropertyNames[i], new String[] { idAliases[i] } ); + subclassPropertyColumnNames.put( idPropertyNames[i], new String[] { idColumnNames[i] } ); + } + } + } + + if ( entityMetamodel.isPolymorphic() ) { + subclassPropertyAliases.put( ENTITY_CLASS, new String[] { getDiscriminatorAlias() } ); + subclassPropertyColumnNames.put( ENTITY_CLASS, new String[] { getDiscriminatorColumnName() } ); + } + + } + private void internalInitSubclassPropertyAliasesMap(String path, Iterator propertyIterator) { while ( propertyIterator.hasNext() ) { @@ -1667,26 +2378,27 @@ } - public Object loadByUniqueKey(String propertyName, Object uniqueKey, SessionImplementor session) - throws HibernateException { - return getAppropriateUniqueKeyLoader( propertyName, session.getEnabledFilters() ) - .loadByUniqueKey( session, uniqueKey ); + public Object loadByUniqueKey( + String propertyName, + Object uniqueKey, + SessionImplementor session) throws HibernateException { + return getAppropriateUniqueKeyLoader( propertyName, session ).loadByUniqueKey( session, uniqueKey ); } - private EntityLoader getAppropriateUniqueKeyLoader(String propertyName, Map enabledFilters) { - - final boolean useStaticLoader = ( enabledFilters == null || enabledFilters.isEmpty() ) + private EntityLoader getAppropriateUniqueKeyLoader(String propertyName, SessionImplementor session) { + final boolean useStaticLoader = !session.getLoadQueryInfluencers().hasEnabledFilters() + && !session.getLoadQueryInfluencers().hasEnabledFetchProfiles() && propertyName.indexOf('.')<0; //ugly little workaround for fact that createUniqueKeyLoaders() does not handle component properties if ( useStaticLoader ) { - return (EntityLoader) uniqueKeyLoaders.get( propertyName ); + return ( EntityLoader ) uniqueKeyLoaders.get( propertyName ); } else { return createUniqueKeyLoader( - propertyMapping.toType(propertyName), - propertyMapping.toColumns(propertyName), - enabledFilters - ); + propertyMapping.toType( propertyName ), + propertyMapping.toColumns( propertyName ), + session.getLoadQueryInfluencers() + ); } } @@ -1705,21 +2417,31 @@ createUniqueKeyLoader( propertyTypes[i], getPropertyColumnNames( i ), - CollectionHelper.EMPTY_MAP - ) - ); + LoadQueryInfluencers.NONE + ) + ); //TODO: create uk loaders for component properties } } } - private EntityLoader createUniqueKeyLoader(Type uniqueKeyType, String[] columns, Map enabledFilters) { + private EntityLoader createUniqueKeyLoader( + Type uniqueKeyType, + String[] columns, + LoadQueryInfluencers loadQueryInfluencers) { if ( uniqueKeyType.isEntityType() ) { String className = ( ( EntityType ) uniqueKeyType ).getAssociatedEntityName(); uniqueKeyType = getFactory().getEntityPersister( className ).getIdentifierType(); } - - return new EntityLoader( this, columns, uniqueKeyType, 1, LockMode.NONE, getFactory(), enabledFilters ); + return new EntityLoader( + this, + columns, + uniqueKeyType, + 1, + LockMode.NONE, + getFactory(), + loadQueryInfluencers + ); } protected String getSQLWhereString(String alias) { @@ -1735,6 +2457,8 @@ propertyMapping.initPropertyPaths( getSubclassPropertyNameClosure()[i], getSubclassPropertyTypeClosure()[i], getSubclassPropertyColumnNameClosure()[i], + getSubclassPropertyColumnReaderClosure()[i], + getSubclassPropertyColumnReaderTemplateClosure()[i], getSubclassPropertyFormulaTemplateClosure()[i], mapping ); } @@ -1743,20 +2467,25 @@ private void initIdentifierPropertyPaths(Mapping mapping) throws MappingException { String idProp = getIdentifierPropertyName(); if ( idProp != null ) { - propertyMapping.initPropertyPaths( idProp, getIdentifierType(), getIdentifierColumnNames(), null, mapping ); + propertyMapping.initPropertyPaths( idProp, getIdentifierType(), getIdentifierColumnNames(), + getIdentifierColumnReaders(), getIdentifierColumnReaderTemplates(), null, mapping ); } if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) { - propertyMapping.initPropertyPaths( null, getIdentifierType(), getIdentifierColumnNames(), null, mapping ); + propertyMapping.initPropertyPaths( null, getIdentifierType(), getIdentifierColumnNames(), + getIdentifierColumnReaders(), getIdentifierColumnReaderTemplates(), null, mapping ); } if ( ! entityMetamodel.hasNonIdentifierPropertyNamedId() ) { - propertyMapping.initPropertyPaths( ENTITY_ID, getIdentifierType(), getIdentifierColumnNames(), null, mapping ); + propertyMapping.initPropertyPaths( ENTITY_ID, getIdentifierType(), getIdentifierColumnNames(), + getIdentifierColumnReaders(), getIdentifierColumnReaderTemplates(), null, mapping ); } } private void initDiscriminatorPropertyPath(Mapping mapping) throws MappingException { propertyMapping.initPropertyPaths( ENTITY_CLASS, getDiscriminatorType(), new String[]{getDiscriminatorColumnName()}, + new String[]{getDiscriminatorColumnReaders()}, + new String[]{getDiscriminatorColumnReaderTemplate()}, new String[]{getDiscriminatorFormulaTemplate()}, getFactory() ); } @@ -1770,13 +2499,33 @@ } } - protected UniqueEntityLoader createEntityLoader(LockMode lockMode, Map enabledFilters) throws MappingException { + protected UniqueEntityLoader createEntityLoader( + LockMode lockMode, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { //TODO: disable batch loading if lockMode > READ? - return BatchingEntityLoader.createBatchingEntityLoader( this, batchSize, lockMode, getFactory(), enabledFilters ); + return BatchingEntityLoaderBuilder.getBuilder( getFactory() ) + .buildLoader( this, batchSize, lockMode, getFactory(), loadQueryInfluencers ); } + protected UniqueEntityLoader createEntityLoader( + LockOptions lockOptions, + LoadQueryInfluencers loadQueryInfluencers) throws MappingException { + //TODO: disable batch loading if lockMode > READ? + return BatchingEntityLoaderBuilder.getBuilder( getFactory() ) + .buildLoader( this, batchSize, lockOptions, getFactory(), loadQueryInfluencers ); + } + + /** + * Used internally to create static loaders. These are the default set of loaders used to handle get()/load() + * processing. lock() handling is done by the LockingStrategy instances (see {@link #getLocker}) + * + * @param lockMode The lock mode to apply to the thing being loaded. + * @return + * + * @throws MappingException + */ protected UniqueEntityLoader createEntityLoader(LockMode lockMode) throws MappingException { - return createEntityLoader( lockMode, CollectionHelper.EMPTY_MAP ); + return createEntityLoader( lockMode, LoadQueryInfluencers.NONE ); } protected boolean check(int rows, Serializable id, int tableNumber, Expectation expectation, PreparedStatement statement) throws HibernateException { @@ -1821,22 +2570,36 @@ // select the correct row by either pk or rowid if ( useRowId ) { - update.setPrimaryKeyColumnNames( new String[]{rowIdName} ); //TODO: eventually, rowIdName[j] + update.addPrimaryKeyColumns( new String[]{rowIdName} ); //TODO: eventually, rowIdName[j] } else { - update.setPrimaryKeyColumnNames( getKeyColumns( j ) ); + update.addPrimaryKeyColumns( getKeyColumns( j ) ); } boolean hasColumns = false; for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) { - if ( includeProperty[i] && isPropertyOfTable( i, j ) ) { + if ( includeProperty[i] && isPropertyOfTable( i, j ) + && !lobProperties.contains( i ) ) { // this is a property of the table, which we are updating - update.addColumns( getPropertyColumnNames(i), propertyColumnUpdateable[i] ); + update.addColumns( getPropertyColumnNames(i), + propertyColumnUpdateable[i], propertyColumnWriters[i] ); hasColumns = hasColumns || getPropertyColumnSpan( i ) > 0; } } + + // HHH-4635 + // Oracle expects all Lob properties to be last in inserts + // and updates. Insert them at the end. + for ( int i : lobProperties ) { + if ( includeProperty[i] && isPropertyOfTable( i, j ) ) { + // this property belongs on the table and is to be inserted + update.addColumns( getPropertyColumnNames(i), + propertyColumnUpdateable[i], propertyColumnWriters[i] ); + hasColumns = true; + } + } - if ( j == 0 && isVersioned() && entityMetamodel.getOptimisticLockMode() == Versioning.OPTIMISTIC_LOCK_VERSION ) { + if ( j == 0 && isVersioned() && entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.VERSION ) { // this is the root (versioned) table, and we are using version-based // optimistic locking; if we are not updating the version, also don't // check it (unless this is a "generated" version column)! @@ -1845,12 +2608,12 @@ hasColumns = true; } } - else if ( entityMetamodel.getOptimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION && oldFields != null ) { + else if ( isAllOrDirtyOptLocking() && oldFields != null ) { // we are using "all" or "dirty" property-based optimistic locking - boolean[] includeInWhere = entityMetamodel.getOptimisticLockMode() == Versioning.OPTIMISTIC_LOCK_ALL ? - getPropertyUpdateability() : //optimistic-lock="all", include all updatable properties - includeProperty; //optimistic-lock="dirty", include all properties we are updating this time + boolean[] includeInWhere = entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.ALL + ? getPropertyUpdateability() //optimistic-lock="all", include all updatable properties + : includeProperty; //optimistic-lock="dirty", include all properties we are updating this time boolean[] versionability = getPropertyVersionability(); Type[] types = getPropertyTypes(); @@ -1862,10 +2625,11 @@ // this property belongs to the table, and it is not specifically // excluded from optimistic locking by optimistic-lock="false" String[] propertyColumnNames = getPropertyColumnNames( i ); + String[] propertyColumnWriters = getPropertyColumnWriters( i ); boolean[] propertyNullness = types[i].toColumnNullness( oldFields[i], getFactory() ); for ( int k=0; k mapping; // this code assumes that optional defaults to "true" because it @@ -2130,15 +2975,15 @@ } if ( sequentialResultSet != null ) { - sequentialResultSet.close(); + session.getTransactionCoordinator().getJdbcCoordinator().release( sequentialResultSet, sequentialSelect ); } return values; } finally { if ( sequentialSelect != null ) { - session.getBatcher().closeStatement( sequentialSelect ); + session.getTransactionCoordinator().getJdbcCoordinator().release( sequentialSelect ); } } } @@ -2163,26 +3008,27 @@ */ protected Serializable insert( final Object[] fields, - final boolean[] notNull, - String sql, - final Object object, - final SessionImplementor session) throws HibernateException { + final boolean[] notNull, + String sql, + final Object object, + final SessionImplementor session) throws HibernateException { - if ( log.isTraceEnabled() ) { - log.trace( "Inserting entity: " + getEntityName() + " (native id)" ); + if ( LOG.isTraceEnabled() ) { + LOG.tracev( "Inserting entity: {0} (native id)", getEntityName() ); if ( isVersioned() ) { - log.trace( "Version: " + Versioning.getVersion( fields, this ) ); + LOG.tracev( "Version: {0}", Versioning.getVersion( fields, this ) ); } } Binder binder = new Binder() { public void bindValues(PreparedStatement ps) throws SQLException { - dehydrate( null, fields, notNull, propertyColumnInsertable, 0, ps, session ); + dehydrate( null, fields, notNull, propertyColumnInsertable, 0, ps, session, false ); } public Object getEntity() { return object; } }; + return identityDelegate.performInsert( sql, session, binder ); } @@ -2203,6 +3049,8 @@ .toStatementString(); } + private BasicBatchKey inserBatchKey; + /** * Perform an SQL INSERT. *

        @@ -2211,12 +3059,12 @@ */ protected void insert( final Serializable id, - final Object[] fields, - final boolean[] notNull, - final int j, - final String sql, - final Object object, - final SessionImplementor session) throws HibernateException { + final Object[] fields, + final boolean[] notNull, + final int j, + final String sql, + final Object object, + final SessionImplementor session) throws HibernateException { if ( isInverseTable( j ) ) { return; @@ -2228,37 +3076,39 @@ return; } - if ( log.isTraceEnabled() ) { - log.trace( "Inserting entity: " + MessageHelper.infoString( this, id, getFactory() ) ); - if ( j == 0 && isVersioned() ) { - log.trace( "Version: " + Versioning.getVersion( fields, this ) ); - } + if ( LOG.isTraceEnabled() ) { + LOG.tracev( "Inserting entity: {0}", MessageHelper.infoString( this, id, getFactory() ) ); + if ( j == 0 && isVersioned() ) + LOG.tracev( "Version: {0}", Versioning.getVersion( fields, this ) ); } - Expectation expectation = Expectations.appropriateExpectation( insertResultCheckStyles[j] ); - boolean callable = isInsertCallable( j ); + // TODO : shouldn't inserts be Expectations.NONE? + final Expectation expectation = Expectations.appropriateExpectation( insertResultCheckStyles[j] ); // we can't batch joined inserts, *especially* not if it is an identity insert; // nor can we batch statements where the expectation is based on an output param final boolean useBatch = j == 0 && expectation.canBeBatched(); - try { + if ( useBatch && inserBatchKey == null ) { + inserBatchKey = new BasicBatchKey( + getEntityName() + "#INSERT", + expectation + ); + } + final boolean callable = isInsertCallable( j ); + try { // Render the SQL query final PreparedStatement insert; if ( useBatch ) { - if ( callable ) { - insert = session.getBatcher().prepareBatchCallableStatement( sql ); - } - else { - insert = session.getBatcher().prepareBatchStatement( sql ); - } + insert = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getBatch( inserBatchKey ) + .getBatchStatement( sql, callable ); } else { - if ( callable ) { - insert = session.getBatcher().prepareCallableStatement( sql ); - } - else { - insert = session.getBatcher().prepareStatement( sql ); - } + insert = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( sql, callable ); } try { @@ -2268,36 +3118,34 @@ // Write the values of fields onto the prepared statement - we MUST use the state at the time the // insert was issued (cos of foreign key constraints). Not necessarily the object's current state - dehydrate( id, fields, null, notNull, propertyColumnInsertable, j, insert, session, index ); + dehydrate( id, fields, null, notNull, propertyColumnInsertable, j, insert, session, index, false ); if ( useBatch ) { - // TODO : shouldnt inserts be Expectations.NONE? - session.getBatcher().addToBatch( expectation ); + session.getTransactionCoordinator().getJdbcCoordinator().getBatch( inserBatchKey ).addToBatch(); } else { - expectation.verifyOutcome( insert.executeUpdate(), insert, -1 ); + expectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( insert ), insert, -1 ); } } - catch ( SQLException sqle ) { + catch ( SQLException e ) { if ( useBatch ) { - session.getBatcher().abortBatch( sqle ); + session.getTransactionCoordinator().getJdbcCoordinator().abortBatch(); } - throw sqle; + throw e; } finally { if ( !useBatch ) { - session.getBatcher().closeStatement( insert ); + session.getTransactionCoordinator().getJdbcCoordinator().release( insert ); } } } - catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - getFactory().getSQLExceptionConverter(), - sqle, + catch ( SQLException e ) { + throw getFactory().getSQLExceptionHelper().convert( + e, "could not insert: " + MessageHelper.infoString( this ), sql - ); + ); } } @@ -2307,15 +3155,15 @@ */ protected void updateOrInsert( final Serializable id, - final Object[] fields, - final Object[] oldFields, - final Object rowId, - final boolean[] includeProperty, - final int j, - final Object oldVersion, - final Object object, - final String sql, - final SessionImplementor session) throws HibernateException { + final Object[] fields, + final Object[] oldFields, + final Object rowId, + final boolean[] includeProperty, + final int j, + final Object oldVersion, + final Object object, + final String sql, + final SessionImplementor session) throws HibernateException { if ( !isInverseTable( j ) ) { @@ -2346,68 +3194,70 @@ } + private BasicBatchKey updateBatchKey; + protected boolean update( final Serializable id, - final Object[] fields, - final Object[] oldFields, - final Object rowId, - final boolean[] includeProperty, - final int j, - final Object oldVersion, - final Object object, - final String sql, - final SessionImplementor session) throws HibernateException { + final Object[] fields, + final Object[] oldFields, + final Object rowId, + final boolean[] includeProperty, + final int j, + final Object oldVersion, + final Object object, + final String sql, + final SessionImplementor session) throws HibernateException { - final boolean useVersion = j == 0 && isVersioned(); final Expectation expectation = Expectations.appropriateExpectation( updateResultCheckStyles[j] ); - final boolean callable = isUpdateCallable( j ); final boolean useBatch = j == 0 && expectation.canBeBatched() && isBatchable(); //note: updates to joined tables can't be batched... + if ( useBatch && updateBatchKey == null ) { + updateBatchKey = new BasicBatchKey( + getEntityName() + "#UPDATE", + expectation + ); + } + final boolean callable = isUpdateCallable( j ); + final boolean useVersion = j == 0 && isVersioned(); - if ( log.isTraceEnabled() ) { - log.trace( "Updating entity: " + MessageHelper.infoString( this, id, getFactory() ) ); - if ( useVersion ) { - log.trace( "Existing version: " + oldVersion + " -> New version: " + fields[getVersionProperty()] ); - } + if ( LOG.isTraceEnabled() ) { + LOG.tracev( "Updating entity: {0}", MessageHelper.infoString( this, id, getFactory() ) ); + if ( useVersion ) + LOG.tracev( "Existing version: {0} -> New version:{1}", oldVersion, fields[getVersionProperty()] ); } try { - int index = 1; // starting index final PreparedStatement update; if ( useBatch ) { - if ( callable ) { - update = session.getBatcher().prepareBatchCallableStatement( sql ); - } - else { - update = session.getBatcher().prepareBatchStatement( sql ); - } + update = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getBatch( updateBatchKey ) + .getBatchStatement( sql, callable ); } else { - if ( callable ) { - update = session.getBatcher().prepareCallableStatement( sql ); - } - else { - update = session.getBatcher().prepareStatement( sql ); - } + update = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( sql, callable ); } try { - index+= expectation.prepare( update ); //Now write the values of fields onto the prepared statement - index = dehydrate( id, fields, rowId, includeProperty, propertyColumnUpdateable, j, update, session, index ); + index = dehydrate( id, fields, rowId, includeProperty, propertyColumnUpdateable, j, update, session, index, true ); // Write any appropriate versioning conditional parameters - if ( useVersion && Versioning.OPTIMISTIC_LOCK_VERSION == entityMetamodel.getOptimisticLockMode() ) { + if ( useVersion && entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.VERSION ) { if ( checkVersion( includeProperty ) ) { getVersionType().nullSafeSet( update, oldVersion, index, session ); } } - else if ( entityMetamodel.getOptimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION && oldFields != null ) { + else if ( isAllOrDirtyOptLocking() && oldFields != null ) { boolean[] versionability = getPropertyVersionability(); //TODO: is this really necessary???? - boolean[] includeOldField = entityMetamodel.getOptimisticLockMode() == Versioning.OPTIMISTIC_LOCK_ALL ? - getPropertyUpdateability() : includeProperty; + boolean[] includeOldField = entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.ALL + ? getPropertyUpdateability() + : includeProperty; Type[] types = getPropertyTypes(); for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) { boolean include = includeOldField[i] && @@ -2428,37 +3278,38 @@ } if ( useBatch ) { - session.getBatcher().addToBatch( expectation ); + session.getTransactionCoordinator().getJdbcCoordinator().getBatch( updateBatchKey ).addToBatch(); return true; } else { - return check( update.executeUpdate(), id, j, expectation, update ); + return check( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( update ), id, j, expectation, update ); } } - catch ( SQLException sqle ) { + catch ( SQLException e ) { if ( useBatch ) { - session.getBatcher().abortBatch( sqle ); + session.getTransactionCoordinator().getJdbcCoordinator().abortBatch(); } - throw sqle; + throw e; } finally { if ( !useBatch ) { - session.getBatcher().closeStatement( update ); + session.getTransactionCoordinator().getJdbcCoordinator().release( update ); } } } - catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - getFactory().getSQLExceptionConverter(), - sqle, + catch ( SQLException e ) { + throw getFactory().getSQLExceptionHelper().convert( + e, "could not update: " + MessageHelper.infoString( this, id, getFactory() ), sql ); } } + private BasicBatchKey deleteBatchKey; + /** * Perform an SQL DELETE */ @@ -2479,41 +3330,42 @@ final boolean callable = isDeleteCallable( j ); final Expectation expectation = Expectations.appropriateExpectation( deleteResultCheckStyles[j] ); final boolean useBatch = j == 0 && isBatchable() && expectation.canBeBatched(); + if ( useBatch && deleteBatchKey == null ) { + deleteBatchKey = new BasicBatchKey( + getEntityName() + "#DELETE", + expectation + ); + } - if ( log.isTraceEnabled() ) { - log.trace( "Deleting entity: " + MessageHelper.infoString( this, id, getFactory() ) ); - if ( useVersion ) { - log.trace( "Version: " + version ); - } + final boolean traceEnabled = LOG.isTraceEnabled(); + if ( traceEnabled ) { + LOG.tracev( "Deleting entity: {0}", MessageHelper.infoString( this, id, getFactory() ) ); + if ( useVersion ) + LOG.tracev( "Version: {0}", version ); } if ( isTableCascadeDeleteEnabled( j ) ) { - if ( log.isTraceEnabled() ) { - log.trace( "delete handled by foreign key constraint: " + getTableName( j ) ); + if ( traceEnabled ) { + LOG.tracev( "Delete handled by foreign key constraint: {0}", getTableName( j ) ); } return; //EARLY EXIT! } try { - //Render the SQL query PreparedStatement delete; int index = 1; if ( useBatch ) { - if ( callable ) { - delete = session.getBatcher().prepareBatchCallableStatement( sql ); - } - else { - delete = session.getBatcher().prepareBatchStatement( sql ); - } + delete = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getBatch( deleteBatchKey ) + .getBatchStatement( sql, callable ); } else { - if ( callable ) { - delete = session.getBatcher().prepareCallableStatement( sql ); - } - else { - delete = session.getBatcher().prepareStatement( sql ); - } + delete = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( sql, callable ); } try { @@ -2530,7 +3382,7 @@ if ( useVersion ) { getVersionType().nullSafeSet( delete, version, index, session ); } - else if ( entityMetamodel.getOptimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION && loadedState != null ) { + else if ( isAllOrDirtyOptLocking() && loadedState != null ) { boolean[] versionability = getPropertyVersionability(); Type[] types = getPropertyTypes(); for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) { @@ -2545,29 +3397,28 @@ } if ( useBatch ) { - session.getBatcher().addToBatch( expectation ); + session.getTransactionCoordinator().getJdbcCoordinator().getBatch( deleteBatchKey ).addToBatch(); } else { - check( delete.executeUpdate(), id, j, expectation, delete ); + check( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( delete ), id, j, expectation, delete ); } } catch ( SQLException sqle ) { if ( useBatch ) { - session.getBatcher().abortBatch( sqle ); + session.getTransactionCoordinator().getJdbcCoordinator().abortBatch(); } throw sqle; } finally { if ( !useBatch ) { - session.getBatcher().closeStatement( delete ); + session.getTransactionCoordinator().getJdbcCoordinator().release( delete ); } } } catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - getFactory().getSQLExceptionConverter(), + throw getFactory().getSQLExceptionHelper().convert( sqle, "could not delete: " + MessageHelper.infoString( this, id, getFactory() ), @@ -2592,15 +3443,27 @@ */ public void update( final Serializable id, - final Object[] fields, - final int[] dirtyFields, - final boolean hasDirtyCollection, - final Object[] oldFields, - final Object oldVersion, - final Object object, - final Object rowId, - final SessionImplementor session) throws HibernateException { + final Object[] fields, + final int[] dirtyFields, + final boolean hasDirtyCollection, + final Object[] oldFields, + final Object oldVersion, + final Object object, + final Object rowId, + final SessionImplementor session) throws HibernateException { + // apply any pre-update in-memory value generation + if ( getEntityMetamodel().hasPreUpdateGeneratedValues() ) { + final InMemoryValueGenerationStrategy[] strategies = getEntityMetamodel().getInMemoryValueGenerationStrategies(); + for ( int i = 0; i < strategies.length; i++ ) { + if ( strategies[i] != null && strategies[i].getGenerationTiming().includesUpdate() ) { + fields[i] = strategies[i].getValueGenerator().generateValue( (Session) session, object ); + setPropertyValue( object, i, fields[i] ); + // todo : probably best to add to dirtyFields if not-null + } + } + } + //note: dirtyFields==null means we had no snapshot, and we couldn't get one using select-before-update // oldFields==null just means we had no snapshot to begin with (we might have used select-before-update to get the dirtyFields) @@ -2609,8 +3472,15 @@ final boolean[] propsToUpdate; final String[] updateStrings; - if ( entityMetamodel.isDynamicUpdate() && dirtyFields != null ) { - // For the case of dynamic-update="true", we need to generate the UPDATE SQL + EntityEntry entry = session.getPersistenceContext().getEntry( object ); + + // Ensure that an immutable or non-modifiable entity is not being updated unless it is + // in the process of being deleted. + if ( entry == null && ! isMutable() ) { + throw new IllegalStateException( "Updating immutable entity that is not in session yet!" ); + } + if ( ( entityMetamodel.isDynamicUpdate() && dirtyFields != null ) ) { + // We need to generate the UPDATE SQL when dynamic-update="true" propsToUpdate = getPropertiesToUpdate( dirtyFields, hasDirtyCollection ); // don't need to check laziness (dirty checking algorithm handles that) updateStrings = new String[span]; @@ -2620,13 +3490,33 @@ null; } } + else if ( ! isModifiableEntity( entry ) ) { + // We need to generate UPDATE SQL when a non-modifiable entity (e.g., read-only or immutable) + // needs: + // - to have references to transient entities set to null before being deleted + // - to have version incremented do to a "dirty" association + // If dirtyFields == null, then that means that there are no dirty properties to + // to be updated; an empty array for the dirty fields needs to be passed to + // getPropertiesToUpdate() instead of null. + propsToUpdate = getPropertiesToUpdate( + ( dirtyFields == null ? ArrayHelper.EMPTY_INT_ARRAY : dirtyFields ), + hasDirtyCollection + ); + // don't need to check laziness (dirty checking algorithm handles that) + updateStrings = new String[span]; + for ( int j = 0; j < span; j++ ) { + updateStrings[j] = tableUpdateNeeded[j] ? + generateUpdateString( propsToUpdate, j, oldFields, j == 0 && rowId != null ) : + null; + } + } else { // For the case of dynamic-update="false", or no snapshot, we use the static SQL updateStrings = getUpdateStrings( rowId != null, - hasUninitializedLazyProperties( object, session.getEntityMode() ) - ); - propsToUpdate = getPropertyUpdateability( object, session.getEntityMode() ); + hasUninitializedLazyProperties( object ) + ); + propsToUpdate = getPropertyUpdateability( object ); } for ( int j = 0; j < span; j++ ) { @@ -2650,7 +3540,9 @@ public Serializable insert(Object[] fields, Object object, SessionImplementor session) throws HibernateException { - + // apply any pre-insert in-memory value generation + preInsertInMemoryValueGeneration( fields, object, session ); + final int span = getTableSpan(); final Serializable id; if ( entityMetamodel.isDynamicInsert() ) { @@ -2671,8 +3563,9 @@ return id; } - public void insert(Serializable id, Object[] fields, Object object, SessionImplementor session) - throws HibernateException { + public void insert(Serializable id, Object[] fields, Object object, SessionImplementor session) { + // apply any pre-insert in-memory value generation + preInsertInMemoryValueGeneration( fields, object, session ); final int span = getTableSpan(); if ( entityMetamodel.isDynamicInsert() ) { @@ -2689,21 +3582,33 @@ } } } + + private void preInsertInMemoryValueGeneration(Object[] fields, Object object, SessionImplementor session) { + if ( getEntityMetamodel().hasPreInsertGeneratedValues() ) { + final InMemoryValueGenerationStrategy[] strategies = getEntityMetamodel().getInMemoryValueGenerationStrategies(); + for ( int i = 0; i < strategies.length; i++ ) { + if ( strategies[i] != null && strategies[i].getGenerationTiming().includesInsert() ) { + fields[i] = strategies[i].getValueGenerator().generateValue( (Session) session, object ); + setPropertyValue( object, i, fields[i] ); + } + } + } + } /** * Delete an object */ public void delete(Serializable id, Object version, Object object, SessionImplementor session) throws HibernateException { final int span = getTableSpan(); - boolean isImpliedOptimisticLocking = !entityMetamodel.isVersioned() && entityMetamodel.getOptimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION; + boolean isImpliedOptimisticLocking = !entityMetamodel.isVersioned() && isAllOrDirtyOptLocking(); Object[] loadedState = null; if ( isImpliedOptimisticLocking ) { // need to treat this as if it where optimistic-lock="all" (dirty does *not* make sense); // first we need to locate the "loaded" state // - // Note, it potentially could be a proxy, so perform the location the safe way... - EntityKey key = new EntityKey( id, this, session.getEntityMode() ); + // Note, it potentially could be a proxy, so doAfterTransactionCompletion the location the safe way... + final EntityKey key = session.generateEntityKey( id, this ); Object entity = session.getPersistenceContext().getEntity( key ); if ( entity != null ) { EntityEntry entry = session.getPersistenceContext().getEntry( entity ); @@ -2727,13 +3632,18 @@ } + private boolean isAllOrDirtyOptLocking() { + return entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.DIRTY + || entityMetamodel.getOptimisticLockStyle() == OptimisticLockStyle.ALL; + } + private String[] generateSQLDeletStrings(Object[] loadedState) { int span = getTableSpan(); String[] deleteStrings = new String[span]; for ( int j = span - 1; j >= 0; j-- ) { Delete delete = new Delete() .setTableName( getTableName( j ) ) - .setPrimaryKeyColumnNames( getKeyColumns( j ) ); + .addPrimaryKeyColumns( getKeyColumns( j ) ); if ( getFactory().getSettings().isCommentsEnabled() ) { delete.setComment( "delete " + getEntityName() + " [" + j + "]" ); } @@ -2762,48 +3672,54 @@ } protected void logStaticSQL() { - if ( log.isDebugEnabled() ) { - log.debug( "Static SQL for entity: " + getEntityName() ); - if ( sqlLazySelectString != null ) { - log.debug( " Lazy select: " + sqlLazySelectString ); + if ( LOG.isDebugEnabled() ) { + LOG.debugf( "Static SQL for entity: %s", getEntityName() ); + if ( sqlLazySelectString != null ) { + LOG.debugf( " Lazy select: %s", sqlLazySelectString ); } - if ( sqlVersionSelectString != null ) { - log.debug( " Version select: " + sqlVersionSelectString ); + if ( sqlVersionSelectString != null ) { + LOG.debugf( " Version select: %s", sqlVersionSelectString ); } - if ( sqlSnapshotSelectString != null ) { - log.debug( " Snapshot select: " + sqlSnapshotSelectString ); + if ( sqlSnapshotSelectString != null ) { + LOG.debugf( " Snapshot select: %s", sqlSnapshotSelectString ); } for ( int j = 0; j < getTableSpan(); j++ ) { - log.debug( " Insert " + j + ": " + getSQLInsertStrings()[j] ); - log.debug( " Update " + j + ": " + getSQLUpdateStrings()[j] ); - log.debug( " Delete " + j + ": " + getSQLDeleteStrings()[j] ); - + LOG.debugf( " Insert %s: %s", j, getSQLInsertStrings()[j] ); + LOG.debugf( " Update %s: %s", j, getSQLUpdateStrings()[j] ); + LOG.debugf( " Delete %s: %s", j, getSQLDeleteStrings()[j] ); } - if ( sqlIdentityInsertString != null ) { - log.debug( " Identity insert: " + sqlIdentityInsertString ); + if ( sqlIdentityInsertString != null ) { + LOG.debugf( " Identity insert: %s", sqlIdentityInsertString ); } - if ( sqlUpdateByRowIdString != null ) { - log.debug( " Update by row id (all fields): " + sqlUpdateByRowIdString ); + if ( sqlUpdateByRowIdString != null ) { + LOG.debugf( " Update by row id (all fields): %s", sqlUpdateByRowIdString ); } - if ( sqlLazyUpdateByRowIdString != null ) { - log.debug( " Update by row id (non-lazy fields): " + sqlLazyUpdateByRowIdString ); + if ( sqlLazyUpdateByRowIdString != null ) { + LOG.debugf( " Update by row id (non-lazy fields): %s", sqlLazyUpdateByRowIdString ); } - if ( sqlInsertGeneratedValuesSelectString != null ) { - log.debug( "Insert-generated property select: " + sqlInsertGeneratedValuesSelectString ); + if ( sqlInsertGeneratedValuesSelectString != null ) { + LOG.debugf( " Insert-generated property select: %s", sqlInsertGeneratedValuesSelectString ); } - if ( sqlUpdateGeneratedValuesSelectString != null ) { - log.debug( "Update-generated property select: " + sqlUpdateGeneratedValuesSelectString ); + if ( sqlUpdateGeneratedValuesSelectString != null ) { + LOG.debugf( " Update-generated property select: %s", sqlUpdateGeneratedValuesSelectString ); } } } + @Override public String filterFragment(String alias, Map enabledFilters) throws MappingException { - final StringBuffer sessionFilterFragment = new StringBuffer(); - filterHelper.render( sessionFilterFragment, generateFilterConditionAlias( alias ), enabledFilters ); - + final StringBuilder sessionFilterFragment = new StringBuilder(); + filterHelper.render( sessionFilterFragment, getFilterAliasGenerator(alias), enabledFilters ); return sessionFilterFragment.append( filterFragment( alias ) ).toString(); } + @Override + public String filterFragment(String alias, Map enabledFilters, Set treatAsDeclarations) { + final StringBuilder sessionFilterFragment = new StringBuilder(); + filterHelper.render( sessionFilterFragment, getFilterAliasGenerator(alias), enabledFilters ); + return sessionFilterFragment.append( filterFragment( alias, treatAsDeclarations ) ).toString(); + } + public String generateFilterConditionAlias(String rootAlias) { return rootAlias; } @@ -2812,55 +3728,137 @@ return ""; } + @Override + public String oneToManyFilterFragment(String alias, Set treatAsDeclarations) { + return oneToManyFilterFragment( alias ); + } + + @Override public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) { - return getSubclassTableSpan() == 1 ? - "" : //just a performance opt! - createJoin( alias, innerJoin, includeSubclasses ).toFromFragmentString(); + // NOTE : Not calling createJoin here is just a performance optimization + return getSubclassTableSpan() == 1 + ? "" + : createJoin( alias, innerJoin, includeSubclasses, Collections.emptySet() ).toFromFragmentString(); } + @Override + public String fromJoinFragment( + String alias, + boolean innerJoin, + boolean includeSubclasses, + Set treatAsDeclarations) { + // NOTE : Not calling createJoin here is just a performance optimization + return getSubclassTableSpan() == 1 + ? "" + : createJoin( alias, innerJoin, includeSubclasses, treatAsDeclarations ).toFromFragmentString(); + } + + @Override public String whereJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) { - return getSubclassTableSpan() == 1 ? - "" : //just a performance opt! - createJoin( alias, innerJoin, includeSubclasses ).toWhereFragmentString(); + // NOTE : Not calling createJoin here is just a performance optimization + return getSubclassTableSpan() == 1 + ? "" + : createJoin( alias, innerJoin, includeSubclasses, Collections.emptySet() ).toWhereFragmentString(); } + @Override + public String whereJoinFragment( + String alias, + boolean innerJoin, + boolean includeSubclasses, + Set treatAsDeclarations) { + // NOTE : Not calling createJoin here is just a performance optimization + return getSubclassTableSpan() == 1 + ? "" + : createJoin( alias, innerJoin, includeSubclasses, treatAsDeclarations ).toWhereFragmentString(); + } + protected boolean isSubclassTableLazy(int j) { return false; } - protected JoinFragment createJoin(String name, boolean innerJoin, boolean includeSubclasses) { - final String[] idCols = StringHelper.qualify( name, getIdentifierColumnNames() ); //all joins join to the pk of the driving table + protected JoinFragment createJoin(String name, boolean innerJoin, boolean includeSubclasses, Set treatAsDeclarations) { + // IMPL NOTE : all joins join to the pk of the driving table + final String[] idCols = StringHelper.qualify( name, getIdentifierColumnNames() ); final JoinFragment join = getFactory().getDialect().createOuterJoinFragment(); final int tableSpan = getSubclassTableSpan(); - for ( int j = 1; j < tableSpan; j++ ) { //notice that we skip the first table; it is the driving table! - final boolean joinIsIncluded = isClassOrSuperclassTable( j ) || - ( includeSubclasses && !isSubclassTableSequentialSelect( j ) && !isSubclassTableLazy( j ) ); - if ( joinIsIncluded ) { - join.addJoin( getSubclassTableName( j ), + // IMPL NOTE : notice that we skip the first table; it is the driving table! + for ( int j = 1; j < tableSpan; j++ ) { + final JoinType joinType = determineSubclassTableJoinType( + j, + innerJoin, + includeSubclasses, + treatAsDeclarations + ); + + if ( joinType != null && joinType != JoinType.NONE ) { + join.addJoin( + getSubclassTableName( j ), generateTableAlias( name, j ), idCols, getSubclassTableKeyColumns( j ), - innerJoin && isClassOrSuperclassTable( j ) && !isInverseTable( j ) && !isNullableTable( j ) ? - JoinFragment.INNER_JOIN : //we can inner join to superclass tables (the row MUST be there) - JoinFragment.LEFT_OUTER_JOIN //we can never inner join to subclass tables - ); + joinType + ); } } return join; } + protected JoinType determineSubclassTableJoinType( + int subclassTableNumber, + boolean canInnerJoin, + boolean includeSubclasses, + Set treatAsDeclarations) { + + if ( isClassOrSuperclassTable( subclassTableNumber ) ) { + final boolean shouldInnerJoin = canInnerJoin + && !isInverseTable( subclassTableNumber ) + && !isNullableTable( subclassTableNumber ); + // the table is either this persister's driving table or (one of) its super class persister's driving + // tables which can be inner joined as long as the `shouldInnerJoin` condition resolves to true + return shouldInnerJoin ? JoinType.INNER_JOIN : JoinType.LEFT_OUTER_JOIN; + } + + // otherwise we have a subclass table and need to look a little deeper... + + // IMPL NOTE : By default includeSubclasses indicates that all subclasses should be joined and that each + // subclass ought to be joined by outer-join. However, TREAT-AS always requires that an inner-join be used + // so we give TREAT-AS higher precedence... + + if ( isSubclassTableIndicatedByTreatAsDeclarations( subclassTableNumber, treatAsDeclarations ) ) { + return JoinType.INNER_JOIN; + } + + if ( includeSubclasses + && !isSubclassTableSequentialSelect( subclassTableNumber ) + && !isSubclassTableLazy( subclassTableNumber ) ) { + return JoinType.LEFT_OUTER_JOIN; + } + + return JoinType.NONE; + } + + protected boolean isSubclassTableIndicatedByTreatAsDeclarations( + int subclassTableNumber, + Set treatAsDeclarations) { + return false; + } + + protected JoinFragment createJoin(int[] tableNumbers, String drivingAlias) { final String[] keyCols = StringHelper.qualify( drivingAlias, getSubclassTableKeyColumns( tableNumbers[0] ) ); final JoinFragment jf = getFactory().getDialect().createOuterJoinFragment(); - for ( int i = 1; i < tableNumbers.length; i++ ) { //skip the driving table + // IMPL NOTE : notice that we skip the first table; it is the driving table! + for ( int i = 1; i < tableNumbers.length; i++ ) { final int j = tableNumbers[i]; jf.addJoin( getSubclassTableName( j ), generateTableAlias( getRootAlias(), j ), keyCols, getSubclassTableKeyColumns( j ), - isInverseSubclassTable( j ) || isNullableSubclassTable( j ) ? - JoinFragment.LEFT_OUTER_JOIN : - JoinFragment.INNER_JOIN ); + isInverseSubclassTable( j ) || isNullableSubclassTable( j ) + ? JoinType.LEFT_OUTER_JOIN + : JoinType.INNER_JOIN + ); } return jf; } @@ -2872,12 +3870,12 @@ int[] columnTableNumbers = getSubclassColumnTableNumberClosure(); String[] columnAliases = getSubclassColumnAliasClosure(); - String[] columns = getSubclassColumnClosure(); + String[] columnReaderTemplates = getSubclassColumnReaderTemplateClosure(); for ( int i = 0; i < subclassColumnNumbers.length; i++ ) { - if ( subclassColumnSelectableClosure[i] ) { - int columnNumber = subclassColumnNumbers[i]; + int columnNumber = subclassColumnNumbers[i]; + if ( subclassColumnSelectableClosure[columnNumber] ) { final String subalias = generateTableAlias( getRootAlias(), columnTableNumbers[columnNumber] ); - selectFragment.addColumn( subalias, columns[columnNumber], columnAliases[columnNumber] ); + selectFragment.addColumnTemplate( subalias, columnReaderTemplates[columnNumber], columnAliases[columnNumber] ); } } @@ -2938,9 +3936,23 @@ return StringHelper.generateAlias( getEntityName() ); } + /** + * Post-construct is a callback for AbstractEntityPersister subclasses to call after they are all done with their + * constructor processing. It allows AbstractEntityPersister to extend its construction after all subclass-specific + * details have been handled. + * + * @param mapping The mapping + * + * @throws MappingException Indicates a problem accessing the Mapping + */ protected void postConstruct(Mapping mapping) throws MappingException { - initPropertyPaths(mapping); + initPropertyPaths( mapping ); + //doLateInit(); + prepareEntityIdentifierDefinition(); + } + + private void doLateInit() { //insert/update/delete SQL final int joinSpan = getTableSpan(); sqlDeleteStrings = new String[joinSpan]; @@ -2997,18 +4009,29 @@ } logStaticSQL(); - } - public void postInstantiate() throws MappingException { + public final void postInstantiate() throws MappingException { + doLateInit(); createLoaders(); createUniqueKeyLoaders(); createQueryLoader(); + doPostInstantiate(); } - private void createLoaders() { + protected void doPostInstantiate() { + } + + //needed by subclasses to override the createLoader strategy + protected Map getLoaders() { + return loaders; + } + + //Relational based Persisters should be content with this implementation + protected void createLoaders() { + final Map loaders = getLoaders(); loaders.put( LockMode.NONE, createEntityLoader( LockMode.NONE ) ); UniqueEntityLoader readLoader = createEntityLoader( LockMode.READ ); @@ -3032,19 +4055,45 @@ createEntityLoader( LockMode.UPGRADE_NOWAIT ) ); loaders.put( + LockMode.UPGRADE_SKIPLOCKED, + disableForUpdate ? + readLoader : + createEntityLoader( LockMode.UPGRADE_SKIPLOCKED ) + ); + loaders.put( LockMode.FORCE, disableForUpdate ? readLoader : createEntityLoader( LockMode.FORCE ) ); + loaders.put( + LockMode.PESSIMISTIC_READ, + disableForUpdate ? + readLoader : + createEntityLoader( LockMode.PESSIMISTIC_READ ) + ); + loaders.put( + LockMode.PESSIMISTIC_WRITE, + disableForUpdate ? + readLoader : + createEntityLoader( LockMode.PESSIMISTIC_WRITE ) + ); + loaders.put( + LockMode.PESSIMISTIC_FORCE_INCREMENT, + disableForUpdate ? + readLoader : + createEntityLoader( LockMode.PESSIMISTIC_FORCE_INCREMENT ) + ); + loaders.put( LockMode.OPTIMISTIC, createEntityLoader( LockMode.OPTIMISTIC) ); + loaders.put( LockMode.OPTIMISTIC_FORCE_INCREMENT, createEntityLoader(LockMode.OPTIMISTIC_FORCE_INCREMENT) ); loaders.put( "merge", - new CascadeEntityLoader( this, CascadingAction.MERGE, getFactory() ) + new CascadeEntityLoader( this, CascadingActions.MERGE, getFactory() ) ); loaders.put( "refresh", - new CascadeEntityLoader( this, CascadingAction.REFRESH, getFactory() ) + new CascadeEntityLoader( this, CascadingActions.REFRESH, getFactory() ) ); } @@ -3058,35 +4107,78 @@ * Load an instance using either the forUpdateLoader or the outer joining loader, * depending upon the value of the lock parameter */ - public Object load(Serializable id, Object optionalObject, LockMode lockMode, SessionImplementor session) + public Object load(Serializable id, Object optionalObject, LockMode lockMode, SessionImplementor session) { + return load( id, optionalObject, new LockOptions().setLockMode(lockMode), session ); + } + + /** + * Load an instance using either the forUpdateLoader or the outer joining loader, + * depending upon the value of the lock parameter + */ + public Object load(Serializable id, Object optionalObject, LockOptions lockOptions, SessionImplementor session) throws HibernateException { - if ( log.isTraceEnabled() ) { - log.trace( - "Fetching entity: " + - MessageHelper.infoString( this, id, getFactory() ) - ); + if ( LOG.isTraceEnabled() ) { + LOG.tracev( "Fetching entity: {0}", MessageHelper.infoString( this, id, getFactory() ) ); } - final UniqueEntityLoader loader = getAppropriateLoader( lockMode, session ); - return loader.load( id, optionalObject, session ); + final UniqueEntityLoader loader = getAppropriateLoader(lockOptions, session ); + return loader.load( id, optionalObject, session, lockOptions ); } - private UniqueEntityLoader getAppropriateLoader(LockMode lockMode, SessionImplementor session) { - final Map enabledFilters = session.getEnabledFilters(); + public void registerAffectingFetchProfile(String fetchProfileName) { + affectingFetchProfileNames.add( fetchProfileName ); + } + + private boolean isAffectedByEntityGraph(SessionImplementor session) { + return session.getLoadQueryInfluencers().getFetchGraph() != null || session.getLoadQueryInfluencers() + .getLoadGraph() != null; + } + + private boolean isAffectedByEnabledFetchProfiles(SessionImplementor session) { + for ( String s : session.getLoadQueryInfluencers().getEnabledFetchProfileNames() ) { + if ( affectingFetchProfileNames.contains( s ) ) { + return true; + } + } + return false; + } + + private boolean isAffectedByEnabledFilters(SessionImplementor session) { + return session.getLoadQueryInfluencers().hasEnabledFilters() + && filterHelper.isAffectedBy( session.getLoadQueryInfluencers().getEnabledFilters() ); + } + + private UniqueEntityLoader getAppropriateLoader(LockOptions lockOptions, SessionImplementor session) { if ( queryLoader != null ) { + // if the user specified a custom query loader we need to that + // regardless of any other consideration return queryLoader; } - else if ( enabledFilters == null || enabledFilters.isEmpty() ) { - if ( session.getFetchProfile()!=null && LockMode.UPGRADE.greaterThan(lockMode) ) { - return (UniqueEntityLoader) loaders.get( session.getFetchProfile() ); - } - else { - return (UniqueEntityLoader) loaders.get( lockMode ); - } + else if ( isAffectedByEnabledFilters( session ) ) { + // because filters affect the rows returned (because they add + // restrictions) these need to be next in precedence + return createEntityLoader(lockOptions, session.getLoadQueryInfluencers() ); } + else if ( session.getLoadQueryInfluencers().getInternalFetchProfile() != null && LockMode.UPGRADE.greaterThan( lockOptions.getLockMode() ) ) { + // Next, we consider whether an 'internal' fetch profile has been set. + // This indicates a special fetch profile Hibernate needs applied + // (for its merge loading process e.g.). + return ( UniqueEntityLoader ) getLoaders().get( session.getLoadQueryInfluencers().getInternalFetchProfile() ); + } + else if ( isAffectedByEnabledFetchProfiles( session ) ) { + // If the session has associated influencers we need to adjust the + // SQL query used for loading based on those influencers + return createEntityLoader(lockOptions, session.getLoadQueryInfluencers() ); + } + else if ( isAffectedByEntityGraph( session ) ) { + return createEntityLoader( lockOptions, session.getLoadQueryInfluencers() ); + } + else if ( lockOptions.getTimeOut() != LockOptions.WAIT_FOREVER ) { + return createEntityLoader( lockOptions, session.getLoadQueryInfluencers() ); + } else { - return createEntityLoader( lockMode, enabledFilters ); + return ( UniqueEntityLoader ) getLoaders().get( lockOptions.getLockMode() ); } } @@ -3116,7 +4208,7 @@ propsToUpdate[property] = true; } } - if ( isVersioned() ) { + if ( isVersioned() && updateability[getVersionProperty() ]) { propsToUpdate[ getVersionProperty() ] = Versioning.isVersionIncrementRequired( dirtyProperties, hasDirtyCollection, getPropertyVersionability() ); } @@ -3142,18 +4234,18 @@ * @param currentState The current state of the entity (the state to be checked). * @param previousState The previous state of the entity (the state to be checked against). * @param entity The entity for which we are checking state dirtiness. - * @param session The session in which the check is ccurring. + * @param session The session in which the check is occurring. * @return null or the indices of the dirty properties * @throws HibernateException */ public int[] findDirty(Object[] currentState, Object[] previousState, Object entity, SessionImplementor session) throws HibernateException { - int[] props = TypeFactory.findDirty( + int[] props = TypeHelper.findDirty( entityMetamodel.getProperties(), currentState, previousState, propertyColumnUpdateable, - hasUninitializedLazyProperties( entity, session.getEntityMode() ), + hasUninitializedLazyProperties( entity ), session ); if ( props == null ) { @@ -3171,18 +4263,18 @@ * @param old The old state of the entity. * @param current The current state of the entity. * @param entity The entity for which we are checking state modification. - * @param session The session in which the check is ccurring. + * @param session The session in which the check is occurring. * @return null or the indices of the modified properties * @throws HibernateException */ public int[] findModified(Object[] old, Object[] current, Object entity, SessionImplementor session) throws HibernateException { - int[] props = TypeFactory.findModified( + int[] props = TypeHelper.findModified( entityMetamodel.getProperties(), current, old, propertyColumnUpdateable, - hasUninitializedLazyProperties( entity, session.getEntityMode() ), + hasUninitializedLazyProperties( entity ), session ); if ( props == null ) { @@ -3198,29 +4290,21 @@ * Which properties appear in the SQL update? * (Initialized, updateable ones!) */ - protected boolean[] getPropertyUpdateability(Object entity, EntityMode entityMode) { - return hasUninitializedLazyProperties( entity, entityMode ) ? - getNonLazyPropertyUpdateability() : - getPropertyUpdateability(); + protected boolean[] getPropertyUpdateability(Object entity) { + return hasUninitializedLazyProperties( entity ) + ? getNonLazyPropertyUpdateability() + : getPropertyUpdateability(); } private void logDirtyProperties(int[] props) { - if ( log.isTraceEnabled() ) { + if ( LOG.isTraceEnabled() ) { for ( int i = 0; i < props.length; i++ ) { String propertyName = entityMetamodel.getProperties()[ props[i] ].getName(); - log.trace( StringHelper.qualify( getEntityName(), propertyName ) + " is dirty" ); + LOG.trace( StringHelper.qualify( getEntityName(), propertyName ) + " is dirty" ); } } } - protected EntityTuplizer getTuplizer(SessionImplementor session) { - return getTuplizer( session.getEntityMode() ); - } - - protected EntityTuplizer getTuplizer(EntityMode entityMode) { - return entityMetamodel.getTuplizer( entityMode ); - } - public SessionFactoryImplementor getFactory() { return factory; } @@ -3237,10 +4321,24 @@ return cacheAccessStrategy; } + @Override public CacheEntryStructure getCacheEntryStructure() { - return cacheEntryStructure; + return cacheEntryHelper.getCacheEntryStructure(); } + @Override + public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SessionImplementor session) { + return cacheEntryHelper.buildCacheEntry( entity, state, version, session ); + } + + public boolean hasNaturalIdCache() { + return naturalIdRegionAccessStrategy != null; + } + + public NaturalIdRegionAccessStrategy getNaturalIdCacheAccessStrategy() { + return naturalIdRegionAccessStrategy; + } + public Comparator getVersionComparator() { return isVersioned() ? getVersionType().getComparator() : null; } @@ -3254,10 +4352,6 @@ return entityMetamodel.getEntityType(); } - private String getSubclassEntityName(Class clazz) { - return ( String ) entityNameBySubclass.get( clazz ); - } - public boolean isPolymorphic() { return entityMetamodel.isPolymorphic(); } @@ -3311,14 +4405,13 @@ // } public void afterReassociate(Object entity, SessionImplementor session) { - //if ( hasLazyProperties() ) { - if ( FieldInterceptionHelper.isInstrumented( entity ) ) { - FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( entity ); + if ( getEntityMetamodel().getInstrumentationMetadata().isInstrumented() ) { + FieldInterceptor interceptor = getEntityMetamodel().getInstrumentationMetadata().extractInterceptor( entity ); if ( interceptor != null ) { interceptor.setSession( session ); } else { - FieldInterceptor fieldInterceptor = FieldInterceptionHelper.injectFieldInterceptor( + FieldInterceptor fieldInterceptor = getEntityMetamodel().getInstrumentationMetadata().injectInterceptor( entity, getEntityName(), null, @@ -3327,12 +4420,49 @@ fieldInterceptor.dirty(); } } + + handleNaturalIdReattachment( entity, session ); } + private void handleNaturalIdReattachment(Object entity, SessionImplementor session) { + if ( ! hasNaturalIdentifier() ) { + return; + } + + if ( getEntityMetamodel().hasImmutableNaturalId() ) { + // we assume there were no changes to natural id during detachment for now, that is validated later + // during flush. + return; + } + + final NaturalIdHelper naturalIdHelper = session.getPersistenceContext().getNaturalIdHelper(); + final Serializable id = getIdentifier( entity, session ); + + // for reattachment of mutable natural-ids, we absolutely positively have to grab the snapshot from the + // database, because we have no other way to know if the state changed while detached. + final Object[] naturalIdSnapshot; + final Object[] entitySnapshot = session.getPersistenceContext().getDatabaseSnapshot( id, this ); + if ( entitySnapshot == StatefulPersistenceContext.NO_ROW ) { + naturalIdSnapshot = null; + } + else { + naturalIdSnapshot = naturalIdHelper.extractNaturalIdValues( entitySnapshot, this ); + } + + naturalIdHelper.removeSharedNaturalIdCrossReference( this, id, naturalIdSnapshot ); + naturalIdHelper.manageLocalNaturalIdCrossReference( + this, + id, + naturalIdHelper.extractNaturalIdValues( entity, this ), + naturalIdSnapshot, + CachedNaturalIdValueSource.UPDATE + ); + } + public Boolean isTransient(Object entity, SessionImplementor session) throws HibernateException { final Serializable id; if ( canExtractIdOutOfEntity() ) { - id = getIdentifier( entity, session.getEntityMode() ); + id = getIdentifier( entity, session ); } else { id = null; @@ -3344,7 +4474,7 @@ } // check the version unsaved-value, if appropriate - final Object version = getVersion( entity, session.getEntityMode() ); + final Object version = getVersion( entity ); if ( isVersioned() ) { // let this take precedence if defined, since it works for // assigned identifiers @@ -3364,14 +4494,9 @@ // check to see if it is in the second-level cache if ( hasCache() ) { - CacheKey ck = new CacheKey( - id, - getIdentifierType(), - getRootEntityName(), - session.getEntityMode(), - session.getFactory() - ); - if ( getCacheAccessStrategy().get( ck, session.getTimestamp() ) != null ) { + final CacheKey ck = session.generateCacheKey( id, getIdentifierType(), getRootEntityName() ); + final Object ce = CacheHelper.fromSharedCache( session, ck, getCacheAccessStrategy() ); + if ( ce != null ) { return Boolean.FALSE; } } @@ -3391,6 +4516,11 @@ return entityMetamodel.isMutable(); } + private boolean isModifiableEntity(EntityEntry entry) { + + return ( entry == null ? isMutable() : entry.isModifiableEntity() ); + } + public boolean isAbstract() { return entityMetamodel.isAbstract(); } @@ -3464,7 +4594,7 @@ } public Type getPropertyType(String propertyName) throws MappingException { - return propertyMapping.toType(propertyName); + return propertyMapping.toType( propertyName ); } public Type getType() { @@ -3475,13 +4605,12 @@ return entityMetamodel.isSelectBeforeUpdate(); } - protected final int optimisticLockMode() { - return entityMetamodel.getOptimisticLockMode(); + protected final OptimisticLockStyle optimisticLockStyle() { + return entityMetamodel.getOptimisticLockStyle(); } public Object createProxy(Serializable id, SessionImplementor session) throws HibernateException { - return entityMetamodel.getTuplizer( session.getEntityMode() ) - .createProxy( id, session ); + return entityMetamodel.getTuplizer().createProxy( id, session ); } public String toString() { @@ -3499,9 +4628,8 @@ return selectFragment( lhsAlias, entitySuffix ); } - public boolean isInstrumented(EntityMode entityMode) { - EntityTuplizer tuplizer = entityMetamodel.getTuplizerOrNull(entityMode); - return tuplizer!=null && tuplizer.isInstrumented(); + public boolean isInstrumented() { + return entityMetamodel.isInstrumented(); } public boolean hasInsertGeneratedProperties() { @@ -3513,15 +4641,15 @@ } public boolean isVersionPropertyGenerated() { - return isVersioned() && ( getPropertyUpdateGenerationInclusions() [ getVersionProperty() ] != ValueInclusion.NONE ); + return isVersioned() && getEntityMetamodel().isVersionGenerated(); } public boolean isVersionPropertyInsertable() { return isVersioned() && getPropertyInsertability() [ getVersionProperty() ]; } public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) { - getTuplizer( session ).afterInitialize( entity, lazyPropertiesAreUnfetched, session ); + getEntityTuplizer().afterInitialize( entity, lazyPropertiesAreUnfetched, session ); } public String[] getPropertyNames() { @@ -3552,12 +4680,14 @@ return entityMetamodel.getPropertyInsertability(); } + @Deprecated public ValueInclusion[] getPropertyInsertGenerationInclusions() { - return entityMetamodel.getPropertyInsertGenerationInclusions(); + return null; } + @Deprecated public ValueInclusion[] getPropertyUpdateGenerationInclusions() { - return entityMetamodel.getPropertyUpdateGenerationInclusions(); + return null; } public boolean[] getPropertyNullability() { @@ -3572,110 +4702,101 @@ return entityMetamodel.getCascadeStyles(); } - public final Class getMappedClass(EntityMode entityMode) { - Tuplizer tup = entityMetamodel.getTuplizerOrNull(entityMode); - return tup==null ? null : tup.getMappedClass(); + public final Class getMappedClass() { + return getEntityTuplizer().getMappedClass(); } - public boolean implementsLifecycle(EntityMode entityMode) { - return getTuplizer( entityMode ).isLifecycleImplementor(); + public boolean implementsLifecycle() { + return getEntityTuplizer().isLifecycleImplementor(); } - public boolean implementsValidatable(EntityMode entityMode) { - return getTuplizer( entityMode ).isValidatableImplementor(); + public Class getConcreteProxyClass() { + return getEntityTuplizer().getConcreteProxyClass(); } - public Class getConcreteProxyClass(EntityMode entityMode) { - return getTuplizer( entityMode ).getConcreteProxyClass(); + public void setPropertyValues(Object object, Object[] values) { + getEntityTuplizer().setPropertyValues( object, values ); } - public void setPropertyValues(Object object, Object[] values, EntityMode entityMode) - throws HibernateException { - getTuplizer( entityMode ).setPropertyValues( object, values ); + public void setPropertyValue(Object object, int i, Object value) { + getEntityTuplizer().setPropertyValue( object, i, value ); } - public void setPropertyValue(Object object, int i, Object value, EntityMode entityMode) - throws HibernateException { - getTuplizer( entityMode ).setPropertyValue( object, i, value ); + public Object[] getPropertyValues(Object object) { + return getEntityTuplizer().getPropertyValues( object ); } - public Object[] getPropertyValues(Object object, EntityMode entityMode) - throws HibernateException { - return getTuplizer( entityMode ).getPropertyValues( object ); + @Override + public Object getPropertyValue(Object object, int i) { + return getEntityTuplizer().getPropertyValue( object, i ); } - public Object getPropertyValue(Object object, int i, EntityMode entityMode) - throws HibernateException { - return getTuplizer( entityMode ).getPropertyValue( object , i ); + @Override + public Object getPropertyValue(Object object, String propertyName) { + return getEntityTuplizer().getPropertyValue( object, propertyName ); } - public Object getPropertyValue(Object object, String propertyName, EntityMode entityMode) - throws HibernateException { - return getTuplizer( entityMode ).getPropertyValue( object, propertyName ); + @Override + public Serializable getIdentifier(Object object) { + return getEntityTuplizer().getIdentifier( object, null ); } - public Serializable getIdentifier(Object object, EntityMode entityMode) - throws HibernateException { - return getTuplizer( entityMode ).getIdentifier( object ); + @Override + public Serializable getIdentifier(Object entity, SessionImplementor session) { + return getEntityTuplizer().getIdentifier( entity, session ); } - public void setIdentifier(Object object, Serializable id, EntityMode entityMode) - throws HibernateException { - getTuplizer( entityMode ).setIdentifier( object, id ); + @Override + public void setIdentifier(Object entity, Serializable id, SessionImplementor session) { + getEntityTuplizer().setIdentifier( entity, id, session ); } - public Object getVersion(Object object, EntityMode entityMode) - throws HibernateException { - return getTuplizer( entityMode ).getVersion( object ); + @Override + public Object getVersion(Object object) { + return getEntityTuplizer().getVersion( object ); } - public Object instantiate(Serializable id, EntityMode entityMode) - throws HibernateException { - return getTuplizer( entityMode ).instantiate( id ); + @Override + public Object instantiate(Serializable id, SessionImplementor session) { + return getEntityTuplizer().instantiate( id, session ); } - public boolean isInstance(Object object, EntityMode entityMode) { - return getTuplizer( entityMode ).isInstance( object ); + @Override + public boolean isInstance(Object object) { + return getEntityTuplizer().isInstance( object ); } - public boolean hasUninitializedLazyProperties(Object object, EntityMode entityMode) { - return getTuplizer( entityMode ).hasUninitializedLazyProperties( object ); + @Override + public boolean hasUninitializedLazyProperties(Object object) { + return getEntityTuplizer().hasUninitializedLazyProperties( object ); } - public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion, EntityMode entityMode) { - getTuplizer( entityMode ).resetIdentifier( entity, currentId, currentVersion ); + @Override + public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion, SessionImplementor session) { + getEntityTuplizer().resetIdentifier( entity, currentId, currentVersion, session ); } - public EntityPersister getSubclassEntityPersister(Object instance, SessionFactoryImplementor factory, EntityMode entityMode) { + @Override + public EntityPersister getSubclassEntityPersister(Object instance, SessionFactoryImplementor factory) { if ( !hasSubclasses() ) { return this; } else { - // TODO : really need a way to do something like : - // getTuplizer(entityMode).determineConcreteSubclassEntityName(instance) - Class clazz = instance.getClass(); - if ( clazz == getMappedClass( entityMode ) ) { + final String concreteEntityName = getEntityTuplizer().determineConcreteSubclassEntityName( + instance, + factory + ); + if ( concreteEntityName == null || getEntityName().equals( concreteEntityName ) ) { + // the contract of EntityTuplizer.determineConcreteSubclassEntityName says that returning null + // is an indication that the specified entity-name (this.getEntityName) should be used. return this; } else { - String subclassEntityName = getSubclassEntityName( clazz ); - if ( subclassEntityName == null ) { - throw new HibernateException( - "instance not of expected entity type: " + clazz.getName() + - " is not a: " + getEntityName() - ); - } - else { - return factory.getEntityPersister( subclassEntityName ); - } + return factory.getEntityPersister( concreteEntityName ); } } } - public EntityMode guessEntityMode(Object object) { - return entityMetamodel.guessEntityMode(object); - } - public boolean isMultiTable() { return false; } @@ -3693,21 +4814,21 @@ } public Object[] getPropertyValuesToInsert(Object object, Map mergeMap, SessionImplementor session) throws HibernateException { - return getTuplizer( session.getEntityMode() ).getPropertyValuesToInsert( object, mergeMap, session ); + return getEntityTuplizer().getPropertyValuesToInsert( object, mergeMap, session ); } public void processInsertGeneratedProperties(Serializable id, Object entity, Object[] state, SessionImplementor session) { if ( !hasInsertGeneratedProperties() ) { throw new AssertionFailure("no insert-generated properties"); } - processGeneratedProperties( id, entity, state, session, sqlInsertGeneratedValuesSelectString, getPropertyInsertGenerationInclusions() ); + processGeneratedProperties( id, entity, state, session, sqlInsertGeneratedValuesSelectString, GenerationTiming.INSERT ); } public void processUpdateGeneratedProperties(Serializable id, Object entity, Object[] state, SessionImplementor session) { if ( !hasUpdateGeneratedProperties() ) { throw new AssertionFailure("no update-generated properties"); } - processGeneratedProperties( id, entity, state, session, sqlUpdateGeneratedValuesSelectString, getPropertyUpdateGenerationInclusions() ); + processGeneratedProperties( id, entity, state, session, sqlUpdateGeneratedValuesSelectString, GenerationTiming.ALWAYS ); } private void processGeneratedProperties( @@ -3716,51 +4837,83 @@ Object[] state, SessionImplementor session, String selectionSQL, - ValueInclusion[] includeds) { + GenerationTiming matchTiming) { + // force immediate execution of the insert batch (if one) + session.getTransactionCoordinator().getJdbcCoordinator().executeBatch(); - session.getBatcher().executeBatch(); //force immediate execution of the insert - try { - PreparedStatement ps = session.getBatcher().prepareSelectStatement( selectionSQL ); + PreparedStatement ps = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( selectionSQL ); try { getIdentifierType().nullSafeSet( ps, id, 1, session ); - ResultSet rs = ps.executeQuery(); + ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( ps ); try { if ( !rs.next() ) { throw new HibernateException( "Unable to locate row for retrieval of generated properties: " + MessageHelper.infoString( this, id, getFactory() ) ); } - for ( int i = 0; i < getPropertySpan(); i++ ) { - if ( includeds[i] != ValueInclusion.NONE ) { - Object hydratedState = getPropertyTypes()[i].hydrate( rs, getPropertyAliases( "", i ), session, entity ); - state[i] = getPropertyTypes()[i].resolve( hydratedState, session, entity ); - setPropertyValue( entity, i, state[i], session.getEntityMode() ); + int propertyIndex = -1; + for ( NonIdentifierAttribute attribute : entityMetamodel.getProperties() ) { + propertyIndex++; + final ValueGeneration valueGeneration = attribute.getValueGenerationStrategy(); + if ( isReadRequired( valueGeneration, matchTiming ) ) { + final Object hydratedState = attribute.getType().hydrate( + rs, getPropertyAliases( + "", + propertyIndex + ), session, entity + ); + state[propertyIndex] = attribute.getType().resolve( hydratedState, session, entity ); + setPropertyValue( entity, propertyIndex, state[propertyIndex] ); } } +// for ( int i = 0; i < getPropertySpan(); i++ ) { +// if ( includeds[i] != ValueInclusion.NONE ) { +// Object hydratedState = getPropertyTypes()[i].hydrate( rs, getPropertyAliases( "", i ), session, entity ); +// state[i] = getPropertyTypes()[i].resolve( hydratedState, session, entity ); +// setPropertyValue( entity, i, state[i] ); +// } +// } } finally { if ( rs != null ) { - rs.close(); + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, ps ); } } } finally { - session.getBatcher().closeStatement( ps ); + session.getTransactionCoordinator().getJdbcCoordinator().release( ps ); } } - catch( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - getFactory().getSQLExceptionConverter(), - sqle, + catch( SQLException e ) { + throw getFactory().getSQLExceptionHelper().convert( + e, "unable to select generated column values", selectionSQL ); } } + /** + * Whether the given value generation strategy requires to read the value from the database or not. + */ + private boolean isReadRequired(ValueGeneration valueGeneration, GenerationTiming matchTiming) { + return valueGeneration != null && + valueGeneration.getValueGenerator() == null && + timingsMatch( valueGeneration.getGenerationTiming(), matchTiming ); + } + + private boolean timingsMatch(GenerationTiming timing, GenerationTiming matchTiming) { + return + (matchTiming == GenerationTiming.INSERT && timing.includesInsert()) || + (matchTiming == GenerationTiming.ALWAYS && timing.includesUpdate()); + } + public String getIdentifierPropertyName() { return entityMetamodel.getIdentifierProperty().getName(); } @@ -3781,8 +4934,9 @@ if ( !hasNaturalIdentifier() ) { throw new MappingException( "persistent class did not define a natural-id : " + MessageHelper.infoString( this ) ); } - if ( log.isTraceEnabled() ) { - log.trace( "Getting current natural-id snapshot state for: " + MessageHelper.infoString( this, id, getFactory() ) ); + if ( LOG.isTraceEnabled() ) { + LOG.tracev( "Getting current natural-id snapshot state for: {0}", + MessageHelper.infoString( this, id, getFactory() ) ); } int[] naturalIdPropertyIndexes = getNaturalIdentifierProperties(); @@ -3804,7 +4958,7 @@ select.setFromClause( fromTableFragment( getRootAlias() ) + fromJoinFragment( getRootAlias(), true, false ) ); String[] aliasedIdColumns = StringHelper.qualify( getRootAlias(), getIdentifierColumnNames() ); - String whereClause = new StringBuffer() + String whereClause = new StringBuilder() .append( StringHelper.join( "=? and ", aliasedIdColumns ) ) .append( "=?" ) @@ -3818,40 +4972,203 @@ Object[] snapshot = new Object[ naturalIdPropertyCount ]; try { - PreparedStatement ps = session.getBatcher().prepareSelectStatement( sql ); + PreparedStatement ps = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( sql ); try { getIdentifierType().nullSafeSet( ps, id, 1, session ); - ResultSet rs = ps.executeQuery(); + ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( ps ); try { //if there is no resulting row, return null if ( !rs.next() ) { return null; } - + final EntityKey key = session.generateEntityKey( id, this ); + Object owner = session.getPersistenceContext().getEntity( key ); for ( int i = 0; i < naturalIdPropertyCount; i++ ) { snapshot[i] = extractionTypes[i].hydrate( rs, getPropertyAliases( "", naturalIdPropertyIndexes[i] ), session, null ); + if (extractionTypes[i].isEntityType()) { + snapshot[i] = extractionTypes[i].resolve(snapshot[i], session, owner); + } } return snapshot; } finally { - rs.close(); + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, ps ); } } finally { - session.getBatcher().closeStatement( ps ); + session.getTransactionCoordinator().getJdbcCoordinator().release( ps ); } } - catch ( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - getFactory().getSQLExceptionConverter(), - sqle, - "could not retrieve snapshot: " + - MessageHelper.infoString( this, id, getFactory() ), + catch ( SQLException e ) { + throw getFactory().getSQLExceptionHelper().convert( + e, + "could not retrieve snapshot: " + MessageHelper.infoString( this, id, getFactory() ), sql - ); + ); } } + @Override + public Serializable loadEntityIdByNaturalId( + Object[] naturalIdValues, + LockOptions lockOptions, + SessionImplementor session) { + if ( LOG.isTraceEnabled() ) { + LOG.tracef( + "Resolving natural-id [%s] to id : %s ", + naturalIdValues, + MessageHelper.infoString( this ) + ); + } + + final boolean[] valueNullness = determineValueNullness( naturalIdValues ); + final String sqlEntityIdByNaturalIdString = determinePkByNaturalIdQuery( valueNullness ); + + try { + PreparedStatement ps = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( sqlEntityIdByNaturalIdString ); + try { + int positions = 1; + int loop = 0; + for ( int idPosition : getNaturalIdentifierProperties() ) { + final Object naturalIdValue = naturalIdValues[loop++]; + if ( naturalIdValue != null ) { + final Type type = getPropertyTypes()[idPosition]; + type.nullSafeSet( ps, naturalIdValue, positions, session ); + positions += type.getColumnSpan( session.getFactory() ); + } + } + ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( ps ); + try { + // if there is no resulting row, return null + if ( !rs.next() ) { + return null; + } + + return (Serializable) getIdentifierType().hydrate( rs, getIdentifierAliases(), session, null ); + } + finally { + session.getTransactionCoordinator().getJdbcCoordinator().release( rs, ps ); + } + } + finally { + session.getTransactionCoordinator().getJdbcCoordinator().release( ps ); + } + } + catch ( SQLException e ) { + throw getFactory().getSQLExceptionHelper().convert( + e, + String.format( + "could not resolve natural-id [%s] to id : %s", + naturalIdValues, + MessageHelper.infoString( this ) + ), + sqlEntityIdByNaturalIdString + ); + } + } + + private boolean[] determineValueNullness(Object[] naturalIdValues) { + boolean[] nullness = new boolean[ naturalIdValues.length ]; + for ( int i = 0; i < naturalIdValues.length; i++ ) { + nullness[i] = naturalIdValues[i] == null; + } + return nullness; + } + + private Boolean naturalIdIsNonNullable; + private String cachedPkByNonNullableNaturalIdQuery; + + private String determinePkByNaturalIdQuery(boolean[] valueNullness) { + if ( ! hasNaturalIdentifier() ) { + throw new HibernateException( "Attempt to build natural-id -> PK resolution query for entity that does not define natural id" ); + } + + // performance shortcut for cases where the natural-id is defined as completely non-nullable + if ( isNaturalIdNonNullable() ) { + if ( valueNullness != null && ! ArrayHelper.isAllFalse( valueNullness ) ) { + throw new HibernateException( "Null value(s) passed to lookup by non-nullable natural-id" ); + } + if ( cachedPkByNonNullableNaturalIdQuery == null ) { + cachedPkByNonNullableNaturalIdQuery = generateEntityIdByNaturalIdSql( null ); + } + return cachedPkByNonNullableNaturalIdQuery; + } + + // Otherwise, regenerate it each time + return generateEntityIdByNaturalIdSql( valueNullness ); + } + + protected boolean isNaturalIdNonNullable() { + if ( naturalIdIsNonNullable == null ) { + naturalIdIsNonNullable = determineNaturalIdNullability(); + } + return naturalIdIsNonNullable; + } + + private boolean determineNaturalIdNullability() { + boolean[] nullability = getPropertyNullability(); + for ( int position : getNaturalIdentifierProperties() ) { + // if any individual property is nullable, return false + if ( nullability[position] ) { + return false; + } + } + // return true if we found no individually nullable properties + return true; + } + + private String generateEntityIdByNaturalIdSql(boolean[] valueNullness) { + EntityPersister rootPersister = getFactory().getEntityPersister( getRootEntityName() ); + if ( rootPersister != this ) { + if ( rootPersister instanceof AbstractEntityPersister ) { + return ( (AbstractEntityPersister) rootPersister ).generateEntityIdByNaturalIdSql( valueNullness ); + } + } + + Select select = new Select( getFactory().getDialect() ); + if ( getFactory().getSettings().isCommentsEnabled() ) { + select.setComment( "get current natural-id->entity-id state " + getEntityName() ); + } + + final String rootAlias = getRootAlias(); + + select.setSelectClause( identifierSelectFragment( rootAlias, "" ) ); + select.setFromClause( fromTableFragment( rootAlias ) + fromJoinFragment( rootAlias, true, false ) ); + + final StringBuilder whereClause = new StringBuilder(); + final int[] propertyTableNumbers = getPropertyTableNumbers(); + final int[] naturalIdPropertyIndexes = this.getNaturalIdentifierProperties(); + int valuesIndex = -1; + for ( int propIdx = 0; propIdx < naturalIdPropertyIndexes.length; propIdx++ ) { + valuesIndex++; + if ( propIdx > 0 ) { + whereClause.append( " and " ); + } + + final int naturalIdIdx = naturalIdPropertyIndexes[propIdx]; + final String tableAlias = generateTableAlias( rootAlias, propertyTableNumbers[naturalIdIdx] ); + final String[] propertyColumnNames = getPropertyColumnNames( naturalIdIdx ); + final String[] aliasedPropertyColumns = StringHelper.qualify( tableAlias, propertyColumnNames ); + + if ( valueNullness != null && valueNullness[valuesIndex] ) { + whereClause.append( StringHelper.join( " is null and ", aliasedPropertyColumns ) ).append( " is null" ); + } + else { + whereClause.append( StringHelper.join( "=? and ", aliasedPropertyColumns ) ).append( "=?" ); + } + } + + whereClause.append( whereJoinFragment( getRootAlias(), true, false ) ); + + return select.setOuterJoins( "", "" ).setWhereClause( whereClause.toString() ).toStatementString(); + } + protected String concretePropertySelectFragmentSansLeadingComma(String alias, boolean[] include) { String concretePropertySelectFragment = concretePropertySelectFragment( alias, include ); int firstComma = concretePropertySelectFragment.indexOf( ", " ); @@ -3860,14 +5177,327 @@ } return concretePropertySelectFragment; } + public boolean hasNaturalIdentifier() { return entityMetamodel.hasNaturalIdentifier(); } - public void setPropertyValue(Object object, String propertyName, Object value, EntityMode entityMode) - throws HibernateException { - getTuplizer( entityMode ).setPropertyValue( object, propertyName, value ); + public void setPropertyValue(Object object, String propertyName, Object value) { + getEntityTuplizer().setPropertyValue( object, propertyName, value ); } - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + public static int getTableId(String tableName, String[] tables) { + for ( int j = 0; j < tables.length; j++ ) { + if ( tableName.equalsIgnoreCase( tables[j] ) ) { + return j; + } + } + throw new AssertionFailure( "Table " + tableName + " not found" ); + } + + @Override + public EntityMode getEntityMode() { + return entityMetamodel.getEntityMode(); + } + @Override + public EntityTuplizer getEntityTuplizer() { + return entityTuplizer; + } + + @Override + public EntityInstrumentationMetadata getInstrumentationMetadata() { + return entityMetamodel.getInstrumentationMetadata(); + } + + @Override + public String getTableAliasForColumn(String columnName, String rootAlias) { + return generateTableAlias( rootAlias, determineTableNumberForColumn( columnName ) ); + } + + public int determineTableNumberForColumn(String columnName) { + return 0; + } + + /** + * Consolidated these onto a single helper because the 2 pieces work in tandem. + */ + public static interface CacheEntryHelper { + public CacheEntryStructure getCacheEntryStructure(); + + public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SessionImplementor session); + } + + private static class StandardCacheEntryHelper implements CacheEntryHelper { + private final EntityPersister persister; + + private StandardCacheEntryHelper(EntityPersister persister) { + this.persister = persister; + } + + @Override + public CacheEntryStructure getCacheEntryStructure() { + return UnstructuredCacheEntry.INSTANCE; + } + + @Override + public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SessionImplementor session) { + return new StandardCacheEntryImpl( + state, + persister, + persister.hasUninitializedLazyProperties( entity ), + version, + session, + entity + ); + } + } + + private static class ReferenceCacheEntryHelper implements CacheEntryHelper { + private final EntityPersister persister; + + private ReferenceCacheEntryHelper(EntityPersister persister) { + this.persister = persister; + } + + @Override + public CacheEntryStructure getCacheEntryStructure() { + return UnstructuredCacheEntry.INSTANCE; + } + + @Override + public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SessionImplementor session) { + return new ReferenceCacheEntryImpl( entity, persister.getEntityName() ); + } + } + + private static class StructuredCacheEntryHelper implements CacheEntryHelper { + private final EntityPersister persister; + private final StructuredCacheEntry structure; + + private StructuredCacheEntryHelper(EntityPersister persister) { + this.persister = persister; + this.structure = new StructuredCacheEntry( persister ); + } + + @Override + public CacheEntryStructure getCacheEntryStructure() { + return structure; + } + + @Override + public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SessionImplementor session) { + return new StandardCacheEntryImpl( + state, + persister, + persister.hasUninitializedLazyProperties( entity ), + version, + session, + entity + ); + } + } + + private static class NoopCacheEntryHelper implements CacheEntryHelper { + public static final NoopCacheEntryHelper INSTANCE = new NoopCacheEntryHelper(); + + @Override + public CacheEntryStructure getCacheEntryStructure() { + return UnstructuredCacheEntry.INSTANCE; + } + + @Override + public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SessionImplementor session) { + throw new HibernateException( "Illegal attempt to build cache entry for non-cached entity" ); + } + } + + + // EntityDefinition impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + private EntityIdentifierDefinition entityIdentifierDefinition; + private Iterable embeddedCompositeIdentifierAttributes; + private Iterable attributeDefinitions; + + @Override + public void generateEntityDefinition() { + prepareEntityIdentifierDefinition(); + collectAttributeDefinitions(); + } + + @Override + public EntityPersister getEntityPersister() { + return this; + } + + @Override + public EntityIdentifierDefinition getEntityKeyDefinition() { + return entityIdentifierDefinition; + } + + @Override + public Iterable getAttributes() { + return attributeDefinitions; + } + + + private void prepareEntityIdentifierDefinition() { + if ( entityIdentifierDefinition != null ) { + return; + } + final Type idType = getIdentifierType(); + + if ( !idType.isComponentType() ) { + entityIdentifierDefinition = + EntityIdentifierDefinitionHelper.buildSimpleEncapsulatedIdentifierDefinition( this ); + return; + } + + final CompositeType cidType = (CompositeType) idType; + if ( !cidType.isEmbedded() ) { + entityIdentifierDefinition = + EntityIdentifierDefinitionHelper.buildEncapsulatedCompositeIdentifierDefinition( this ); + return; + } + + entityIdentifierDefinition = + EntityIdentifierDefinitionHelper.buildNonEncapsulatedCompositeIdentifierDefinition( this ); + } + + private void collectAttributeDefinitions( + Map attributeDefinitionsByName, + EntityMetamodel metamodel) { + for ( int i = 0; i < metamodel.getPropertySpan(); i++ ) { + final AttributeDefinition attributeDefinition = metamodel.getProperties()[i]; + // Don't replace an attribute definition if it is already in attributeDefinitionsByName + // because the new value will be from a subclass. + final AttributeDefinition oldAttributeDefinition = attributeDefinitionsByName.get( + attributeDefinition.getName() + ); + if ( oldAttributeDefinition != null ) { + if ( LOG.isTraceEnabled() ) { + LOG.tracef( + "Ignoring subclass attribute definition [%s.%s] because it is defined in a superclass ", + entityMetamodel.getName(), + attributeDefinition.getName() + ); + } + } + else { + attributeDefinitionsByName.put( attributeDefinition.getName(), attributeDefinition ); + } + } + + // see if there are any subclass persisters... + final Set subClassEntityNames = metamodel.getSubclassEntityNames(); + if ( subClassEntityNames == null ) { + return; + } + + // see if we can find the persisters... + for ( String subClassEntityName : subClassEntityNames ) { + if ( metamodel.getName().equals( subClassEntityName ) ) { + // skip it + continue; + } + try { + final EntityPersister subClassEntityPersister = factory.getEntityPersister( subClassEntityName ); + collectAttributeDefinitions( attributeDefinitionsByName, subClassEntityPersister.getEntityMetamodel() ); + } + catch (MappingException e) { + throw new IllegalStateException( + String.format( + "Could not locate subclass EntityPersister [%s] while processing EntityPersister [%s]", + subClassEntityName, + metamodel.getName() + ), + e + ); + } + } + } + + private void collectAttributeDefinitions() { + // todo : I think this works purely based on luck atm + // specifically in terms of the sub/super class entity persister(s) being available. Bit of chicken-egg + // problem there: + // * If I do this during postConstruct (as it is now), it works as long as the + // super entity persister is already registered, but I don't think that is necessarily true. + // * If I do this during postInstantiate then lots of stuff in postConstruct breaks if we want + // to try and drive SQL generation on these (which we do ultimately). A possible solution there + // would be to delay all SQL generation until postInstantiate + + Map attributeDefinitionsByName = new LinkedHashMap(); + collectAttributeDefinitions( attributeDefinitionsByName, getEntityMetamodel() ); + + +// EntityMetamodel currentEntityMetamodel = this.getEntityMetamodel(); +// while ( currentEntityMetamodel != null ) { +// for ( int i = 0; i < currentEntityMetamodel.getPropertySpan(); i++ ) { +// attributeDefinitions.add( currentEntityMetamodel.getProperties()[i] ); +// } +// // see if there is a super class EntityMetamodel +// final String superEntityName = currentEntityMetamodel.getSuperclass(); +// if ( superEntityName != null ) { +// currentEntityMetamodel = factory.getEntityPersister( superEntityName ).getEntityMetamodel(); +// } +// else { +// currentEntityMetamodel = null; +// } +// } + + this.attributeDefinitions = Collections.unmodifiableList( + new ArrayList( attributeDefinitionsByName.values() ) + ); +// // todo : leverage the attribute definitions housed on EntityMetamodel +// // for that to work, we'd have to be able to walk our super entity persister(s) +// this.attributeDefinitions = new Iterable() { +// @Override +// public Iterator iterator() { +// return new Iterator() { +//// private final int numberOfAttributes = countSubclassProperties(); +//// private final int numberOfAttributes = entityMetamodel.getPropertySpan(); +// +// EntityMetamodel currentEntityMetamodel = entityMetamodel; +// int numberOfAttributesInCurrentEntityMetamodel = currentEntityMetamodel.getPropertySpan(); +// +// private int currentAttributeNumber; +// +// @Override +// public boolean hasNext() { +// return currentEntityMetamodel != null +// && currentAttributeNumber < numberOfAttributesInCurrentEntityMetamodel; +// } +// +// @Override +// public AttributeDefinition next() { +// final int attributeNumber = currentAttributeNumber; +// currentAttributeNumber++; +// final AttributeDefinition next = currentEntityMetamodel.getProperties()[ attributeNumber ]; +// +// if ( currentAttributeNumber >= numberOfAttributesInCurrentEntityMetamodel ) { +// // see if there is a super class EntityMetamodel +// final String superEntityName = currentEntityMetamodel.getSuperclass(); +// if ( superEntityName != null ) { +// currentEntityMetamodel = factory.getEntityPersister( superEntityName ).getEntityMetamodel(); +// if ( currentEntityMetamodel != null ) { +// numberOfAttributesInCurrentEntityMetamodel = currentEntityMetamodel.getPropertySpan(); +// currentAttributeNumber = 0; +// } +// } +// } +// +// return next; +// } +// +// @Override +// public void remove() { +// throw new UnsupportedOperationException( "Remove operation not supported here" ); +// } +// }; +// } +// }; + } + + } Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/AbstractPropertyMapping.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/entity/AbstractPropertyMapping.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/AbstractPropertyMapping.java 17 Aug 2012 14:33:33 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/AbstractPropertyMapping.java 30 Jul 2014 16:16:32 -0000 1.1.2.1 @@ -29,30 +29,46 @@ import org.hibernate.MappingException; import org.hibernate.QueryException; -import org.hibernate.engine.Mapping; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.sql.Template; -import org.hibernate.type.AbstractComponentType; import org.hibernate.type.AssociationType; +import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; -import org.hibernate.util.ArrayHelper; -import org.hibernate.util.StringHelper; +import org.jboss.logging.Logger; + /** * Basic implementation of the {@link PropertyMapping} contract. * * @author Gavin King */ public abstract class AbstractPropertyMapping implements PropertyMapping { + private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, + AbstractPropertyMapping.class.getName()); + private final Map typesByPropertyPath = new HashMap(); private final Map columnsByPropertyPath = new HashMap(); + private final Map columnReadersByPropertyPath = new HashMap(); + private final Map columnReaderTemplatesByPropertyPath = new HashMap(); private final Map formulaTemplatesByPropertyPath = new HashMap(); public String[] getIdentifierColumnNames() { throw new UnsupportedOperationException("one-to-one is not supported here"); } + public String[] getIdentifierColumnReaderTemplates() { + throw new UnsupportedOperationException("one-to-one is not supported here"); + } + + public String[] getIdentifierColumnReaders() { + throw new UnsupportedOperationException("one-to-one is not supported here"); + } + protected abstract String getEntityName(); public Type toType(String propertyName) throws QueryException { @@ -81,14 +97,15 @@ if ( columns == null ) { throw propertyException( propertyName ); } - String[] templates = (String[]) formulaTemplatesByPropertyPath.get(propertyName); + String[] formulaTemplates = (String[]) formulaTemplatesByPropertyPath.get(propertyName); + String[] columnReaderTemplates = (String[]) columnReaderTemplatesByPropertyPath.get(propertyName); String[] result = new String[columns.length]; for ( int i=0; i - * Implementors must be threadsafe (preferrably immutable) and must provide a constructor - * matching the signature of: {@link org.hibernate.mapping.PersistentClass}, {@link org.hibernate.engine.SessionFactoryImplementor} + * Implementations must be thread-safe (preferably immutable). * * @author Gavin King + * @author Steve Ebersole + * + * @see org.hibernate.persister.spi.PersisterFactory + * @see org.hibernate.persister.spi.PersisterClassResolver */ -public interface EntityPersister extends OptimisticCacheSource { +public interface EntityPersister extends OptimisticCacheSource, EntityDefinition { /** * The property name of the "special" identifier property in HQL */ public static final String ENTITY_ID = "id"; /** - * Finish the initialization of this object. + * Generate the entity definition for this object. This must be done for all + * entity persisters before calling {@link #postInstantiate()}. + */ + public void generateEntityDefinition(); + + /** + * Finish the initialization of this object. {@link #generateEntityDefinition()} + * must be called for all entity persisters before calling this method. *

        * Called only once per {@link org.hibernate.SessionFactory} lifecycle, * after all entity persisters have been instantiated. * - * @throws org.hibernate.MappingException Indicates an issue in the metdata. + * @throws org.hibernate.MappingException Indicates an issue in the metadata. */ public void postInstantiate() throws MappingException; @@ -171,7 +187,7 @@ /** * Determine whether this entity has any non-none cascading. * - * @return True if the entity has any properties with a cscade other than NONE; + * @return True if the entity has any properties with a cascade other than NONE; * false otherwise (aka, no cascading). */ public boolean hasCascades(); @@ -204,7 +220,7 @@ * Get the type of a particular property by name. * * @param propertyName The name of the property for which to retrieve - * the typpe. + * the type. * @return The type. * @throws org.hibernate.MappingException Typically indicates an unknown * property name. @@ -244,10 +260,10 @@ public boolean hasIdentifierProperty(); /** - * Determine whether detahced instances of this entity carry their own + * Determine whether detached instances of this entity carry their own * identifier value. *

        - * The other option is the deperecated feature where users could supply + * The other option is the deprecated feature where users could supply * the id during session calls. * * @return True if either (1) {@link #hasIdentifierProperty()} or @@ -299,7 +315,7 @@ /** * Retrieve the current state of the natural-id properties from the database. * - * @param id The identifier of the entity for which to retrieve the naturak-id values. + * @param id The identifier of the entity for which to retrieve the natural-id values. * @param session The session from which the request originated. * @return The natural-id snapshot. */ @@ -321,18 +337,36 @@ public boolean hasLazyProperties(); /** + * Load the id for the entity based on the natural id. + */ + public Serializable loadEntityIdByNaturalId(Object[] naturalIdValues, LockOptions lockOptions, + SessionImplementor session); + + /** * Load an instance of the persistent class. */ public Object load(Serializable id, Object optionalObject, LockMode lockMode, SessionImplementor session) throws HibernateException; /** + * Load an instance of the persistent class. + */ + public Object load(Serializable id, Object optionalObject, LockOptions lockOptions, SessionImplementor session) + throws HibernateException; + + /** * Do a version check (optional operation) */ public void lock(Serializable id, Object version, Object object, LockMode lockMode, SessionImplementor session) throws HibernateException; /** + * Do a version check (optional operation) + */ + public void lock(Serializable id, Object version, Object object, LockOptions lockOptions, SessionImplementor session) + throws HibernateException; + + /** * Persist an instance */ public void insert(Serializable id, Object[] fields, Object object, SessionImplementor session) @@ -384,12 +418,18 @@ /** * Which of the properties of this class are database generated values on insert? + * + * @deprecated Replaced internally with InMemoryValueGenerationStrategy / InDatabaseValueGenerationStrategy */ + @Deprecated public ValueInclusion[] getPropertyInsertGenerationInclusions(); /** * Which of the properties of this class are database generated values on update? + * + * @deprecated Replaced internally with InMemoryValueGenerationStrategy / InDatabaseValueGenerationStrategy */ + @Deprecated public ValueInclusion[] getPropertyUpdateGenerationInclusions(); /** @@ -417,7 +457,7 @@ public boolean[] getPropertyVersionability(); public boolean[] getPropertyLaziness(); /** - * Get the cascade styles of the propertes (optional operation) + * Get the cascade styles of the properties (optional operation) */ public CascadeStyle[] getPropertyCascadeStyles(); @@ -454,7 +494,19 @@ */ public CacheEntryStructure getCacheEntryStructure(); + public CacheEntry buildCacheEntry(Object entity, Object[] state, Object version, SessionImplementor session); + /** + * Does this class have a natural id cache + */ + public boolean hasNaturalIdCache(); + + /** + * Get the NaturalId cache (optional operation) + */ + public NaturalIdRegionAccessStrategy getNaturalIdCacheAccessStrategy(); + + /** * Get the user-visible metadata for the class (optional operation) */ public ClassMetadata getClassMetadata(); @@ -477,6 +529,8 @@ public Object[] getDatabaseSnapshot(Serializable id, SessionImplementor session) throws HibernateException; + public Serializable getIdByUniqueKey(Serializable key, String uniquePropertyName, SessionImplementor session); + /** * Get the current version of the object, or return null if there is no row for * the given identifier. In the case of unversioned data, return any object @@ -489,14 +543,9 @@ throws HibernateException; /** - * Try to discover the entity mode from the entity instance - */ - public EntityMode guessEntityMode(Object object); - - /** * Has the class actually been bytecode instrumented? */ - public boolean isInstrumented(EntityMode entityMode); + public boolean isInstrumented(); /** * Does this entity define any properties as being database generated on insert? @@ -558,7 +607,7 @@ * Perform a select to retrieve the values of any generated properties * back from the database, injecting these generated values into the * given entity as well as writing this state to the - * {@link org.hibernate.engine.PersistenceContext}. + * {@link org.hibernate.engine.spi.PersistenceContext}. *

        * Note, that because we update the PersistenceContext here, callers * need to take care that they have already written the initial snapshot @@ -574,7 +623,7 @@ * Perform a select to retrieve the values of any generated properties * back from the database, injecting these generated values into the * given entity as well as writing this state to the - * {@link org.hibernate.engine.PersistenceContext}. + * {@link org.hibernate.engine.spi.PersistenceContext}. *

        * Note, that because we update the PersistenceContext here, callers * need to take care that they have already written the initial snapshot @@ -595,88 +644,136 @@ /** * The persistent class, or null */ - public Class getMappedClass(EntityMode entityMode); + public Class getMappedClass(); /** - * Does the class implement the Lifecycle interface. + * Does the class implement the {@link org.hibernate.classic.Lifecycle} interface. */ - public boolean implementsLifecycle(EntityMode entityMode); + public boolean implementsLifecycle(); /** - * Does the class implement the Validatable interface. - */ - public boolean implementsValidatable(EntityMode entityMode); - /** * Get the proxy interface that instances of this concrete class will be * cast to (optional operation). */ - public Class getConcreteProxyClass(EntityMode entityMode); + public Class getConcreteProxyClass(); /** * Set the given values to the mapped properties of the given object */ - public void setPropertyValues(Object object, Object[] values, EntityMode entityMode) throws HibernateException; + public void setPropertyValues(Object object, Object[] values); /** * Set the value of a particular property */ - public void setPropertyValue(Object object, int i, Object value, EntityMode entityMode) throws HibernateException; + public void setPropertyValue(Object object, int i, Object value); /** * Return the (loaded) values of the mapped properties of the object (not including backrefs) */ - public Object[] getPropertyValues(Object object, EntityMode entityMode) throws HibernateException; + public Object[] getPropertyValues(Object object); /** * Get the value of a particular property */ - public Object getPropertyValue(Object object, int i, EntityMode entityMode) throws HibernateException; + public Object getPropertyValue(Object object, int i) throws HibernateException; /** * Get the value of a particular property */ - public Object getPropertyValue(Object object, String propertyName, EntityMode entityMode) throws HibernateException; + public Object getPropertyValue(Object object, String propertyName); /** * Get the identifier of an instance (throw an exception if no identifier property) + * + * @deprecated Use {@link #getIdentifier(Object,SessionImplementor)} instead */ - public Serializable getIdentifier(Object object, EntityMode entityMode) throws HibernateException; + @SuppressWarnings( {"JavaDoc"}) + public Serializable getIdentifier(Object object) throws HibernateException; /** - * Set the identifier of an instance (or do nothing if no identifier property) + * Get the identifier of an instance (throw an exception if no identifier property) + * + * @param entity The entity for which to get the identifier + * @param session The session from which the request originated + * + * @return The identifier */ - public void setIdentifier(Object object, Serializable id, EntityMode entityMode) throws HibernateException; + public Serializable getIdentifier(Object entity, SessionImplementor session); + /** + * Inject the identifier value into the given entity. + * + * @param entity The entity to inject with the identifier value. + * @param id The value to be injected as the identifier. + * @param session The session from which is requests originates + */ + public void setIdentifier(Object entity, Serializable id, SessionImplementor session); + /** * Get the version number (or timestamp) from the object's version property (or return null if not versioned) */ - public Object getVersion(Object object, EntityMode entityMode) throws HibernateException; + public Object getVersion(Object object) throws HibernateException; /** * Create a class instance initialized with the given identifier + * + * @param id The identifier value to use (may be null to represent no value) + * @param session The session from which the request originated. + * + * @return The instantiated entity. */ - public Object instantiate(Serializable id, EntityMode entityMode) throws HibernateException; + public Object instantiate(Serializable id, SessionImplementor session); /** * Is the given object an instance of this entity? */ - public boolean isInstance(Object object, EntityMode entityMode); + public boolean isInstance(Object object); /** * Does the given instance have any uninitialized lazy properties? */ - public boolean hasUninitializedLazyProperties(Object object, EntityMode entityMode); + public boolean hasUninitializedLazyProperties(Object object); /** - * Set the identifier and version of the given instance back - * to its "unsaved" value, returning the id - * @param currentId TODO - * @param currentVersion TODO + * Set the identifier and version of the given instance back to its "unsaved" value. + * + * @param entity The entity instance + * @param currentId The currently assigned identifier value. + * @param currentVersion The currently assigned version value. + * @param session The session from which the request originated. */ - public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion, EntityMode entityMode); + public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion, SessionImplementor session); /** - * Get the persister for an instance of this class or a subclass + * A request has already identified the entity-name of this persister as the mapping for the given instance. + * However, we still need to account for possible subclassing and potentially re-route to the more appropriate + * persister. + *

        + * For example, a request names Animal as the entity-name which gets resolved to this persister. But the + * actual instance is really an instance of Cat which is a subclass of Animal. So, here the + * Animal persister is being asked to return the persister specific to Cat. + *

        + * It is also possible that the instance is actually an Animal instance in the above example in which + * case we would return this from this method. + * + * @param instance The entity instance + * @param factory Reference to the SessionFactory + * + * @return The appropriate persister + * + * @throws HibernateException Indicates that instance was deemed to not be a subclass of the entity mapped by + * this persister. */ - public EntityPersister getSubclassEntityPersister(Object instance, SessionFactoryImplementor factory, EntityMode entityMode); + public EntityPersister getSubclassEntityPersister(Object instance, SessionFactoryImplementor factory); + + public EntityMode getEntityMode(); + public EntityTuplizer getEntityTuplizer(); + + public EntityInstrumentationMetadata getInstrumentationMetadata(); + + public FilterAliasGenerator getFilterAliasGenerator(final String rootAlias); + + public int[] resolveAttributeIndexes(Set properties); + + public boolean canUseReferenceCacheEntries(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Joinable.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Joinable.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Joinable.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Joinable.java 30 Jul 2014 16:16:32 -0000 1.1.2.1 @@ -23,11 +23,11 @@ * */ package org.hibernate.persister.entity; +import java.util.Map; +import java.util.Set; import org.hibernate.MappingException; -import java.util.Map; - /** * Anything that can be loaded by outer join - namely * persisters for classes or collections. @@ -56,21 +56,44 @@ * (optional operation) */ public String whereJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses); + /** + * Get the where clause part of any joins + * (optional operation) + */ + public String whereJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses, Set treatAsDeclarations); + + /** * Get the from clause part of any joins * (optional operation) */ public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses); + /** + * Get the from clause part of any joins + * (optional operation) + */ + public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses, Set treatAsDeclarations); + + /** * The columns to join on */ public String[] getKeyColumnNames(); + /** * Get the where clause filter, given a query alias and considering enabled session filters */ public String filterFragment(String alias, Map enabledFilters) throws MappingException; + /** + * Get the where clause filter, given a query alias and considering enabled session filters + */ + public String filterFragment(String alias, Map enabledFilters, Set treatAsDeclarations) throws MappingException; + public String oneToManyFilterFragment(String alias) throws MappingException; + + public String oneToManyFilterFragment(String alias, Set treatAsDeclarations); + /** * Is this instance actually a CollectionPersister? */ Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java 17 Aug 2012 14:33:33 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java 30 Jul 2014 16:16:32 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,52 +20,77 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.persister.entity; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.Map; +import java.util.Set; import org.hibernate.AssertionFailure; -import org.hibernate.Hibernate; import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.QueryException; -import org.hibernate.cache.access.EntityRegionAccessStrategy; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.Versioning; -import org.hibernate.engine.ExecuteUpdateResultCheckStyle; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; +import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; +import org.hibernate.engine.OptimisticLockStyle; +import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.DynamicFilterAliasGenerator; +import org.hibernate.internal.FilterAliasGenerator; +import org.hibernate.internal.util.MarkerObject; +import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.mapping.Column; +import org.hibernate.mapping.Formula; +import org.hibernate.mapping.Join; import org.hibernate.mapping.KeyValue; +import org.hibernate.mapping.MappedSuperclass; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.mapping.Selectable; import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Table; +import org.hibernate.mapping.Value; +import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.sql.CaseFragment; +import org.hibernate.sql.InFragment; +import org.hibernate.sql.Insert; import org.hibernate.sql.SelectFragment; -import org.hibernate.type.Type; -import org.hibernate.util.ArrayHelper; +import org.hibernate.type.*; +import org.hibernate.type.DiscriminatorType; +import org.jboss.logging.Logger; + /** * An EntityPersister implementing the normalized "table-per-subclass" * mapping strategy * * @author Gavin King */ public class JoinedSubclassEntityPersister extends AbstractEntityPersister { + private static final Logger log = Logger.getLogger( JoinedSubclassEntityPersister.class ); + private static final String IMPLICIT_DISCRIMINATOR_ALIAS = "clazz_"; + private static final Object NULL_DISCRIMINATOR = new MarkerObject(""); + private static final Object NOT_NULL_DISCRIMINATOR = new MarkerObject(""); + private static final String NULL_STRING = "null"; + private static final String NOT_NULL_STRING = "not null"; + // the class hierarchy structure private final int tableSpan; private final String[] tableNames; private final String[] naturalOrderTableNames; private final String[][] tableKeyColumns; + private final String[][] tableKeyColumnReaders; + private final String[][] tableKeyColumnReaderTemplates; private final String[][] naturalOrderTableKeyColumns; + private final String[][] naturalOrderTableKeyColumnReaders; + private final String[][] naturalOrderTableKeyColumnReaderTemplates; private final boolean[] naturalOrderCascadeDeleteEnabled; private final String[] spaces; @@ -89,6 +114,9 @@ private final int[] subclassColumnTableNumberClosure; private final int[] subclassFormulaTableNumberClosure; + private final boolean[] subclassTableSequentialSelect; + private final boolean[] subclassTableIsLazyClosure; + // subclass discrimination works by assigning particular // values to certain combinations of null primary key // values in the outer join using an SQL CASE @@ -100,36 +128,88 @@ private final String[] constraintOrderedTableNames; private final String[][] constraintOrderedKeyColumnNames; + private final Object discriminatorValue; private final String discriminatorSQLString; + private final DiscriminatorType discriminatorType; + private final String explicitDiscriminatorColumnName; + private final String discriminatorAlias; + // Span of the tables directly mapped by this entity and super-classes, if any + private final int coreTableSpan; + // only contains values for SecondaryTables, ie. not tables part of the "coreTableSpan" + private final boolean[] isNullableTable; + //INITIALIZATION: public JoinedSubclassEntityPersister( final PersistentClass persistentClass, final EntityRegionAccessStrategy cacheAccessStrategy, + final NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy, final SessionFactoryImplementor factory, final Mapping mapping) throws HibernateException { - super( persistentClass, cacheAccessStrategy, factory ); + super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, factory ); // DISCRIMINATOR - final Object discriminatorValue; if ( persistentClass.isPolymorphic() ) { - try { - discriminatorValue = new Integer( persistentClass.getSubclassId() ); - discriminatorSQLString = discriminatorValue.toString(); + final Value discriminatorMapping = persistentClass.getDiscriminator(); + if ( discriminatorMapping != null ) { + log.debug( "Encountered explicit discriminator mapping for joined inheritance" ); + + final Selectable selectable = discriminatorMapping.getColumnIterator().next(); + if ( Formula.class.isInstance( selectable ) ) { + throw new MappingException( "Discriminator formulas on joined inheritance hierarchies not supported at this time" ); + } + else { + final Column column = (Column) selectable; + explicitDiscriminatorColumnName = column.getQuotedName( factory.getDialect() ); + discriminatorAlias = column.getAlias( factory.getDialect(), persistentClass.getRootTable() ); + } + discriminatorType = (DiscriminatorType) persistentClass.getDiscriminator().getType(); + if ( persistentClass.isDiscriminatorValueNull() ) { + discriminatorValue = NULL_DISCRIMINATOR; + discriminatorSQLString = InFragment.NULL; + } + else if ( persistentClass.isDiscriminatorValueNotNull() ) { + discriminatorValue = NOT_NULL_DISCRIMINATOR; + discriminatorSQLString = InFragment.NOT_NULL; + } + else { + try { + discriminatorValue = discriminatorType.stringToObject( persistentClass.getDiscriminatorValue() ); + discriminatorSQLString = discriminatorType.objectToSQLString( discriminatorValue, factory.getDialect() ); + } + catch (ClassCastException cce) { + throw new MappingException("Illegal discriminator type: " + discriminatorType.getName() ); + } + catch (Exception e) { + throw new MappingException("Could not format discriminator value to SQL string", e); + } + } } - catch (Exception e) { - throw new MappingException("Could not format discriminator value to SQL string", e ); + else { + explicitDiscriminatorColumnName = null; + discriminatorAlias = IMPLICIT_DISCRIMINATOR_ALIAS; + discriminatorType = StandardBasicTypes.INTEGER; + try { + discriminatorValue = persistentClass.getSubclassId(); + discriminatorSQLString = discriminatorValue.toString(); + } + catch ( Exception e ) { + throw new MappingException( "Could not format discriminator value to SQL string", e ); + } } } else { + explicitDiscriminatorColumnName = null; + discriminatorAlias = IMPLICIT_DISCRIMINATOR_ALIAS; + discriminatorType = StandardBasicTypes.INTEGER; discriminatorValue = null; discriminatorSQLString = null; } - if ( optimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION ) { + if ( optimisticLockStyle() == OptimisticLockStyle.ALL || optimisticLockStyle() == OptimisticLockStyle.DIRTY ) { throw new MappingException( "optimistic-lock=all|dirty not supported for joined-subclass mappings [" + getEntityName() + "]" ); } @@ -139,6 +219,8 @@ ArrayList tables = new ArrayList(); ArrayList keyColumns = new ArrayList(); + ArrayList keyColumnReaders = new ArrayList(); + ArrayList keyColumnReaderTemplates = new ArrayList(); ArrayList cascadeDeletes = new ArrayList(); Iterator titer = persistentClass.getTableClosureIterator(); Iterator kiter = persistentClass.getKeyClosureIterator(); @@ -150,56 +232,153 @@ factory.getSettings().getDefaultCatalogName(), factory.getSettings().getDefaultSchemaName() ); - tables.add(tabname); + tables.add( tabname ); String[] keyCols = new String[idColumnSpan]; + String[] keyColReaders = new String[idColumnSpan]; + String[] keyColReaderTemplates = new String[idColumnSpan]; Iterator citer = key.getColumnIterator(); - for ( int k=0; k= 0 ; i--, currentPosition++ ) { - constraintOrderedTableNames[currentPosition] = subclassTableNameClosure[i]; - constraintOrderedKeyColumnNames[currentPosition] = subclassTableKeyColumnClosure[i]; + for ( int i = naturalOrderSubclassTableNameClosure.length - 1; i >= 0; i--, currentPosition++ ) { + constraintOrderedTableNames[currentPosition] = naturalOrderSubclassTableNameClosure[i]; + constraintOrderedKeyColumnNames[currentPosition] = naturalOrderSubclassTableKeyColumnClosure[i]; } + /** + * Suppose an entity Client extends Person, mapped to the tables CLIENT and PERSON respectively. + * For the Client entity: + * naturalOrderTableNames -> PERSON, CLIENT; this reflects the sequence in which the tables are + * added to the meta-data when the annotated entities are processed. + * However, in some instances, for example when generating joins, the CLIENT table needs to be + * the first table as it will the driving table. + * tableNames -> CLIENT, PERSON + */ + tableSpan = naturalOrderTableNames.length; - tableNames = reverse(naturalOrderTableNames); - tableKeyColumns = reverse(naturalOrderTableKeyColumns); - reverse(subclassTableNameClosure, tableSpan); - reverse(subclassTableKeyColumnClosure, tableSpan); + tableNames = reverse( naturalOrderTableNames, coreTableSpan ); + tableKeyColumns = reverse( naturalOrderTableKeyColumns, coreTableSpan ); + tableKeyColumnReaders = reverse( naturalOrderTableKeyColumnReaders, coreTableSpan ); + tableKeyColumnReaderTemplates = reverse( naturalOrderTableKeyColumnReaderTemplates, coreTableSpan ); + subclassTableNameClosure = reverse( naturalOrderSubclassTableNameClosure, coreTableSpan ); + subclassTableKeyColumnClosure = reverse( naturalOrderSubclassTableKeyColumnClosure, coreTableSpan ); spaces = ArrayHelper.join( tableNames, @@ -218,46 +397,71 @@ deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[tableSpan]; PersistentClass pc = persistentClass; - int jk = tableSpan-1; - while (pc!=null) { + int jk = coreTableSpan - 1; + while ( pc != null ) { customSQLInsert[jk] = pc.getCustomSQLInsert(); insertCallable[jk] = customSQLInsert[jk] != null && pc.isCustomInsertCallable(); insertResultCheckStyles[jk] = pc.getCustomSQLInsertCheckStyle() == null - ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[jk], insertCallable[jk] ) - : pc.getCustomSQLInsertCheckStyle(); + ? ExecuteUpdateResultCheckStyle.determineDefault( + customSQLInsert[jk], insertCallable[jk] + ) + : pc.getCustomSQLInsertCheckStyle(); customSQLUpdate[jk] = pc.getCustomSQLUpdate(); updateCallable[jk] = customSQLUpdate[jk] != null && pc.isCustomUpdateCallable(); updateResultCheckStyles[jk] = pc.getCustomSQLUpdateCheckStyle() == null - ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[jk], updateCallable[jk] ) - : pc.getCustomSQLUpdateCheckStyle(); + ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[jk], updateCallable[jk] ) + : pc.getCustomSQLUpdateCheckStyle(); customSQLDelete[jk] = pc.getCustomSQLDelete(); deleteCallable[jk] = customSQLDelete[jk] != null && pc.isCustomDeleteCallable(); deleteResultCheckStyles[jk] = pc.getCustomSQLDeleteCheckStyle() == null - ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[jk], deleteCallable[jk] ) - : pc.getCustomSQLDeleteCheckStyle(); + ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[jk], deleteCallable[jk] ) + : pc.getCustomSQLDeleteCheckStyle(); jk--; pc = pc.getSuperclass(); } + if ( jk != -1 ) { throw new AssertionFailure( "Tablespan does not match height of joined-subclass hiearchy." ); } - // PROPERTIES + joinIter = persistentClass.getJoinClosureIterator(); + int j = coreTableSpan; + while ( joinIter.hasNext() ) { + Join join = (Join) joinIter.next(); + customSQLInsert[j] = join.getCustomSQLInsert(); + insertCallable[j] = customSQLInsert[j] != null && join.isCustomInsertCallable(); + insertResultCheckStyles[j] = join.getCustomSQLInsertCheckStyle() == null + ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[j], insertCallable[j] ) + : join.getCustomSQLInsertCheckStyle(); + customSQLUpdate[j] = join.getCustomSQLUpdate(); + updateCallable[j] = customSQLUpdate[j] != null && join.isCustomUpdateCallable(); + updateResultCheckStyles[j] = join.getCustomSQLUpdateCheckStyle() == null + ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[j], updateCallable[j] ) + : join.getCustomSQLUpdateCheckStyle(); + customSQLDelete[j] = join.getCustomSQLDelete(); + deleteCallable[j] = customSQLDelete[j] != null && join.isCustomDeleteCallable(); + deleteResultCheckStyles[j] = join.getCustomSQLDeleteCheckStyle() == null + ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[j], deleteCallable[j] ) + : join.getCustomSQLDeleteCheckStyle(); + j++; + } + + // PROPERTIES int hydrateSpan = getPropertySpan(); naturalOrderPropertyTableNumbers = new int[hydrateSpan]; propertyTableNumbers = new int[hydrateSpan]; Iterator iter = persistentClass.getPropertyClosureIterator(); - int i=0; - while( iter.hasNext() ) { + int i = 0; + while ( iter.hasNext() ) { Property prop = (Property) iter.next(); String tabname = prop.getValue().getTable().getQualifiedName( - factory.getDialect(), - factory.getSettings().getDefaultCatalogName(), - factory.getSettings().getDefaultSchemaName() + factory.getDialect(), + factory.getSettings().getDefaultCatalogName(), + factory.getSettings().getDefaultSchemaName() ); - propertyTableNumbers[i] = getTableId(tabname, tableNames); - naturalOrderPropertyTableNumbers[i] = getTableId(tabname, naturalOrderTableNames); + propertyTableNumbers[i] = getTableId( tabname, tableNames ); + naturalOrderPropertyTableNumbers[i] = getTableId( tabname, naturalOrderTableNames ); i++; } @@ -278,47 +482,47 @@ factory.getSettings().getDefaultCatalogName(), factory.getSettings().getDefaultSchemaName() ); - Integer tabnum = new Integer( getTableId(tabname, subclassTableNameClosure) ); - propTableNumbers.add(tabnum); + Integer tabnum = getTableId( tabname, subclassTableNameClosure ); + propTableNumbers.add( tabnum ); Iterator citer = prop.getColumnIterator(); while ( citer.hasNext() ) { Selectable thing = (Selectable) citer.next(); if ( thing.isFormula() ) { - formulaTableNumbers.add(tabnum); + formulaTableNumbers.add( tabnum ); } else { - columnTableNumbers.add(tabnum); + columnTableNumbers.add( tabnum ); } } } - subclassColumnTableNumberClosure = ArrayHelper.toIntArray(columnTableNumbers); - subclassPropertyTableNumberClosure = ArrayHelper.toIntArray(propTableNumbers); - subclassFormulaTableNumberClosure = ArrayHelper.toIntArray(formulaTableNumbers); + subclassColumnTableNumberClosure = ArrayHelper.toIntArray( columnTableNumbers ); + subclassPropertyTableNumberClosure = ArrayHelper.toIntArray( propTableNumbers ); + subclassFormulaTableNumberClosure = ArrayHelper.toIntArray( formulaTableNumbers ); // SUBCLASSES int subclassSpan = persistentClass.getSubclassSpan() + 1; subclassClosure = new String[subclassSpan]; - subclassClosure[subclassSpan-1] = getEntityName(); + subclassClosure[subclassSpan - 1] = getEntityName(); if ( persistentClass.isPolymorphic() ) { subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() ); discriminatorValues = new String[subclassSpan]; - discriminatorValues[subclassSpan-1] = discriminatorSQLString; + discriminatorValues[subclassSpan - 1] = discriminatorSQLString; notNullColumnTableNumbers = new int[subclassSpan]; final int id = getTableId( - persistentClass.getTable().getQualifiedName( - factory.getDialect(), - factory.getSettings().getDefaultCatalogName(), - factory.getSettings().getDefaultSchemaName() - ), - subclassTableNameClosure + persistentClass.getTable().getQualifiedName( + factory.getDialect(), + factory.getSettings().getDefaultCatalogName(), + factory.getSettings().getDefaultSchemaName() + ), + subclassTableNameClosure ); - notNullColumnTableNumbers[subclassSpan-1] = id; + notNullColumnTableNumbers[subclassSpan - 1] = id; notNullColumnNames = new String[subclassSpan]; - notNullColumnNames[subclassSpan-1] = subclassTableKeyColumnClosure[id][0]; //( (Column) model.getTable().getPrimaryKey().getColumnIterator().next() ).getName(); + notNullColumnNames[subclassSpan - 1] = subclassTableKeyColumnClosure[id][0]; //( (Column) model.getTable().getPrimaryKey().getColumnIterator().next() ).getName(); } else { discriminatorValues = null; @@ -327,67 +531,334 @@ } iter = persistentClass.getSubclassIterator(); - int k=0; + int k = 0; while ( iter.hasNext() ) { Subclass sc = (Subclass) iter.next(); subclassClosure[k] = sc.getEntityName(); try { if ( persistentClass.isPolymorphic() ) { - // we now use subclass ids that are consistent across all - // persisters for a class hierarchy, so that the use of - // "foo.class = Bar" works in HQL - Integer subclassId = new Integer( sc.getSubclassId() );//new Integer(k+1); - subclassesByDiscriminatorValue.put( subclassId, sc.getEntityName() ); - discriminatorValues[k] = subclassId.toString(); + final Object discriminatorValue; + if ( explicitDiscriminatorColumnName != null ) { + if ( sc.isDiscriminatorValueNull() ) { + discriminatorValue = NULL_DISCRIMINATOR; + } + else if ( sc.isDiscriminatorValueNotNull() ) { + discriminatorValue = NOT_NULL_DISCRIMINATOR; + } + else { + try { + discriminatorValue = discriminatorType.stringToObject( sc.getDiscriminatorValue() ); + } + catch (ClassCastException cce) { + throw new MappingException( "Illegal discriminator type: " + discriminatorType.getName() ); + } + catch (Exception e) { + throw new MappingException( "Could not format discriminator value to SQL string", e); + } + } + } + else { + // we now use subclass ids that are consistent across all + // persisters for a class hierarchy, so that the use of + // "foo.class = Bar" works in HQL + discriminatorValue = sc.getSubclassId(); + } + + subclassesByDiscriminatorValue.put( discriminatorValue, sc.getEntityName() ); + discriminatorValues[k] = discriminatorValue.toString(); int id = getTableId( - sc.getTable().getQualifiedName( - factory.getDialect(), - factory.getSettings().getDefaultCatalogName(), - factory.getSettings().getDefaultSchemaName() - ), - subclassTableNameClosure + sc.getTable().getQualifiedName( + factory.getDialect(), + factory.getSettings().getDefaultCatalogName(), + factory.getSettings().getDefaultSchemaName() + ), + subclassTableNameClosure ); notNullColumnTableNumbers[k] = id; notNullColumnNames[k] = subclassTableKeyColumnClosure[id][0]; //( (Column) sc.getTable().getPrimaryKey().getColumnIterator().next() ).getName(); } } - catch (Exception e) { - throw new MappingException("Error parsing discriminator value", e ); + catch ( Exception e ) { + throw new MappingException( "Error parsing discriminator value", e ); } k++; } + subclassNamesBySubclassTable = buildSubclassNamesBySubclassTableMapping( persistentClass, factory ); + initLockers(); - initSubclassPropertyAliasesMap(persistentClass); + initSubclassPropertyAliasesMap( persistentClass ); - postConstruct(mapping); + postConstruct( mapping ); } + + /** + * Used to hold the name of subclasses that each "subclass table" is part of. For example, given a hierarchy like: + * {@code JoinedEntity <- JoinedEntitySubclass <- JoinedEntitySubSubclass}.. + *

        + * For the persister for JoinedEntity, we'd have: + *

        +	 *     subclassClosure[0] = "JoinedEntitySubSubclass"
        +	 *     subclassClosure[1] = "JoinedEntitySubclass"
        +	 *     subclassClosure[2] = "JoinedEntity"
        +	 *
        +	 *     subclassTableNameClosure[0] = "T_JoinedEntity"
        +	 *     subclassTableNameClosure[1] = "T_JoinedEntitySubclass"
        +	 *     subclassTableNameClosure[2] = "T_JoinedEntitySubSubclass"
        +	 *
        +	 *     subclassNameClosureBySubclassTable[0] = ["JoinedEntitySubSubclass", "JoinedEntitySubclass"]
        +	 *     subclassNameClosureBySubclassTable[1] = ["JoinedEntitySubSubclass"]
        +	 * 
        + * Note that there are only 2 entries in subclassNameClosureBySubclassTable. That is because there are really only + * 2 tables here that make up the subclass mapping, the others make up the class/superclass table mappings. We + * do not need to account for those here. The "offset" is defined by the value of {@link #getTableSpan()}. + * Therefore the corresponding row in subclassNameClosureBySubclassTable for a given row in subclassTableNameClosure + * is calculated as {@code subclassTableNameClosureIndex - getTableSpan()}. + *

        + * As we consider each subclass table we can look into this array based on the subclass table's index and see + * which subclasses would require it to be included. E.g., given {@code TREAT( x AS JoinedEntitySubSubclass )}, + * when trying to decide whether to include join to "T_JoinedEntitySubclass" (subclassTableNameClosureIndex = 1), + * we'd look at {@code subclassNameClosureBySubclassTable[0]} and see if the TREAT-AS subclass name is included in + * its values. Since {@code subclassNameClosureBySubclassTable[1]} includes "JoinedEntitySubSubclass", we'd + * consider it included. + *

        + * {@link #subclassTableNameClosure} also accounts for secondary tables and we properly handle those as we + * build the subclassNamesBySubclassTable array and they are therefore properly handled when we use it + */ + private final String[][] subclassNamesBySubclassTable; + + /** + * Essentially we are building a mapping that we can later use to determine whether a given "subclass table" + * should be included in joins when JPA TREAT-AS is used. + * + * @param persistentClass + * @param factory + * @return + */ + private String[][] buildSubclassNamesBySubclassTableMapping(PersistentClass persistentClass, SessionFactoryImplementor factory) { + // this value represents the number of subclasses (and not the class itself) + final int numberOfSubclassTables = subclassTableNameClosure.length - coreTableSpan; + if ( numberOfSubclassTables == 0 ) { + return new String[0][]; + } + + final String[][] mapping = new String[numberOfSubclassTables][]; + processPersistentClassHierarchy( persistentClass, true, factory, mapping ); + return mapping; + } + + private Set processPersistentClassHierarchy( + PersistentClass persistentClass, + boolean isBase, + SessionFactoryImplementor factory, + String[][] mapping) { + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // collect all the class names that indicate that the "main table" of the given PersistentClass should be + // included when one of the collected class names is used in TREAT + final Set classNames = new HashSet(); + + final Iterator itr = persistentClass.getDirectSubclasses(); + while ( itr.hasNext() ) { + final Subclass subclass = (Subclass) itr.next(); + final Set subclassSubclassNames = processPersistentClassHierarchy( + subclass, + false, + factory, + mapping + ); + classNames.addAll( subclassSubclassNames ); + } + + classNames.add( persistentClass.getEntityName() ); + + if ( ! isBase ) { + MappedSuperclass msc = persistentClass.getSuperMappedSuperclass(); + while ( msc != null ) { + classNames.add( msc.getMappedClass().getName() ); + msc = msc.getSuperMappedSuperclass(); + } + + associateSubclassNamesToSubclassTableIndexes( persistentClass, classNames, mapping, factory ); + } + + return classNames; + } + + private void associateSubclassNamesToSubclassTableIndexes( + PersistentClass persistentClass, + Set classNames, + String[][] mapping, + SessionFactoryImplementor factory) { + + final String tableName = persistentClass.getTable().getQualifiedName( + factory.getDialect(), + factory.getSettings().getDefaultCatalogName(), + factory.getSettings().getDefaultSchemaName() + ); + + associateSubclassNamesToSubclassTableIndex( tableName, classNames, mapping ); + + Iterator itr = persistentClass.getJoinIterator(); + while ( itr.hasNext() ) { + final Join join = (Join) itr.next(); + final String secondaryTableName = join.getTable().getQualifiedName( + factory.getDialect(), + factory.getSettings().getDefaultCatalogName(), + factory.getSettings().getDefaultSchemaName() + ); + associateSubclassNamesToSubclassTableIndex( secondaryTableName, classNames, mapping ); + } + } + + private void associateSubclassNamesToSubclassTableIndex( + String tableName, + Set classNames, + String[][] mapping) { + // find the table's entry in the subclassTableNameClosure array + boolean found = false; + for ( int i = 0; i < subclassTableNameClosure.length; i++ ) { + if ( subclassTableNameClosure[i].equals( tableName ) ) { + found = true; + final int index = i - coreTableSpan; + if ( index < 0 || index >= mapping.length ) { + throw new IllegalStateException( + String.format( + "Encountered 'subclass table index' [%s] was outside expected range ( [%s] < i < [%s] )", + index, + 0, + mapping.length + ) + ); + } + mapping[index] = classNames.toArray( new String[ classNames.size() ] ); + break; + } + } + if ( !found ) { + throw new IllegalStateException( + String.format( + "Was unable to locate subclass table [%s] in 'subclassTableNameClosure'", + tableName + ) + ); + } + } + + public JoinedSubclassEntityPersister( + final EntityBinding entityBinding, + final EntityRegionAccessStrategy cacheAccessStrategy, + final NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy, + final SessionFactoryImplementor factory, + final Mapping mapping) throws HibernateException { + super( entityBinding, cacheAccessStrategy, naturalIdRegionAccessStrategy, factory ); + // TODO: implement!!! initializing final fields to null to make compiler happy + tableSpan = -1; + tableNames = null; + naturalOrderTableNames = null; + tableKeyColumns = null; + tableKeyColumnReaders = null; + tableKeyColumnReaderTemplates = null; + naturalOrderTableKeyColumns = null; + naturalOrderTableKeyColumnReaders = null; + naturalOrderTableKeyColumnReaderTemplates = null; + naturalOrderCascadeDeleteEnabled = null; + spaces = null; + subclassClosure = null; + subclassTableNameClosure = null; + subclassTableKeyColumnClosure = null; + isClassOrSuperclassTable = null; + naturalOrderPropertyTableNumbers = null; + propertyTableNumbers = null; + subclassPropertyTableNumberClosure = null; + subclassColumnTableNumberClosure = null; + subclassFormulaTableNumberClosure = null; + subclassTableSequentialSelect = null; + subclassTableIsLazyClosure = null; + discriminatorValues = null; + notNullColumnNames = null; + notNullColumnTableNumbers = null; + constraintOrderedTableNames = null; + constraintOrderedKeyColumnNames = null; + discriminatorValue = null; + discriminatorSQLString = null; + discriminatorType = StandardBasicTypes.INTEGER; + explicitDiscriminatorColumnName = null; + discriminatorAlias = IMPLICIT_DISCRIMINATOR_ALIAS; + coreTableSpan = -1; + isNullableTable = null; + subclassNamesBySubclassTable = null; + } + + protected boolean isNullableTable(int j) { + if ( j < coreTableSpan ) { + return false; + } + return isNullableTable[j - coreTableSpan]; + } + + protected boolean isSubclassTableSequentialSelect(int j) { + return subclassTableSequentialSelect[j] && !isClassOrSuperclassTable[j]; + } + /*public void postInstantiate() throws MappingException { super.postInstantiate(); //TODO: other lock modes? loader = createEntityLoader(LockMode.NONE, CollectionHelper.EMPTY_MAP); }*/ public String getSubclassPropertyTableName(int i) { - return subclassTableNameClosure[ subclassPropertyTableNumberClosure[i] ]; + return subclassTableNameClosure[subclassPropertyTableNumberClosure[i]]; } public Type getDiscriminatorType() { - return Hibernate.INTEGER; + return discriminatorType; } + public Object getDiscriminatorValue() { + return discriminatorValue; + } + + @Override public String getDiscriminatorSQLValue() { return discriminatorSQLString; } + @Override + public String getDiscriminatorColumnName() { + return explicitDiscriminatorColumnName == null + ? super.getDiscriminatorColumnName() + : explicitDiscriminatorColumnName; + } + @Override + public String getDiscriminatorColumnReaders() { + return getDiscriminatorColumnName(); + } + + @Override + public String getDiscriminatorColumnReaderTemplate() { + return getDiscriminatorColumnName(); + } + + protected String getDiscriminatorAlias() { + return discriminatorAlias; + } + public String getSubclassForDiscriminatorValue(Object value) { - return (String) subclassesByDiscriminatorValue.get(value); + return (String) subclassesByDiscriminatorValue.get( value ); } + @Override + protected void addDiscriminatorToInsert(Insert insert) { + if ( explicitDiscriminatorColumnName != null ) { + insert.addColumn( explicitDiscriminatorColumnName, getDiscriminatorSQLValue() ); + } + } + public Serializable[] getPropertySpaces() { return spaces; // don't need subclass tables, because they can't appear in conditions } @@ -406,7 +877,7 @@ } protected boolean isPropertyOfTable(int property, int j) { - return naturalOrderPropertyTableNumbers[property]==j; + return naturalOrderPropertyTableNumbers[property] == j; } /** @@ -434,35 +905,64 @@ throw new JDBCException( "could not load by id: " + MessageHelper.infoString(this, id), sqle ); } }*/ - private static final void reverse(Object[] objects, int len) { Object[] temp = new Object[len]; - for (int i=0; i treatAsDeclarations) { + return filterFragment( alias ); + } + public String generateFilterConditionAlias(String rootAlias) { - return generateTableAlias( rootAlias, tableSpan-1 ); + return generateTableAlias( rootAlias, tableSpan - 1 ); } public String[] getIdentifierColumnNames() { return tableKeyColumns[0]; } - public String[] toColumns(String alias, String propertyName) throws QueryException { + public String[] getIdentifierColumnReaderTemplates() { + return tableKeyColumnReaderTemplates[0]; + } - if ( ENTITY_CLASS.equals(propertyName) ) { + public String[] getIdentifierColumnReaders() { + return tableKeyColumnReaders[0]; + } + + public String[] toColumns(String alias, String propertyName) throws QueryException { + if ( ENTITY_CLASS.equals( propertyName ) ) { // This doesn't actually seem to work but it *might* // work on some dbs. Also it doesn't work if there // are multiple columns of results because it // is not accounting for the suffix: // return new String[] { getDiscriminatorColumnName() }; - return new String[] { discriminatorFragment(alias).toFragmentString() }; + return new String[] { discriminatorFragment( alias ).toFragmentString() }; } else { - return super.toColumns(alias, propertyName); + return super.toColumns( alias, propertyName ); } - } protected int[] getPropertyTableNumbersInSelect() { @@ -571,16 +1079,56 @@ return subclassTableNameClosure.length; } + protected boolean isSubclassTableLazy(int j) { + return subclassTableIsLazyClosure[j]; + } + + protected boolean isClassOrSuperclassTable(int j) { return isClassOrSuperclassTable[j]; } + @Override + protected boolean isSubclassTableIndicatedByTreatAsDeclarations( + int subclassTableNumber, + Set treatAsDeclarations) { + if ( treatAsDeclarations == null || treatAsDeclarations.isEmpty() ) { + return false; + } + + final String[] inclusionSubclassNameClosure = getSubclassNameClosureBySubclassTable( subclassTableNumber ); + + // NOTE : we assume the entire hierarchy is joined-subclass here + for ( String subclassName : treatAsDeclarations ) { + for ( String inclusionSubclassName : inclusionSubclassNameClosure ) { + if ( inclusionSubclassName.equals( subclassName ) ) { + return true; + } + } + } + + return false; + } + + private String[] getSubclassNameClosureBySubclassTable(int subclassTableNumber) { + final int index = subclassTableNumber - getTableSpan(); + + if ( index > subclassNamesBySubclassTable.length ) { + throw new IllegalArgumentException( + "Given subclass table number is outside expected range [" + subclassNamesBySubclassTable.length + + "] as defined by subclassTableNameClosure/subclassClosure" + ); + } + + return subclassNamesBySubclassTable[index]; + } + public String getPropertyTableName(String propertyName) { - Integer index = getEntityMetamodel().getPropertyIndexOrNull(propertyName); + Integer index = getEntityMetamodel().getPropertyIndexOrNull( propertyName ); if ( index == null ) { return null; } - return tableNames[ propertyTableNumbers[ index.intValue() ] ]; + return tableNames[propertyTableNumbers[index]]; } public String[] getConstraintOrderedTableNameClosure() { @@ -601,9 +1149,43 @@ public Declarer getSubclassPropertyDeclarer(String propertyPath) { if ( "class".equals( propertyPath ) ) { - // special case where we need to force incloude all subclass joins + // special case where we need to force include all subclass joins return Declarer.SUBCLASS; } return super.getSubclassPropertyDeclarer( propertyPath ); } + + @Override + public int determineTableNumberForColumn(String columnName) { + // HHH-7630: In case the naturalOrder/identifier column is explicitly given in the ordering, check here. + for ( int i = 0, max = naturalOrderTableKeyColumns.length; i < max; i++ ) { + final String[] keyColumns = naturalOrderTableKeyColumns[i]; + if ( ArrayHelper.contains( keyColumns, columnName ) ) { + return naturalOrderPropertyTableNumbers[i]; + } + } + + final String[] subclassColumnNameClosure = getSubclassColumnClosure(); + for ( int i = 0, max = subclassColumnNameClosure.length; i < max; i++ ) { + final boolean quoted = subclassColumnNameClosure[i].startsWith( "\"" ) + && subclassColumnNameClosure[i].endsWith( "\"" ); + if ( quoted ) { + if ( subclassColumnNameClosure[i].equals( columnName ) ) { + return getSubclassColumnTableNumberClosure()[i]; + } + } + else { + if ( subclassColumnNameClosure[i].equalsIgnoreCase( columnName ) ) { + return getSubclassColumnTableNumberClosure()[i]; + } + } + } + throw new HibernateException( "Could not locate table which owns column [" + columnName + "] referenced in order-by mapping" ); + } + + + @Override + public FilterAliasGenerator getFilterAliasGenerator(String rootAlias) { + return new DynamicFilterAliasGenerator(subclassTableNameClosure, rootAlias); + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Loadable.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Loadable.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Loadable.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Loadable.java 30 Jul 2014 16:16:32 -0000 1.1.2.1 @@ -23,13 +23,12 @@ * */ package org.hibernate.persister.entity; - import java.io.Serializable; import java.sql.ResultSet; import java.sql.SQLException; import org.hibernate.HibernateException; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.type.Type; /** @@ -54,6 +53,11 @@ public Type getDiscriminatorType(); /** + * Get the discriminator value + */ + public Object getDiscriminatorValue(); + + /** * Get the concrete subclass corresponding to the given discriminator * value */ @@ -108,4 +112,26 @@ public boolean isAbstract(); + /** + * Register the name of a fetch profile determined to have an affect on the + * underlying loadable in regards to the fact that the underlying load SQL + * needs to be adjust when the given fetch profile is enabled. + * + * @param fetchProfileName The name of the profile affecting this. + */ + public void registerAffectingFetchProfile(String fetchProfileName); + + /** + * Given a column name and the root table alias in use for the entity hierarchy, determine the proper table alias + * for the table in that hierarchy that contains said column. + *

        + * NOTE : Generally speaking the column is not validated to exist. Most implementations simply return the + * root alias; the exception is {@link JoinedSubclassEntityPersister} + * + * @param columnName The column name + * @param rootAlias The hierarchy root alias + * + * @return The proper table alias for qualifying the given column. + */ + public String getTableAliasForColumn(String columnName, String rootAlias); } Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Lockable.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Lockable.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Lockable.java 17 Aug 2012 14:33:33 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Lockable.java 30 Jul 2014 16:16:32 -0000 1.1.2.1 @@ -24,6 +24,7 @@ */ package org.hibernate.persister.entity; + /** * Contract for things that can be locked via a {@link org.hibernate.dialect.lock.LockingStrategy}. *

        Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/NamedQueryLoader.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/entity/NamedQueryLoader.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/NamedQueryLoader.java 17 Aug 2012 14:33:33 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/NamedQueryLoader.java 30 Jul 2014 16:16:32 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,70 +20,76 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.persister.entity; import java.io.Serializable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.FlushMode; -import org.hibernate.HibernateException; -import org.hibernate.engine.EntityKey; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.impl.AbstractQueryImpl; +import org.hibernate.LockOptions; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.AbstractQueryImpl; +import org.hibernate.internal.CoreLogging; +import org.hibernate.internal.CoreMessageLogger; import org.hibernate.loader.entity.UniqueEntityLoader; /** - * Not really a Loader, just a wrapper around a - * named query. + * Not really a Loader, just a wrapper around a named query. Used when the metadata has named a query to use for + * loading an entity (using {@link org.hibernate.annotations.Loader} or {@code }). + * * @author Gavin King + * @author Steve Ebersole */ public final class NamedQueryLoader implements UniqueEntityLoader { + private static final CoreMessageLogger LOG = CoreLogging.messageLogger( NamedQueryLoader.class ); + private final String queryName; private final EntityPersister persister; - - private static final Logger log = LoggerFactory.getLogger(NamedQueryLoader.class); + /** + * Constructs the NamedQueryLoader + * + * @param queryName The name of the named query to use + * @param persister The corresponding persister for the entity we are loading + */ public NamedQueryLoader(String queryName, EntityPersister persister) { super(); this.queryName = queryName; this.persister = persister; } - public Object load(Serializable id, Object optionalObject, SessionImplementor session) - throws HibernateException { - - if ( log.isDebugEnabled() ) { - log.debug( - "loading entity: " + persister.getEntityName() + - " using named query: " + queryName - ); + @Override + public Object load(Serializable id, Object optionalObject, SessionImplementor session, LockOptions lockOptions) { + if ( lockOptions != null ) { + LOG.debug( "Ignoring lock-options passed to named query loader" ); } - - AbstractQueryImpl query = (AbstractQueryImpl) session.getNamedQuery(queryName); + return load( id, optionalObject, session ); + } + + @Override + public Object load(Serializable id, Object optionalObject, SessionImplementor session) { + LOG.debugf( "Loading entity: %s using named query: %s", persister.getEntityName(), queryName ); + + // IMPL NOTE: essentially we perform the named query (which loads the entity into the PC), and then + // do an internal lookup of the entity from the PC. + + final AbstractQueryImpl query = (AbstractQueryImpl) session.getNamedQuery( queryName ); if ( query.hasNamedParameters() ) { - query.setParameter( - query.getNamedParameters()[0], - id, - persister.getIdentifierType() - ); + query.setParameter( query.getNamedParameters()[0], id, persister.getIdentifierType() ); } else { query.setParameter( 0, id, persister.getIdentifierType() ); } - query.setOptionalId(id); + + query.setOptionalId( id ); query.setOptionalEntityName( persister.getEntityName() ); - query.setOptionalObject(optionalObject); + query.setOptionalObject( optionalObject ); query.setFlushMode( FlushMode.MANUAL ); query.list(); - + // now look up the object we are really interested in! - // (this lets us correctly handle proxies and multi-row - // or multi-column queries) - return session.getPersistenceContext() - .getEntity( new EntityKey( id, persister, session.getEntityMode() ) ); + // (this lets us correctly handle proxies and multi-row or multi-column queries) + return session.getPersistenceContext().getEntity( session.generateEntityKey( id, persister ) ); } -} \ No newline at end of file +} Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/OuterJoinLoadable.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/entity/OuterJoinLoadable.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/OuterJoinLoadable.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/OuterJoinLoadable.java 30 Jul 2014 16:16:32 -0000 1.1.2.1 @@ -23,9 +23,8 @@ * */ package org.hibernate.persister.entity; - import org.hibernate.FetchMode; -import org.hibernate.engine.CascadeStyle; +import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.type.EntityType; import org.hibernate.type.Type; Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/PropertyMapping.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/entity/PropertyMapping.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/PropertyMapping.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/PropertyMapping.java 30 Jul 2014 16:16:32 -0000 1.1.2.1 @@ -23,25 +23,33 @@ * */ package org.hibernate.persister.entity; - import org.hibernate.QueryException; import org.hibernate.type.Type; /** - * Abstraction of all mappings that define properties: - * entities, collection elements. + * Contract for all things that know how to map a property to the needed bits of SQL. + *

        + * The column/formula fragments that represent a property in the table defining the property be obtained by + * calling either {@link #toColumns(String, String)} or {@link #toColumns(String)} to obtain SQL-aliased + * column/formula fragments aliased or un-aliased, respectively. * + * + *

        + * Note, the methods here are generally ascribed to accept "property paths". That is a historical necessity because + * of how Hibernate originally understood composites (embeddables) internally. That is in the process of changing + * as Hibernate has added {@link org.hibernate.loader.plan.build.internal.spaces.CompositePropertyMapping} + * * @author Gavin King + * @author Steve Ebersole */ public interface PropertyMapping { - // TODO: It would be really, really nice to use this to also model components! /** * Given a component path expression, get the type of the property */ public Type toType(String propertyName) throws QueryException; + /** - * Given a query alias and a property path, return the qualified - * column name + * Obtain aliased column/formula fragments for the specified property path. */ public String[] toColumns(String alias, String propertyName) throws QueryException; /** Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Queryable.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Queryable.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Queryable.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/Queryable.java 30 Jul 2014 16:16:32 -0000 1.1.2.1 @@ -23,6 +23,7 @@ * */ package org.hibernate.persister.entity; +import org.hibernate.sql.SelectFragment; /** * Extends the generic EntityPersister contract to add @@ -52,30 +53,31 @@ public String getDiscriminatorSQLValue(); /** - * Given a query alias and an identifying suffix, render the intentifier select fragment. + * Given a query alias and an identifying suffix, render the identifier select fragment. */ public String identifierSelectFragment(String name, String suffix); /** * Given a query alias and an identifying suffix, render the property select fragment. */ public String propertySelectFragment(String alias, String suffix, boolean allProperties); + public SelectFragment propertySelectFragmentFragment(String alias, String suffix, boolean allProperties); /** * Get the names of columns used to persist the identifier */ public String[] getIdentifierColumnNames(); /** - * Is the inheritence hierarchy described by this persister contained across + * Is the inheritance hierarchy described by this persister contained across * multiple tables? * - * @return True if the inheritence hierarchy is spread across multiple tables; false otherwise. + * @return True if the inheritance hierarchy is spread across multiple tables; false otherwise. */ public boolean isMultiTable(); /** * Get the names of all tables used in the hierarchy (up and down) ordered such - * that deletes in the given order would not cause contraint violations. + * that deletes in the given order would not cause constraint violations. * * @return The ordered array of table names. */ @@ -89,9 +91,8 @@ * {@link #getConstraintOrderedTableNameClosure()}. *

        * The second dimension should have the same length across all the elements in - * the first dimension. If not, that'd be a problem ;) + * the first dimension. If not, that would be a problem ;) * - * @return */ public String[][] getContraintOrderedTableKeyColumnClosure(); @@ -120,7 +121,7 @@ * It is also relative to the indexing used to resolve {@link #getSubclassTableName}... * * @param propertyPath The name of the property. - * @return The nunber of the table to which the property is mapped. + * @return The number of the table to which the property is mapped. */ public int getSubclassPropertyTableNumber(String propertyPath); @@ -141,7 +142,6 @@ * array. * * @param number The index into the internal array. - * @return */ public String getSubclassTableName(int number); @@ -155,13 +155,23 @@ * enabled-filters). *

        * This may or may not be different from the root alias depending upon the - * inheritence mapping strategy. + * inheritance mapping strategy. * * @param rootAlias The root alias * @return The alias used for "filter conditions" within the where clause. */ public String generateFilterConditionAlias(String rootAlias); + /** + * Retrieve the information needed to properly deal with this entity's discriminator + * in a query. + * + * @return The entity discriminator metadata + */ + public DiscriminatorMetadata getTypeDiscriminatorMetadata(); + + String[][] getSubclassPropertyFormulaTemplateClosure(); + public static class Declarer { public static final Declarer CLASS = new Declarer( "class" ); public static final Declarer SUBCLASS = new Declarer( "subclass" ); Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/SQLLoadable.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/entity/SQLLoadable.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/SQLLoadable.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/SQLLoadable.java 30 Jul 2014 16:16:32 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.persister.entity; - import org.hibernate.type.Type; /** Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/SingleTableEntityPersister.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/entity/SingleTableEntityPersister.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/SingleTableEntityPersister.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/SingleTableEntityPersister.java 30 Jul 2014 16:16:32 -0000 1.1.2.1 @@ -23,21 +23,26 @@ * */ package org.hibernate.persister.entity; - import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Map; +import java.util.Set; -import org.hibernate.EntityMode; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.cache.access.EntityRegionAccessStrategy; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.ExecuteUpdateResultCheckStyle; +import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; +import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; +import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.DynamicFilterAliasGenerator; +import org.hibernate.internal.FilterAliasGenerator; +import org.hibernate.internal.util.MarkerObject; +import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.mapping.Column; import org.hibernate.mapping.Formula; import org.hibernate.mapping.Join; @@ -47,14 +52,20 @@ import org.hibernate.mapping.Subclass; import org.hibernate.mapping.Table; import org.hibernate.mapping.Value; +import org.hibernate.metamodel.binding.AttributeBinding; +import org.hibernate.metamodel.binding.CustomSQL; +import org.hibernate.metamodel.binding.EntityBinding; +import org.hibernate.metamodel.binding.SimpleValueBinding; +import org.hibernate.metamodel.binding.SingularAttributeBinding; +import org.hibernate.metamodel.relational.DerivedValue; +import org.hibernate.metamodel.relational.SimpleValue; +import org.hibernate.metamodel.relational.TableSpecification; import org.hibernate.sql.InFragment; import org.hibernate.sql.Insert; import org.hibernate.sql.SelectFragment; import org.hibernate.type.AssociationType; import org.hibernate.type.DiscriminatorType; import org.hibernate.type.Type; -import org.hibernate.util.ArrayHelper; -import org.hibernate.util.MarkerObject; /** * The default implementation of the EntityPersister interface. @@ -102,10 +113,13 @@ private final Map subclassesByDiscriminatorValue = new HashMap(); private final boolean forceDiscriminator; private final String discriminatorColumnName; + private final String discriminatorColumnReaders; + private final String discriminatorColumnReaderTemplate; private final String discriminatorFormula; private final String discriminatorFormulaTemplate; private final String discriminatorAlias; private final Type discriminatorType; + private final Object discriminatorValue; private final String discriminatorSQLValue; private final boolean discriminatorInsertable; @@ -119,16 +133,19 @@ private static final Object NULL_DISCRIMINATOR = new MarkerObject(""); private static final Object NOT_NULL_DISCRIMINATOR = new MarkerObject(""); + private static final String NULL_STRING = "null"; + private static final String NOT_NULL_STRING = "not null"; //INITIALIZATION: public SingleTableEntityPersister( final PersistentClass persistentClass, final EntityRegionAccessStrategy cacheAccessStrategy, + final NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy, final SessionFactoryImplementor factory, final Mapping mapping) throws HibernateException { - super( persistentClass, cacheAccessStrategy, factory ); + super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, factory ); // CLASS + TABLE @@ -230,16 +247,16 @@ ArrayHelper.toStringArray( persistentClass.getSynchronizedTables() ) ); - final boolean lazyAvailable = isInstrumented(EntityMode.POJO); + final boolean lazyAvailable = isInstrumented(); boolean hasDeferred = false; ArrayList subclassTables = new ArrayList(); ArrayList joinKeyColumns = new ArrayList(); - ArrayList isConcretes = new ArrayList(); - ArrayList isDeferreds = new ArrayList(); - ArrayList isInverses = new ArrayList(); - ArrayList isNullables = new ArrayList(); - ArrayList isLazies = new ArrayList(); + ArrayList isConcretes = new ArrayList(); + ArrayList isDeferreds = new ArrayList(); + ArrayList isInverses = new ArrayList(); + ArrayList isNullables = new ArrayList(); + ArrayList isLazies = new ArrayList(); subclassTables.add( qualifiedTableNames[0] ); joinKeyColumns.add( getIdentifierColumnNames() ); isConcretes.add(Boolean.TRUE); @@ -250,11 +267,11 @@ joinIter = persistentClass.getSubclassJoinClosureIterator(); while ( joinIter.hasNext() ) { Join join = (Join) joinIter.next(); - isConcretes.add( new Boolean( persistentClass.isClassOrSuperclassJoin(join) ) ); - isDeferreds.add( new Boolean( join.isSequentialSelect() ) ); - isInverses.add( new Boolean( join.isInverse() ) ); - isNullables.add( new Boolean( join.isOptional() ) ); - isLazies.add( new Boolean( lazyAvailable && join.isLazy() ) ); + isConcretes.add( persistentClass.isClassOrSuperclassJoin(join) ); + isDeferreds.add( join.isSequentialSelect() ); + isInverses.add( join.isInverse() ); + isNullables.add( join.isOptional() ); + isLazies.add( lazyAvailable && join.isLazy() ); if ( join.isSequentialSelect() && !persistentClass.isClassOrSuperclassJoin(join) ) hasDeferred = true; subclassTables.add( join.getTable().getQualifiedName( factory.getDialect(), @@ -274,15 +291,14 @@ subclassTableSequentialSelect = ArrayHelper.toBooleanArray(isDeferreds); subclassTableNameClosure = ArrayHelper.toStringArray(subclassTables); subclassTableIsLazyClosure = ArrayHelper.toBooleanArray(isLazies); - subclassTableKeyColumnClosure = ArrayHelper.to2DStringArray(joinKeyColumns); + subclassTableKeyColumnClosure = ArrayHelper.to2DStringArray( joinKeyColumns ); isClassOrSuperclassTable = ArrayHelper.toBooleanArray(isConcretes); isInverseSubclassTable = ArrayHelper.toBooleanArray(isInverses); isNullableSubclassTable = ArrayHelper.toBooleanArray(isNullables); hasSequentialSelects = hasDeferred; // DISCRIMINATOR - final Object discriminatorValue; if ( persistentClass.isPolymorphic() ) { Value discrimValue = persistentClass.getDiscriminator(); if (discrimValue==null) { @@ -295,11 +311,15 @@ discriminatorFormula = formula.getFormula(); discriminatorFormulaTemplate = formula.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() ); discriminatorColumnName = null; + discriminatorColumnReaders = null; + discriminatorColumnReaderTemplate = null; discriminatorAlias = "clazz_"; } else { Column column = (Column) selectable; discriminatorColumnName = column.getQuotedName( factory.getDialect() ); + discriminatorColumnReaders = column.getReadExpr( factory.getDialect() ); + discriminatorColumnReaderTemplate = column.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() ); discriminatorAlias = column.getAlias( factory.getDialect(), persistentClass.getRootTable() ); discriminatorFormula = null; discriminatorFormulaTemplate = null; @@ -334,6 +354,8 @@ forceDiscriminator = false; discriminatorInsertable = false; discriminatorColumnName = null; + discriminatorColumnReaders = null; + discriminatorColumnReaderTemplate = null; discriminatorAlias = null; discriminatorType = null; discriminatorValue = null; @@ -362,7 +384,7 @@ iter = persistentClass.getSubclassPropertyClosureIterator(); while ( iter.hasNext() ) { Property prop = (Property) iter.next(); - Integer join = new Integer( persistentClass.getJoinNumber(prop) ); + Integer join = persistentClass.getJoinNumber(prop); propertyJoinNumbers.add(join); //propertyTableNumbersByName.put( prop.getName(), join ); @@ -390,7 +412,7 @@ subclassClosure = new String[subclassSpan]; subclassClosure[0] = getEntityName(); if ( persistentClass.isPolymorphic() ) { - subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() ); + addSubclassByDiscriminatorValue( discriminatorValue, getEntityName() ); } // SUBCLASSES @@ -401,15 +423,15 @@ Subclass sc = (Subclass) iter.next(); subclassClosure[k++] = sc.getEntityName(); if ( sc.isDiscriminatorValueNull() ) { - subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, sc.getEntityName() ); + addSubclassByDiscriminatorValue( NULL_DISCRIMINATOR, sc.getEntityName() ); } else if ( sc.isDiscriminatorValueNotNull() ) { - subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, sc.getEntityName() ); + addSubclassByDiscriminatorValue( NOT_NULL_DISCRIMINATOR, sc.getEntityName() ); } else { try { DiscriminatorType dtype = (DiscriminatorType) discriminatorType; - subclassesByDiscriminatorValue.put( + addSubclassByDiscriminatorValue( dtype.stringToObject( sc.getDiscriminatorValue() ), sc.getEntityName() ); @@ -432,6 +454,290 @@ } + private void addSubclassByDiscriminatorValue(Object discriminatorValue, String entityName) { + String mappedEntityName = (String) subclassesByDiscriminatorValue.put( discriminatorValue, entityName ); + if ( mappedEntityName != null ) { + throw new MappingException( + "Entities [" + entityName + "] and [" + mappedEntityName + + "] are mapped with the same discriminator value '" + discriminatorValue + "'." + ); + } + } + + public SingleTableEntityPersister( + final EntityBinding entityBinding, + final EntityRegionAccessStrategy cacheAccessStrategy, + final NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy, + final SessionFactoryImplementor factory, + final Mapping mapping) throws HibernateException { + + super( entityBinding, cacheAccessStrategy, naturalIdRegionAccessStrategy, factory ); + + // CLASS + TABLE + + // TODO: fix when joins are working (HHH-6391) + //joinSpan = entityBinding.getJoinClosureSpan() + 1; + joinSpan = 1; + qualifiedTableNames = new String[joinSpan]; + isInverseTable = new boolean[joinSpan]; + isNullableTable = new boolean[joinSpan]; + keyColumnNames = new String[joinSpan][]; + + final TableSpecification table = entityBinding.getPrimaryTable(); + qualifiedTableNames[0] = table.getQualifiedName( factory.getDialect() ); + isInverseTable[0] = false; + isNullableTable[0] = false; + keyColumnNames[0] = getIdentifierColumnNames(); + cascadeDeleteEnabled = new boolean[joinSpan]; + + // Custom sql + customSQLInsert = new String[joinSpan]; + customSQLUpdate = new String[joinSpan]; + customSQLDelete = new String[joinSpan]; + insertCallable = new boolean[joinSpan]; + updateCallable = new boolean[joinSpan]; + deleteCallable = new boolean[joinSpan]; + insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan]; + updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan]; + deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan]; + + initializeCustomSql( entityBinding.getCustomInsert(), 0, customSQLInsert, insertCallable, insertResultCheckStyles ); + initializeCustomSql( entityBinding.getCustomUpdate(), 0, customSQLUpdate, updateCallable, updateResultCheckStyles ); + initializeCustomSql( entityBinding.getCustomDelete(), 0, customSQLDelete, deleteCallable, deleteResultCheckStyles ); + + // JOINS + + // TODO: add join stuff when HHH-6391 is working + + constraintOrderedTableNames = new String[qualifiedTableNames.length]; + constraintOrderedKeyColumnNames = new String[qualifiedTableNames.length][]; + for ( int i = qualifiedTableNames.length - 1, position = 0; i >= 0; i--, position++ ) { + constraintOrderedTableNames[position] = qualifiedTableNames[i]; + constraintOrderedKeyColumnNames[position] = keyColumnNames[i]; + } + + spaces = ArrayHelper.join( + qualifiedTableNames, + ArrayHelper.toStringArray( entityBinding.getSynchronizedTableNames() ) + ); + + final boolean lazyAvailable = isInstrumented(); + + boolean hasDeferred = false; + ArrayList subclassTables = new ArrayList(); + ArrayList joinKeyColumns = new ArrayList(); + ArrayList isConcretes = new ArrayList(); + ArrayList isDeferreds = new ArrayList(); + ArrayList isInverses = new ArrayList(); + ArrayList isNullables = new ArrayList(); + ArrayList isLazies = new ArrayList(); + subclassTables.add( qualifiedTableNames[0] ); + joinKeyColumns.add( getIdentifierColumnNames() ); + isConcretes.add(Boolean.TRUE); + isDeferreds.add(Boolean.FALSE); + isInverses.add(Boolean.FALSE); + isNullables.add(Boolean.FALSE); + isLazies.add(Boolean.FALSE); + + // TODO: add join stuff when HHH-6391 is working + + + subclassTableSequentialSelect = ArrayHelper.toBooleanArray(isDeferreds); + subclassTableNameClosure = ArrayHelper.toStringArray(subclassTables); + subclassTableIsLazyClosure = ArrayHelper.toBooleanArray(isLazies); + subclassTableKeyColumnClosure = ArrayHelper.to2DStringArray( joinKeyColumns ); + isClassOrSuperclassTable = ArrayHelper.toBooleanArray(isConcretes); + isInverseSubclassTable = ArrayHelper.toBooleanArray(isInverses); + isNullableSubclassTable = ArrayHelper.toBooleanArray(isNullables); + hasSequentialSelects = hasDeferred; + + // DISCRIMINATOR + + if ( entityBinding.isPolymorphic() ) { + SimpleValue discriminatorRelationalValue = entityBinding.getHierarchyDetails().getEntityDiscriminator().getBoundValue(); + if ( discriminatorRelationalValue == null ) { + throw new MappingException("discriminator mapping required for single table polymorphic persistence"); + } + forceDiscriminator = entityBinding.getHierarchyDetails().getEntityDiscriminator().isForced(); + if ( DerivedValue.class.isInstance( discriminatorRelationalValue ) ) { + DerivedValue formula = ( DerivedValue ) discriminatorRelationalValue; + discriminatorFormula = formula.getExpression(); + discriminatorFormulaTemplate = getTemplateFromString( formula.getExpression(), factory ); + discriminatorColumnName = null; + discriminatorColumnReaders = null; + discriminatorColumnReaderTemplate = null; + discriminatorAlias = "clazz_"; + } + else { + org.hibernate.metamodel.relational.Column column = ( org.hibernate.metamodel.relational.Column ) discriminatorRelationalValue; + discriminatorColumnName = column.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() ); + discriminatorColumnReaders = + column.getReadFragment() == null ? + column.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() ) : + column.getReadFragment(); + discriminatorColumnReaderTemplate = getTemplateFromColumn( column, factory ); + discriminatorAlias = column.getAlias( factory.getDialect() ); + discriminatorFormula = null; + discriminatorFormulaTemplate = null; + } + + discriminatorType = entityBinding.getHierarchyDetails() + .getEntityDiscriminator() + .getExplicitHibernateTypeDescriptor() + .getResolvedTypeMapping(); + if ( entityBinding.getDiscriminatorMatchValue() == null ) { + discriminatorValue = NULL_DISCRIMINATOR; + discriminatorSQLValue = InFragment.NULL; + discriminatorInsertable = false; + } + else if ( entityBinding.getDiscriminatorMatchValue().equals( NULL_STRING ) ) { + discriminatorValue = NOT_NULL_DISCRIMINATOR; + discriminatorSQLValue = InFragment.NOT_NULL; + discriminatorInsertable = false; + } + else if ( entityBinding.getDiscriminatorMatchValue().equals( NOT_NULL_STRING ) ) { + discriminatorValue = NOT_NULL_DISCRIMINATOR; + discriminatorSQLValue = InFragment.NOT_NULL; + discriminatorInsertable = false; + } + else { + discriminatorInsertable = entityBinding.getHierarchyDetails().getEntityDiscriminator().isInserted() + && ! DerivedValue.class.isInstance( discriminatorRelationalValue ); + try { + DiscriminatorType dtype = ( DiscriminatorType ) discriminatorType; + discriminatorValue = dtype.stringToObject( entityBinding.getDiscriminatorMatchValue() ); + discriminatorSQLValue = dtype.objectToSQLString( discriminatorValue, factory.getDialect() ); + } + catch (ClassCastException cce) { + throw new MappingException("Illegal discriminator type: " + discriminatorType.getName() ); + } + catch (Exception e) { + throw new MappingException("Could not format discriminator value to SQL string", e); + } + } + } + else { + forceDiscriminator = false; + discriminatorInsertable = false; + discriminatorColumnName = null; + discriminatorColumnReaders = null; + discriminatorColumnReaderTemplate = null; + discriminatorAlias = null; + discriminatorType = null; + discriminatorValue = null; + discriminatorSQLValue = null; + discriminatorFormula = null; + discriminatorFormulaTemplate = null; + } + + // PROPERTIES + + propertyTableNumbers = new int[ getPropertySpan() ]; + int i=0; + for( AttributeBinding attributeBinding : entityBinding.getAttributeBindingClosure() ) { + // TODO: fix when joins are working (HHH-6391) + //propertyTableNumbers[i++] = entityBinding.getJoinNumber( attributeBinding); + if ( attributeBinding == entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() ) { + continue; // skip identifier binding + } + if ( ! attributeBinding.getAttribute().isSingular() ) { + continue; + } + propertyTableNumbers[ i++ ] = 0; + } + + //TODO: code duplication with JoinedSubclassEntityPersister + + ArrayList columnJoinNumbers = new ArrayList(); + ArrayList formulaJoinedNumbers = new ArrayList(); + ArrayList propertyJoinNumbers = new ArrayList(); + + for ( AttributeBinding attributeBinding : entityBinding.getSubEntityAttributeBindingClosure() ) { + if ( ! attributeBinding.getAttribute().isSingular() ) { + continue; + } + SingularAttributeBinding singularAttributeBinding = (SingularAttributeBinding) attributeBinding; + + // TODO: fix when joins are working (HHH-6391) + //int join = entityBinding.getJoinNumber(singularAttributeBinding); + int join = 0; + propertyJoinNumbers.add(join); + + //propertyTableNumbersByName.put( singularAttributeBinding.getName(), join ); + propertyTableNumbersByNameAndSubclass.put( + singularAttributeBinding.getContainer().getPathBase() + '.' + singularAttributeBinding.getAttribute().getName(), + join + ); + + for ( SimpleValueBinding simpleValueBinding : singularAttributeBinding.getSimpleValueBindings() ) { + if ( DerivedValue.class.isInstance( simpleValueBinding.getSimpleValue() ) ) { + formulaJoinedNumbers.add( join ); + } + else { + columnJoinNumbers.add( join ); + } + } + } + subclassColumnTableNumberClosure = ArrayHelper.toIntArray(columnJoinNumbers); + subclassFormulaTableNumberClosure = ArrayHelper.toIntArray(formulaJoinedNumbers); + subclassPropertyTableNumberClosure = ArrayHelper.toIntArray(propertyJoinNumbers); + + int subclassSpan = entityBinding.getSubEntityBindingClosureSpan() + 1; + subclassClosure = new String[subclassSpan]; + subclassClosure[0] = getEntityName(); + if ( entityBinding.isPolymorphic() ) { + addSubclassByDiscriminatorValue( discriminatorValue, getEntityName() ); + } + + // SUBCLASSES + if ( entityBinding.isPolymorphic() ) { + int k=1; + for ( EntityBinding subEntityBinding : entityBinding.getPostOrderSubEntityBindingClosure() ) { + subclassClosure[k++] = subEntityBinding.getEntity().getName(); + if ( subEntityBinding.isDiscriminatorMatchValueNull() ) { + addSubclassByDiscriminatorValue( NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() ); + } + else if ( subEntityBinding.isDiscriminatorMatchValueNotNull() ) { + addSubclassByDiscriminatorValue( NOT_NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() ); + } + else { + try { + DiscriminatorType dtype = (DiscriminatorType) discriminatorType; + addSubclassByDiscriminatorValue( + dtype.stringToObject( subEntityBinding.getDiscriminatorMatchValue() ), + subEntityBinding.getEntity().getName() + ); + } + catch (ClassCastException cce) { + throw new MappingException("Illegal discriminator type: " + discriminatorType.getName() ); + } + catch (Exception e) { + throw new MappingException("Error parsing discriminator value", e); + } + } + } + } + + initLockers(); + + initSubclassPropertyAliasesMap( entityBinding ); + + postConstruct( mapping ); + } + + private static void initializeCustomSql( + CustomSQL customSql, + int i, + String[] sqlStrings, + boolean[] callable, + ExecuteUpdateResultCheckStyle[] checkStyles) { + sqlStrings[i] = customSql != null ? customSql.getSql(): null; + callable[i] = sqlStrings[i] != null && customSql.isCallable(); + checkStyles[i] = customSql != null && customSql.getCheckStyle() != null ? + customSql.getCheckStyle() : + ExecuteUpdateResultCheckStyle.determineDefault( sqlStrings[i], callable[i] ); + } + protected boolean isInverseTable(int j) { return isInverseTable[j]; } @@ -444,6 +750,14 @@ return discriminatorColumnName; } + public String getDiscriminatorColumnReaders() { + return discriminatorColumnReaders; + } + + public String getDiscriminatorColumnReaderTemplate() { + return discriminatorColumnReaderTemplate; + } + protected String getDiscriminatorAlias() { return discriminatorAlias; } @@ -460,6 +774,10 @@ return discriminatorType; } + public Object getDiscriminatorValue() { + return discriminatorValue; + } + public String getDiscriminatorSQLValue() { return discriminatorSQLValue; } @@ -519,50 +837,97 @@ return getTableName() + ' ' + name; } + @Override public String filterFragment(String alias) throws MappingException { String result = discriminatorFilterFragment(alias); if ( hasWhere() ) result += " and " + getSQLWhereString(alias); return result; } + + private String discriminatorFilterFragment(String alias) throws MappingException { + return discriminatorFilterFragment( alias, null ); + } public String oneToManyFilterFragment(String alias) throws MappingException { - return forceDiscriminator ? - discriminatorFilterFragment(alias) : - ""; + return forceDiscriminator + ? discriminatorFilterFragment( alias, null ) + : ""; } - private String discriminatorFilterFragment(String alias) throws MappingException { - if ( needsDiscriminator() ) { - InFragment frag = new InFragment(); + @Override + public String oneToManyFilterFragment(String alias, Set treatAsDeclarations) { + return needsDiscriminator() + ? discriminatorFilterFragment( alias, treatAsDeclarations ) + : ""; + } - if ( isDiscriminatorFormula() ) { - frag.setFormula( alias, getDiscriminatorFormulaTemplate() ); - } - else { - frag.setColumn( alias, getDiscriminatorColumnName() ); - } + @Override + public String filterFragment(String alias, Set treatAsDeclarations) { + String result = discriminatorFilterFragment( alias, treatAsDeclarations ); + if ( hasWhere() ) { + result += " and " + getSQLWhereString( alias ); + } + return result; + } - String[] subclasses = getSubclassClosure(); - for ( int i=0; i treatAsDeclarations) { + final boolean hasTreatAs = treatAsDeclarations != null && !treatAsDeclarations.isEmpty(); - StringBuffer buf = new StringBuffer(50) - .append(" and ") - .append( frag.toFragmentString() ); + if ( !needsDiscriminator() && !hasTreatAs) { + return ""; + } - return buf.toString(); + final InFragment frag = new InFragment(); + if ( isDiscriminatorFormula() ) { + frag.setFormula( alias, getDiscriminatorFormulaTemplate() ); } else { - return ""; + frag.setColumn( alias, getDiscriminatorColumnName() ); } + + if ( hasTreatAs ) { + frag.addValues( decodeTreatAsRequests( treatAsDeclarations ) ); + } + else { + frag.addValues( fullDiscriminatorValues() ); + } + + return " and " + frag.toFragmentString(); } private boolean needsDiscriminator() { return forceDiscriminator || isInherited(); } + private String[] decodeTreatAsRequests(Set treatAsDeclarations) { + final List values = new ArrayList(); + for ( String subclass : treatAsDeclarations ) { + final Queryable queryable = (Queryable) getFactory().getEntityPersister( subclass ); + if ( !queryable.isAbstract() ) { + values.add( queryable.getDiscriminatorSQLValue() ); + } + } + return values.toArray( new String[ values.size() ] ); + } + + private String[] fullDiscriminatorValues; + + private String[] fullDiscriminatorValues() { + if ( fullDiscriminatorValues == null ) { + // first access; build it + final List values = new ArrayList(); + for ( String subclass : getSubclassClosure() ) { + final Queryable queryable = (Queryable) getFactory().getEntityPersister( subclass ); + if ( !queryable.isAbstract() ) { + values.add( queryable.getDiscriminatorSQLValue() ); + } + } + fullDiscriminatorValues = values.toArray( new String[values.size() ] ); + } + + return fullDiscriminatorValues; + } + public String getSubclassPropertyTableName(int i) { return subclassTableNameClosure[ subclassPropertyTableNumberClosure[i] ]; } @@ -621,7 +986,7 @@ Type type = propertyMapping.toType(propertyName); if ( type.isAssociationType() && ( (AssociationType) type ).useLHSPrimaryKey() ) return 0; final Integer tabnum = (Integer) propertyTableNumbersByNameAndSubclass.get(entityName + '.' + propertyName); - return tabnum==null ? 0 : tabnum.intValue(); + return tabnum==null ? 0 : tabnum; } protected String getSequentialSelect(String entityName) { @@ -642,7 +1007,7 @@ for ( int i=0; i treatAsDeclarations) { + return filterFragment( alias ); + } + public String getSubclassPropertyTableName(int i) { return getTableName();//ie. the subquery! yuck! } @@ -390,7 +427,7 @@ ); } - HashSet columns = new HashSet(); + HashSet columns = new LinkedHashSet(); Iterator titer = model.getSubclassTableClosureIterator(); while ( titer.hasNext() ) { Table table = (Table) titer.next(); @@ -400,7 +437,7 @@ } } - StringBuffer buf = new StringBuffer() + StringBuilder buf = new StringBuilder() .append("( "); Iterator siter = new JoinedIterator( @@ -422,7 +459,7 @@ buf.append( dialect.getSelectClauseNullString(sqlType) ) .append(" as "); } - buf.append( col.getName() ); + buf.append( col.getQuotedName(dialect) ); buf.append(", "); } buf.append( clazz.getSubclassId() ) @@ -479,4 +516,9 @@ public String[][] getContraintOrderedTableKeyColumnClosure() { return constraintOrderedKeyColumnNames; } + + @Override + public FilterAliasGenerator getFilterAliasGenerator(String rootAlias) { + return new StaticFilterAliasGenerator(rootAlias); + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/UniqueKeyLoadable.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/persister/entity/UniqueKeyLoadable.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/UniqueKeyLoadable.java 17 Aug 2012 14:33:34 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/persister/entity/UniqueKeyLoadable.java 30 Jul 2014 16:16:32 -0000 1.1.2.1 @@ -23,9 +23,8 @@ * */ package org.hibernate.persister.entity; - import org.hibernate.HibernateException; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; /** * @author Gavin King Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/internal/PersisterClassResolverInitiator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/internal/PersisterFactoryImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/internal/PersisterFactoryInitiator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/internal/StandardPersisterClassResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/spi/HydratedCompoundValueHandler.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/spi/PersisterClassResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/spi/PersisterFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/spi/UnknownPersisterException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/internal/CompositionSingularSubAttributesHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/internal/EntityIdentifierDefinitionHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/internal/FetchStrategyHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/internal/StandardAnyTypeDefinition.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/AnyMappingDefinition.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/AssociationAttributeDefinition.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/AssociationKey.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/AssociationVisitationStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/AttributeDefinition.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/AttributeSource.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/CollectionDefinition.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/CollectionElementDefinition.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/CollectionIndexDefinition.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/CompositeCollectionElementDefinition.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/CompositionDefinition.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/EncapsulatedEntityIdentifierDefinition.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/EntityDefinition.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/EntityIdentifierDefinition.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/MetamodelGraphWalker.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/NonEncapsulatedEntityIdentifierDefinition.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/WalkingException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/persister/walking/spi/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/pretty/MessageHelper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/pretty/MessageHelper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/pretty/MessageHelper.java 17 Aug 2012 14:36:55 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/pretty/MessageHelper.java 30 Jul 2014 16:16:46 -0000 1.1.2.1 @@ -23,10 +23,11 @@ * */ package org.hibernate.pretty; - import java.io.Serializable; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.type.Type; @@ -55,7 +56,7 @@ * @return An info string, in the form [FooBar#1]. */ public static String infoString(String entityName, Serializable id) { - StringBuffer s = new StringBuffer(); + StringBuilder s = new StringBuilder(); s.append( '[' ); if( entityName == null ) { s.append( "" ); @@ -81,14 +82,14 @@ * * @param persister The persister for the entity * @param id The entity id value - * @param factory The session factory + * @param factory The session factory - Could be null! * @return An info string, in the form [FooBar#1] */ public static String infoString( - EntityPersister persister, + EntityPersister persister, Object id, SessionFactoryImplementor factory) { - StringBuffer s = new StringBuffer(); + StringBuilder s = new StringBuilder(); s.append( '[' ); Type idType; if( persister == null ) { @@ -109,7 +110,12 @@ s.append( id ); } else { - s.append( idType.toLoggableString( id, factory ) ); + if ( factory != null ) { + s.append( idType.toLoggableString( id, factory ) ); + } + else { + s.append( "" ); + } } } s.append( ']' ); @@ -132,7 +138,7 @@ Object id, Type identifierType, SessionFactoryImplementor factory) { - StringBuffer s = new StringBuffer(); + StringBuilder s = new StringBuilder(); s.append( '[' ); if( persister == null ) { s.append( "" ); @@ -165,7 +171,7 @@ EntityPersister persister, Serializable[] ids, SessionFactoryImplementor factory) { - StringBuffer s = new StringBuffer(); + StringBuilder s = new StringBuilder(); s.append( '[' ); if( persister == null ) { s.append( "" ); @@ -194,7 +200,7 @@ * @return An info string, in the form [FooBar] */ public static String infoString(EntityPersister persister) { - StringBuffer s = new StringBuffer(); + StringBuilder s = new StringBuilder(); s.append( '[' ); if ( persister == null ) { s.append( "" ); @@ -216,7 +222,7 @@ * @return An info string, in the form [Foo.bars#1] */ public static String infoString(String entityName, String propertyName, Object key) { - StringBuffer s = new StringBuffer() + StringBuilder s = new StringBuilder() .append( '[' ) .append( entityName ) .append( '.' ) @@ -235,7 +241,52 @@ // collections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * Generate an info message string relating to a particular managed + * collection. Attempts to intelligently handle property-refs issues + * where the collection key is not the same as the owner key. + * + * @param persister The persister for the collection + * @param collection The collection itself + * @param collectionKey The collection key + * @param session The session + * @return An info string, in the form [Foo.bars#1] + */ + public static String collectionInfoString( + CollectionPersister persister, + PersistentCollection collection, + Serializable collectionKey, + SessionImplementor session ) { + + StringBuilder s = new StringBuilder(); + s.append( '[' ); + if ( persister == null ) { + s.append( "" ); + } + else { + s.append( persister.getRole() ); + s.append( '#' ); + + Type ownerIdentifierType = persister.getOwnerEntityPersister() + .getIdentifierType(); + Serializable ownerKey; + // TODO: Is it redundant to attempt to use the collectionKey, + // or is always using the owner id sufficient? + if ( collectionKey.getClass().isAssignableFrom( + ownerIdentifierType.getReturnedClass() ) ) { + ownerKey = collectionKey; + } else { + ownerKey = session.getPersistenceContext() + .getEntry( collection.getOwner() ).getId(); + } + s.append( ownerIdentifierType.toLoggableString( + ownerKey, session.getFactory() ) ); + } + s.append( ']' ); + return s.toString(); + } /** * Generate an info message string relating to a series of managed @@ -250,7 +301,7 @@ CollectionPersister persister, Serializable[] ids, SessionFactoryImplementor factory) { - StringBuffer s = new StringBuffer(); + StringBuilder s = new StringBuilder(); s.append( '[' ); if ( persister == null ) { s.append( "" ); @@ -259,11 +310,7 @@ s.append( persister.getRole() ); s.append( "#<" ); for ( int i = 0; i < ids.length; i++ ) { - // Need to use the identifier type of the collection owner - // since the incoming is value is actually the owner's id. - // Using the collection's key type causes problems with - // property-ref keys... - s.append( persister.getOwnerEntityPersister().getIdentifierType().toLoggableString( ids[i], factory ) ); + addIdToCollectionInfoString( persister, ids[i], factory, s ); if ( i < ids.length-1 ) { s.append( ", " ); } @@ -287,7 +334,7 @@ CollectionPersister persister, Serializable id, SessionFactoryImplementor factory) { - StringBuffer s = new StringBuffer(); + StringBuilder s = new StringBuilder(); s.append( '[' ); if ( persister == null ) { s.append( "" ); @@ -300,17 +347,37 @@ s.append( "" ); } else { - // Need to use the identifier type of the collection owner - // since the incoming is value is actually the owner's id. - // Using the collection's key type causes problems with - // property-ref keys... - s.append( persister.getOwnerEntityPersister().getIdentifierType().toLoggableString( id, factory ) ); + addIdToCollectionInfoString( persister, id, factory, s ); } } s.append( ']' ); return s.toString(); } + + private static void addIdToCollectionInfoString( + CollectionPersister persister, + Serializable id, + SessionFactoryImplementor factory, + StringBuilder s ) { + // Need to use the identifier type of the collection owner + // since the incoming is value is actually the owner's id. + // Using the collection's key type causes problems with + // property-ref keys. + // Also need to check that the expected identifier type matches + // the given ID. Due to property-ref keys, the collection key + // may not be the owner key. + Type ownerIdentifierType = persister.getOwnerEntityPersister() + .getIdentifierType(); + if ( id.getClass().isAssignableFrom( + ownerIdentifierType.getReturnedClass() ) ) { + s.append( ownerIdentifierType.toLoggableString( id, factory ) ); + } else { + // TODO: This is a crappy backup if a property-ref is used. + // If the reference is an object w/o toString(), this isn't going to work. + s.append( id.toString() ); + } + } /** * Generate an info message string relating to a particular managed @@ -321,7 +388,7 @@ * @return An info string, in the form [Foo.bars#1] */ public static String collectionInfoString(String role, Serializable id) { - StringBuffer s = new StringBuffer(); + StringBuilder s = new StringBuilder(); s.append( '[' ); if( role == null ) { s.append( "" ); Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/pretty/Printer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/NamedParametersNotSupportedException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/NoSuchParameterException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/ParameterBind.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/ParameterMisuseException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/ParameterRegistration.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/ParameterStrategyException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/ProcedureCall.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/ProcedureCallMemento.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/ProcedureOutputs.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/UnknownSqlResultSetMappingException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/internal/AbstractParameterRegistrationImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/internal/NamedParameterRegistration.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/internal/ParameterBindImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/internal/PositionalParameterRegistration.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/internal/PostgresCallableStatementSupport.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/internal/ProcedureCallImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/internal/ProcedureCallMementoImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/internal/ProcedureOutputsImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/internal/StandardCallableStatementSupport.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/internal/Util.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/internal/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/spi/CallableStatementSupport.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/spi/ParameterRegistrationImplementor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/procedure/spi/ParameterStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/property/BackrefPropertyAccessor.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/property/BackrefPropertyAccessor.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/property/BackrefPropertyAccessor.java 17 Aug 2012 14:36:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/property/BackrefPropertyAccessor.java 30 Jul 2014 16:16:26 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,16 +20,15 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; - import java.io.Serializable; +import java.lang.reflect.Member; import java.lang.reflect.Method; import java.util.Map; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; /** * Represents a "back-reference" to the id of a collection owner. A "back-reference" is pertinent in mapping scenarios @@ -56,6 +55,7 @@ * we don't know the value of the back reference */ public static final Serializable UNKNOWN = new Serializable() { + @Override public String toString() { return ""; } @@ -79,16 +79,12 @@ this.getter = new BackrefGetter(); } - /** - * {@inheritDoc} - */ + @Override public Setter getSetter(Class theClass, String propertyName) { return setter; } - /** - * {@inheritDoc} - */ + @Override public Getter getGetter(Class theClass, String propertyName) { return getter; } @@ -98,24 +94,17 @@ * Internal implementation of a property setter specific to these back-ref properties. */ public static final class BackrefSetter implements Setter { - - /** - * {@inheritDoc} - */ + @Override public Method getMethod() { return null; } - /** - * {@inheritDoc} - */ + @Override public String getMethodName() { return null; } - /** - * {@inheritDoc} - */ + @Override public void set(Object target, Object value, SessionFactoryImplementor factory) { // this page intentionally left blank :) } @@ -127,10 +116,7 @@ * Internal implementation of a property getter specific to these back-ref properties. */ public class BackrefGetter implements Getter { - - /** - * {@inheritDoc} - */ + @Override public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) { if ( session == null ) { return UNKNOWN; @@ -140,30 +126,27 @@ } } - /** - * {@inheritDoc} - */ + @Override + public Member getMember() { + return null; + } + + @Override public Object get(Object target) { return UNKNOWN; } - /** - * {@inheritDoc} - */ + @Override public Method getMethod() { return null; } - /** - * {@inheritDoc} - */ + @Override public String getMethodName() { return null; } - /** - * {@inheritDoc} - */ + @Override public Class getReturnType() { return Object.class; } Index: 3rdParty_sources/hibernate-core/org/hibernate/property/BasicPropertyAccessor.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/property/BasicPropertyAccessor.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/property/BasicPropertyAccessor.java 17 Aug 2012 14:36:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/property/BasicPropertyAccessor.java 30 Jul 2014 16:16:27 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,35 +20,36 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; import java.beans.Introspector; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Member; import java.lang.reflect.Method; import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import org.hibernate.HibernateException; import org.hibernate.PropertyAccessException; import org.hibernate.PropertyNotFoundException; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.util.ReflectHelper; +import org.hibernate.PropertySetterAccessException; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.CoreLogging; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.ReflectHelper; +import org.jboss.logging.Logger; + /** * Accesses property values via a get/set pair, which may be nonpublic. * The default (and recommended strategy). - * + * * @author Gavin King */ public class BasicPropertyAccessor implements PropertyAccessor { + private static final CoreMessageLogger LOG = CoreLogging.messageLogger( BasicPropertyAccessor.class ); - private static final Logger log = LoggerFactory.getLogger(BasicPropertyAccessor.class); - public static final class BasicSetter implements Setter { private Class clazz; private final transient Method method; @@ -60,86 +61,83 @@ this.propertyName=propertyName; } - public void set(Object target, Object value, SessionFactoryImplementor factory) + @Override + public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException { try { - method.invoke( target, new Object[] { value } ); + method.invoke( target, value ); } catch (NullPointerException npe) { if ( value==null && method.getParameterTypes()[0].isPrimitive() ) { throw new PropertyAccessException( - npe, - "Null value was assigned to a property of primitive type", - true, - clazz, + npe, + "Null value was assigned to a property of primitive type", + true, + clazz, propertyName ); } else { throw new PropertyAccessException( - npe, - "NullPointerException occurred while calling", - true, - clazz, + npe, + "NullPointerException occurred while calling", + true, + clazz, propertyName ); } } catch (InvocationTargetException ite) { throw new PropertyAccessException( - ite, - "Exception occurred inside", - true, - clazz, + ite, + "Exception occurred inside", + true, + clazz, propertyName ); } catch (IllegalAccessException iae) { throw new PropertyAccessException( - iae, - "IllegalAccessException occurred while calling", - true, - clazz, + iae, + "IllegalAccessException occurred while calling", + true, + clazz, propertyName ); //cannot occur } catch (IllegalArgumentException iae) { if ( value==null && method.getParameterTypes()[0].isPrimitive() ) { throw new PropertyAccessException( - iae, - "Null value was assigned to a property of primitive type", - true, - clazz, + iae, + "Null value was assigned to a property of primitive type", + true, + clazz, propertyName ); } else { - log.error( - "IllegalArgumentException in class: " + clazz.getName() + - ", setter method of property: " + propertyName + final Class expectedType = method.getParameterTypes()[0]; + LOG.illegalPropertySetterArgument( clazz.getName(), propertyName ); + LOG.expectedType( expectedType.getName(), value == null ? null : value.getClass().getName() ); + throw new PropertySetterAccessException( + iae, + clazz, + propertyName, + expectedType, + target, + value ); - log.error( - "expected type: " + - method.getParameterTypes()[0].getName() + - ", actual value: " + - ( value==null ? null : value.getClass().getName() ) - ); - throw new PropertyAccessException( - iae, - "IllegalArgumentException occurred while calling", - true, - clazz, - propertyName - ); } } } + @Override public Method getMethod() { return method; } + @Override public String getMethodName() { return method.getName(); } @@ -148,7 +146,8 @@ return createSetter(clazz, propertyName); } - public String toString() { + @Override + public String toString() { return "BasicSetter(" + clazz.getName() + '.' + propertyName + ')'; } } @@ -164,84 +163,91 @@ this.propertyName=propertyName; } + @Override public Object get(Object target) throws HibernateException { try { - return method.invoke(target, null); + return method.invoke( target, (Object[]) null ); } catch (InvocationTargetException ite) { throw new PropertyAccessException( - ite, - "Exception occurred inside", - false, - clazz, + ite, + "Exception occurred inside", + false, + clazz, propertyName ); } catch (IllegalAccessException iae) { throw new PropertyAccessException( - iae, - "IllegalAccessException occurred while calling", - false, - clazz, + iae, + "IllegalAccessException occurred while calling", + false, + clazz, propertyName ); //cannot occur } catch (IllegalArgumentException iae) { - log.error( - "IllegalArgumentException in class: " + clazz.getName() + - ", getter method of property: " + propertyName - ); + LOG.illegalPropertyGetterArgument(clazz.getName(), propertyName); throw new PropertyAccessException( - iae, - "IllegalArgumentException occurred calling", - false, - clazz, + iae, + "IllegalArgumentException occurred calling", + false, + clazz, propertyName ); } } + @Override public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) { return get( target ); } + @Override public Class getReturnType() { return method.getReturnType(); } + @Override + public Member getMember() { + return method; + } + + @Override public Method getMethod() { return method; } + @Override public String getMethodName() { return method.getName(); } - public String toString() { + @Override + public String toString() { return "BasicGetter(" + clazz.getName() + '.' + propertyName + ')'; } - + Object readResolve() { return createGetter(clazz, propertyName); } } - public Setter getSetter(Class theClass, String propertyName) - throws PropertyNotFoundException { + @Override + public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException { return createSetter(theClass, propertyName); } - - private static Setter createSetter(Class theClass, String propertyName) - throws PropertyNotFoundException { + + private static Setter createSetter(Class theClass, String propertyName) throws PropertyNotFoundException { BasicSetter result = getSetterOrNull(theClass, propertyName); if (result==null) { - throw new PropertyNotFoundException( - "Could not find a setter for property " + - propertyName + - " in class " + - theClass.getName() + throw new PropertyNotFoundException( + "Could not find a setter for property " + + propertyName + + " in class " + + theClass.getName() ); } return result; @@ -254,7 +260,7 @@ Method method = setterMethod(theClass, propertyName); if (method!=null) { - if ( !ReflectHelper.isPublic(theClass, method) ) method.setAccessible(true); + method.setAccessible(true); return new BasicSetter(theClass, method, propertyName); } else { @@ -271,21 +277,20 @@ } private static Method setterMethod(Class theClass, String propertyName) { - BasicGetter getter = getGetterOrNull(theClass, propertyName); Class returnType = (getter==null) ? null : getter.getReturnType(); Method[] methods = theClass.getDeclaredMethods(); Method potentialSetter = null; - for (int i=0; i * Optional operation (return null) + * + * @return The name of the getter method, or null. */ public String getMethodName(); /** + * Retrieve the getter-method. + *

        * Optional operation (return null) + * + * @return The getter method, or null. */ public Method getMethod(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/property/IndexPropertyAccessor.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/property/IndexPropertyAccessor.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/property/IndexPropertyAccessor.java 17 Aug 2012 14:36:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/property/IndexPropertyAccessor.java 30 Jul 2014 16:16:27 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,41 +20,42 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; - +import java.lang.reflect.Member; import java.lang.reflect.Method; import java.util.Map; import org.hibernate.HibernateException; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; /** * Represents a "back-reference" to the index of a collection. * * @author Gavin King */ public class IndexPropertyAccessor implements PropertyAccessor { - private final String propertyName; private final String entityName; /** * Constructs a new instance of IndexPropertyAccessor. * * @param collectionRole The collection role which this back ref references. + * @param entityName The name of the entity owning the collection. */ public IndexPropertyAccessor(String collectionRole, String entityName) { this.propertyName = collectionRole.substring( entityName.length()+1 ); this.entityName = entityName; } + @Override public Setter getSetter(Class theClass, String propertyName) { return new IndexSetter(); } + @Override public Getter getGetter(Class theClass, String propertyName) { return new IndexGetter(); } @@ -64,53 +65,58 @@ * The Setter implementation for index backrefs. */ public static final class IndexSetter implements Setter { - + @Override public Method getMethod() { return null; } + @Override public String getMethodName() { return null; } - public void set(Object target, Object value) { + @Override + public void set(Object target, Object value, SessionFactoryImplementor factory) { // do nothing... } - - public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException { - // do nothing... - } - } /** * The Getter implementation for index backrefs. */ public class IndexGetter implements Getter { - + @Override public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) throws HibernateException { - if (session==null) { + if ( session == null ) { return BackrefPropertyAccessor.UNKNOWN; } else { - return session.getPersistenceContext() - .getIndexInOwner(entityName, propertyName, target, mergeMap); + return session.getPersistenceContext().getIndexInOwner( entityName, propertyName, target, mergeMap ); } } + @Override public Object get(Object target) { return BackrefPropertyAccessor.UNKNOWN; } + @Override + public Member getMember() { + return null; + } + + @Override public Method getMethod() { return null; } + @Override public String getMethodName() { return null; } + @Override public Class getReturnType() { return Object.class; } Index: 3rdParty_sources/hibernate-core/org/hibernate/property/MapAccessor.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/property/MapAccessor.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/property/MapAccessor.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/property/MapAccessor.java 30 Jul 2014 16:16:26 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,84 +20,95 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; - +import java.lang.reflect.Member; import java.lang.reflect.Method; import java.util.Map; import org.hibernate.HibernateException; import org.hibernate.PropertyNotFoundException; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; /** * @author Gavin King */ public class MapAccessor implements PropertyAccessor { - + @Override public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException { return new MapGetter(propertyName); } + @Override public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException { return new MapSetter(propertyName); } public static final class MapSetter implements Setter { - private String name; MapSetter(String name) { this.name = name; } + @Override public Method getMethod() { return null; } + @Override public String getMethodName() { return null; } + @Override + @SuppressWarnings("unchecked") public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException { - ( (Map) target ).put(name, value); + ( (Map) target ).put( name, value ); } } public static final class MapGetter implements Getter { - private String name; MapGetter(String name) { this.name = name; } + @Override + public Member getMember() { + return null; + } + + @Override public Method getMethod() { return null; } + @Override public String getMethodName() { return null; } + @Override public Object get(Object target) throws HibernateException { return ( (Map) target ).get(name); } + @Override public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) { return get( target ); } + @Override public Class getReturnType() { return Object.class; } - } } Index: 3rdParty_sources/hibernate-core/org/hibernate/property/NoopAccessor.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/property/NoopAccessor.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/property/NoopAccessor.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/property/NoopAccessor.java 30 Jul 2014 16:16:26 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,29 +20,29 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; - +import java.lang.reflect.Member; import java.lang.reflect.Method; import java.util.Map; import org.hibernate.HibernateException; import org.hibernate.PropertyNotFoundException; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; /** * Used to declare properties not represented at the pojo level * * @author Michael Bartmann */ public class NoopAccessor implements PropertyAccessor { - + @Override public Getter getGetter(Class arg0, String arg1) throws PropertyNotFoundException { return new NoopGetter(); } + @Override public Setter getSetter(Class arg0, String arg1) throws PropertyNotFoundException { return new NoopSetter(); } @@ -51,47 +51,58 @@ * A Getter which will always return null. It should not be called anyway. */ private static class NoopGetter implements Getter { - /** - * @return always null + * {@inheritDoc} + *

        + * Here we always return null */ + @Override public Object get(Object target) throws HibernateException { return null; } + @Override public Object getForInsert(Object target, Map map, SessionImplementor arg1) throws HibernateException { return null; } + @Override public Class getReturnType() { return Object.class; } + @Override + public Member getMember() { + return null; + } + + @Override public String getMethodName() { return null; } + @Override public Method getMethod() { return null; } - } /** * A Setter which will just do nothing. */ private static class NoopSetter implements Setter { - - public void set(Object target, Object value, SessionFactoryImplementor arg2) - throws HibernateException { - // do not do anything + @Override + public void set(Object target, Object value, SessionFactoryImplementor arg2) { + // nothing to do } + @Override public String getMethodName() { return null; } + @Override public Method getMethod() { return null; } Index: 3rdParty_sources/hibernate-core/org/hibernate/property/PropertyAccessor.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/property/PropertyAccessor.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/property/PropertyAccessor.java 17 Aug 2012 14:36:35 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/property/PropertyAccessor.java 30 Jul 2014 16:16:27 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,24 +20,38 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; - import org.hibernate.PropertyNotFoundException; /** * Abstracts the notion of a "property". Defines a strategy for accessing the * value of an attribute. + * * @author Gavin King */ public interface PropertyAccessor { /** * Create a "getter" for the named attribute + * + * @param theClass The class on which the property is defined. + * @param propertyName The name of the property. + * + * @return An appropriate getter. + * + * @throws PropertyNotFoundException Indicates a problem interpretting the propertyName */ public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException; + /** * Create a "setter" for the named attribute + * + * @param theClass The class on which the property is defined. + * @param propertyName The name of the property. + * + * @return An appropriate setter + * + * @throws PropertyNotFoundException Indicates a problem interpretting the propertyName */ public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException; } Index: 3rdParty_sources/hibernate-core/org/hibernate/property/PropertyAccessorFactory.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/property/PropertyAccessorFactory.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/property/PropertyAccessorFactory.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/property/PropertyAccessorFactory.java 30 Jul 2014 16:16:27 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,19 +20,17 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; import java.util.Map; -import org.hibernate.MappingException; import org.hibernate.EntityMode; -import org.hibernate.type.Type; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.MappingException; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.internal.util.StringHelper; import org.hibernate.mapping.Property; -import org.hibernate.util.ReflectHelper; -import org.hibernate.util.StringHelper; +import org.hibernate.metamodel.binding.AttributeBinding; /** * A factory for building/retrieving PropertyAccessor instances. @@ -78,15 +76,34 @@ else if ( EntityMode.MAP.equals( mode ) ) { return getDynamicMapPropertyAccessor(); } - else if ( EntityMode.DOM4J.equals( mode ) ) { - //TODO: passing null here, because this method is not really used for DOM4J at the moment - // but it is still a bug, if we don't get rid of this! - return getDom4jPropertyAccessor( property.getAccessorPropertyName( mode ), property.getType(), null ); + else { + throw new MappingException( "Unknown entity mode [" + mode + "]" ); } + } + + /** + * Retrieves a PropertyAccessor instance based on the given property definition and + * entity mode. + * + * @param property The property for which to retrieve an accessor. + * @param mode The mode for the resulting entity. + * @return An appropriate accessor. + * @throws MappingException + */ + public static PropertyAccessor getPropertyAccessor(AttributeBinding property, EntityMode mode) throws MappingException { + //TODO: this is temporary in that the end result will probably not take a Property reference per-se. + if ( null == mode || EntityMode.POJO.equals( mode ) ) { + return getPojoPropertyAccessor( property.getPropertyAccessorName() ); + } + else if ( EntityMode.MAP.equals( mode ) ) { + return getDynamicMapPropertyAccessor(); + } else { throw new MappingException( "Unknown entity mode [" + mode + "]" ); } - } /** + } + + /** * Retreives a PropertyAccessor specific for a PojoRepresentation with the given access strategy. * * @param pojoAccessorStrategy The access strategy. @@ -114,17 +131,10 @@ return MAP_ACCESSOR; } - public static PropertyAccessor getDom4jPropertyAccessor(String nodeName, Type type, SessionFactoryImplementor factory) - throws MappingException { - //TODO: need some caching scheme? really comes down to decision - // regarding amount of state (if any) kept on PropertyAccessors - return new Dom4jAccessor( nodeName, type, factory ); - } - private static PropertyAccessor resolveCustomAccessor(String accessorName) { Class accessorClass; try { - accessorClass = ReflectHelper.classForName(accessorName); + accessorClass = ReflectHelper.classForName( accessorName ); } catch (ClassNotFoundException cnfe) { throw new MappingException("could not find PropertyAccessor class: " + accessorName, cnfe); @@ -152,7 +162,7 @@ if ( "map".equals(type) ) return MAP_ACCESSOR; if ( "embedded".equals(type) ) return EMBEDDED_PROPERTY_ACCESSOR; if ( "noop".equals(type)) return NOOP_ACCESSOR; - + return resolveCustomAccessor(type); } } Index: 3rdParty_sources/hibernate-core/org/hibernate/property/Setter.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/property/Setter.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/property/Setter.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/property/Setter.java 30 Jul 2014 16:16:27 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by + * third-party contributors as indicated by either @author tags or express + * copyright attribution statements applied by the authors. All + * third-party contributions are distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,15 +20,13 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.property; - import java.io.Serializable; import java.lang.reflect.Method; import org.hibernate.HibernateException; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionFactoryImplementor; /** * Sets values to a particular property. Index: 3rdParty_sources/hibernate-core/org/hibernate/property/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/property/package.html,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/property/package.html 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/property/package.html 30 Jul 2014 16:16:27 -0000 1.1.2.1 @@ -1,10 +1,10 @@ Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/HibernatePermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/JACCConfiguration.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/JACCPermissions.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/JACCPreDeleteEventListener.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/JACCPreInsertEventListener.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/JACCPreLoadEventListener.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/JACCPreUpdateEventListener.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/JACCSecurityListener.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/package.html'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/internal/AbstractJaccSecurableEventListener.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/internal/DisabledJaccServiceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/internal/JaccPreDeleteEventListener.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/internal/JaccPreInsertEventListener.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/internal/JaccPreLoadEventListener.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/internal/JaccPreUpdateEventListener.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/internal/JaccSecurityListener.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/internal/StandardJaccServiceImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/spi/GrantedPermission.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/spi/IntegrationException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/spi/JaccIntegrator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/spi/JaccPermissionDeclarations.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/spi/JaccService.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/spi/PermissibleAction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/secure/spi/PermissionCheckEntityInformation.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/CategorizedStatistics.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/stat/CollectionStatistics.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/stat/CollectionStatistics.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/stat/CollectionStatistics.java 17 Aug 2012 14:36:38 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/stat/CollectionStatistics.java 30 Jul 2014 16:16:35 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,52 +20,25 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.stat; +import java.io.Serializable; + /** * Collection related statistics - * + * * @author Gavin King */ -public class CollectionStatistics extends CategorizedStatistics { - - CollectionStatistics(String role) { - super(role); - } - - long loadCount; - long fetchCount; - long updateCount; - long removeCount; - long recreateCount; - - public long getLoadCount() { - return loadCount; - } - public long getFetchCount() { - return fetchCount; - } - public long getRecreateCount() { - return recreateCount; - } - public long getRemoveCount() { - return removeCount; - } - public long getUpdateCount() { - return updateCount; - } +public interface CollectionStatistics extends Serializable { - public String toString() { - return new StringBuffer() - .append("CollectionStatistics") - .append("[loadCount=").append(this.loadCount) - .append(",fetchCount=").append(this.fetchCount) - .append(",recreateCount=").append(this.recreateCount) - .append(",removeCount=").append(this.removeCount) - .append(",updateCount=").append(this.updateCount) - .append(']') - .toString(); - } -} \ No newline at end of file + long getLoadCount(); + + long getFetchCount(); + + long getRecreateCount(); + + long getRemoveCount(); + + long getUpdateCount(); +} Index: 3rdParty_sources/hibernate-core/org/hibernate/stat/EntityStatistics.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/stat/EntityStatistics.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/stat/EntityStatistics.java 17 Aug 2012 14:36:38 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/stat/EntityStatistics.java 30 Jul 2014 16:16:35 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,59 +20,27 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.stat; +import java.io.Serializable; /** * Entity related statistics - * + * * @author Gavin King */ -public class EntityStatistics extends CategorizedStatistics { - - EntityStatistics(String name) { - super(name); - } +public interface EntityStatistics extends Serializable { + long getDeleteCount(); - long loadCount; - long updateCount; - long insertCount; - long deleteCount; - long fetchCount; - long optimisticFailureCount; + long getInsertCount(); - public long getDeleteCount() { - return deleteCount; - } - public long getInsertCount() { - return insertCount; - } - public long getLoadCount() { - return loadCount; - } - public long getUpdateCount() { - return updateCount; - } - public long getFetchCount() { - return fetchCount; - } - public long getOptimisticFailureCount() { - return optimisticFailureCount; - } + long getLoadCount(); - public String toString() { - return new StringBuffer() - .append("EntityStatistics") - .append("[loadCount=").append(this.loadCount) - .append(",updateCount=").append(this.updateCount) - .append(",insertCount=").append(this.insertCount) - .append(",deleteCount=").append(this.deleteCount) - .append(",fetchCount=").append(this.fetchCount) - .append(",optimisticLockFailureCount=").append(this.optimisticFailureCount) - .append(']') - .toString(); - } + long getUpdateCount(); + long getFetchCount(); + + long getOptimisticFailureCount(); + } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/NaturalIdCacheStatistics.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/stat/QueryStatistics.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/stat/QueryStatistics.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/stat/QueryStatistics.java 17 Aug 2012 14:36:38 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/stat/QueryStatistics.java 30 Jul 2014 16:16:35 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,115 +20,32 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.stat; +import java.io.Serializable; + /** * Query statistics (HQL and SQL) - * + *

        * Note that for a cached query, the cache miss is equals to the db count - * + * * @author Gavin King */ -public class QueryStatistics extends CategorizedStatistics { +public interface QueryStatistics extends Serializable { + long getExecutionCount(); - /*package*/ long cacheHitCount; - /*package*/ long cacheMissCount; - /*package*/ long cachePutCount; - private long executionCount; - private long executionRowCount; - private long executionAvgTime; - private long executionMaxTime; - private long executionMinTime = Long.MAX_VALUE; + long getCacheHitCount(); - QueryStatistics(String query) { - super(query); - } + long getCachePutCount(); - /** - * queries executed to the DB - */ - public long getExecutionCount() { - return executionCount; - } - - /** - * Queries retrieved successfully from the cache - */ - public long getCacheHitCount() { - return cacheHitCount; - } - - public long getCachePutCount() { - return cachePutCount; - } - - public long getCacheMissCount() { - return cacheMissCount; - } - - /** - * Number of lines returned by all the executions of this query (from DB) - * For now, {@link org.hibernate.Query#iterate()} - * and {@link org.hibernate.Query#scroll()()} do not fill this statistic - * - * @return The number of rows cumulatively returned by the given query; iterate - * and scroll queries do not effect this total as their number of returned rows - * is not known at execution time. - */ - public long getExecutionRowCount() { - return executionRowCount; - } + long getCacheMissCount(); - /** - * average time in ms taken by the excution of this query onto the DB - */ - public long getExecutionAvgTime() { - return executionAvgTime; - } + long getExecutionRowCount(); - /** - * max time in ms taken by the excution of this query onto the DB - */ - public long getExecutionMaxTime() { - return executionMaxTime; - } - - /** - * min time in ms taken by the excution of this query onto the DB - */ - public long getExecutionMinTime() { - return executionMinTime; - } - - /** - * add statistics report of a DB query - * - * @param rows rows count returned - * @param time time taken - */ - void executed(long rows, long time) { - if (time < executionMinTime) executionMinTime = time; - if (time > executionMaxTime) executionMaxTime = time; - executionAvgTime = ( executionAvgTime * executionCount + time ) / ( executionCount + 1 ); - executionCount++; - executionRowCount += rows; - } + long getExecutionAvgTime(); - public String toString() { - return new StringBuffer() - .append( "QueryStatistics" ) - .append( "[cacheHitCount=" ).append( this.cacheHitCount ) - .append( ",cacheMissCount=" ).append( this.cacheMissCount ) - .append( ",cachePutCount=" ).append( this.cachePutCount ) - .append( ",executionCount=" ).append( this.executionCount ) - .append( ",executionRowCount=" ).append( this.executionRowCount ) - .append( ",executionAvgTime=" ).append( this.executionAvgTime ) - .append( ",executionMaxTime=" ).append( this.executionMaxTime ) - .append( ",executionMinTime=" ).append( this.executionMinTime ) - .append( ']' ) - .toString(); - } + long getExecutionMaxTime(); + long getExecutionMinTime(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/stat/SecondLevelCacheStatistics.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/stat/SecondLevelCacheStatistics.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/stat/SecondLevelCacheStatistics.java 17 Aug 2012 14:36:38 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/stat/SecondLevelCacheStatistics.java 30 Jul 2014 16:16:35 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,75 +20,30 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.stat; -import java.util.HashMap; -import java.util.Iterator; +import java.io.Serializable; import java.util.Map; -import org.hibernate.cache.CacheKey; -import org.hibernate.cache.Region; - /** * Second level cache statistics of a specific region - * + * * @author Gavin King */ -public class SecondLevelCacheStatistics extends CategorizedStatistics { +public interface SecondLevelCacheStatistics extends Serializable { - private transient Region region; - long hitCount; - long missCount; - long putCount; + long getHitCount(); - SecondLevelCacheStatistics(Region region) { - super( region.getName() ); - this.region = region; - } - public long getHitCount() { - return hitCount; - } - public long getMissCount() { - return missCount; - } - public long getPutCount() { - return putCount; - } - public long getElementCountInMemory() { - return region.getElementCountInMemory(); - } - public long getElementCountOnDisk() { - return region.getElementCountOnDisk(); - } - public long getSizeInMemory() { - return region.getSizeInMemory(); - } - - public Map getEntries() { - Map map = new HashMap(); - Iterator iter = region.toMap().entrySet().iterator(); - while ( iter.hasNext() ) { - Map.Entry me = (Map.Entry) iter.next(); - map.put( ( (CacheKey) me.getKey() ).getKey(), me.getValue() ); - } - return map; - } + long getMissCount(); - public String toString() { - StringBuffer buf = new StringBuffer() - .append("SecondLevelCacheStatistics") - .append("[hitCount=").append(this.hitCount) - .append(",missCount=").append(this.missCount) - .append(",putCount=").append(this.putCount); - //not sure if this would ever be null but wanted to be careful - if ( region != null ) { - buf.append(",elementCountInMemory=").append(this.getElementCountInMemory()) - .append(",elementCountOnDisk=").append(this.getElementCountOnDisk()) - .append(",sizeInMemory=").append(this.getSizeInMemory()); - } - buf.append(']'); - return buf.toString(); - } + long getPutCount(); + + long getElementCountInMemory(); + + long getElementCountOnDisk(); + + long getSizeInMemory(); + + Map getEntries(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/stat/SessionStatistics.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/stat/SessionStatistics.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/stat/SessionStatistics.java 17 Aug 2012 14:36:38 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/stat/SessionStatistics.java 30 Jul 2014 16:16:35 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.stat; @@ -32,7 +31,6 @@ * @author Gavin King */ public interface SessionStatistics { - /** * Get the number of entity instances associated with the session */ @@ -44,12 +42,12 @@ /** * Get the set of all EntityKeys - * @see org.hibernate.engine.EntityKey + * @see org.hibernate.engine.spi.EntityKey */ public Set getEntityKeys(); /** * Get the set of all CollectionKeys - * @see org.hibernate.engine.CollectionKey + * @see org.hibernate.engine.spi.CollectionKey */ public Set getCollectionKeys(); Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/SessionStatisticsImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/stat/Statistics.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/stat/Statistics.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/stat/Statistics.java 17 Aug 2012 14:36:38 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/stat/Statistics.java 30 Jul 2014 16:16:35 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,15 +20,12 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.stat; - /** - * Statistics for a particular SessionFactory. - * Beware of milliseconds metrics, they are depdendent of the JVM precision: - * you may then encounter a 10 ms approximation dending on you OS platform. + * Exposes statistics for a particular {@link org.hibernate.SessionFactory}. Beware of milliseconds metrics, they + * are dependent of the JVM precision: you may then encounter a 10 ms approximation depending on you OS platform. * Please refer to the JVM documentation for more information. * * @author Emmanuel Bernard @@ -63,6 +60,14 @@ public SecondLevelCacheStatistics getSecondLevelCacheStatistics(String regionName); /** + * Natural id cache statistics per region + * + * @param regionName region name + * @return NaturalIdCacheStatistics + */ + public NaturalIdCacheStatistics getNaturalIdCacheStatistics(String regionName); + + /** * Query statistics from query string (HQL or SQL) * * @param queryString query string @@ -127,6 +132,42 @@ */ public long getQueryCachePutCount(); /** + * Get the global number of naturalId queries executed against the database + */ + public long getNaturalIdQueryExecutionCount(); + /** + * Get the global maximum query time for naturalId queries executed against the database + */ + public long getNaturalIdQueryExecutionMaxTime(); + /** + * Get the region for the maximum naturalId query time + */ + public String getNaturalIdQueryExecutionMaxTimeRegion(); + /** + * Get the global number of cached naturalId lookups successfully retrieved from cache + */ + public long getNaturalIdCacheHitCount(); + /** + * Get the global number of cached naturalId lookups *not* found in cache + */ + public long getNaturalIdCacheMissCount(); + /** + * Get the global number of cacheable naturalId lookups put in cache + */ + public long getNaturalIdCachePutCount(); + /** + * Get the global number of timestamps successfully retrieved from cache + */ + public long getUpdateTimestampsCacheHitCount(); + /** + * Get the global number of tables for which no update timestamps was *not* found in cache + */ + public long getUpdateTimestampsCacheMissCount(); + /** + * Get the global number of timestamps put in cache + */ + public long getUpdateTimestampsCachePutCount(); + /** * Get the global number of flush executed by sessions (either implicit or explicit) */ public long getFlushCount(); @@ -231,4 +272,4 @@ * that occurred */ public long getOptimisticFailureCount(); -} \ No newline at end of file +} Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/StatisticsImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/StatisticsImplementor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/stat/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/stat/package.html,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/stat/package.html 17 Aug 2012 14:36:38 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/stat/package.html 30 Jul 2014 16:16:35 -0000 1.1.2.1 @@ -27,8 +27,7 @@

        - This package exposes statistics about a running - Hibernate instance to the application. + This package exposes statistics about a running Hibernate instance to the application.

        Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/internal/CategorizedStatistics.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/internal/ConcurrentCollectionStatisticsImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/internal/ConcurrentEntityStatisticsImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/internal/ConcurrentNaturalIdCacheStatisticsImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/internal/ConcurrentQueryStatisticsImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/internal/ConcurrentSecondLevelCacheStatisticsImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/internal/ConcurrentStatisticsImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/internal/SessionStatisticsImpl.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/internal/StatisticsInitiator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/spi/StatisticsFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/stat/spi/StatisticsImplementor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/tool/enhance/EnhancementTask.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ColumnMetadata.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ColumnMetadata.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ColumnMetadata.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ColumnMetadata.java 30 Jul 2014 16:15:44 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.tool.hbm2ddl; - import java.sql.ResultSet; import java.sql.SQLException; import java.util.StringTokenizer; Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ConnectionHelper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ConnectionHelper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ConnectionHelper.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ConnectionHelper.java 30 Jul 2014 16:15:44 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.tool.hbm2ddl; - import java.sql.Connection; import java.sql.SQLException; @@ -33,7 +32,7 @@ * * @author Steve Ebersole */ -interface ConnectionHelper { +public interface ConnectionHelper { /** * Prepare the helper for use. * Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/DatabaseExporter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/DatabaseMetadata.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/DatabaseMetadata.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/DatabaseMetadata.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/DatabaseMetadata.java 30 Jul 2014 16:15:43 -0000 1.1.2.1 @@ -34,43 +34,71 @@ import java.util.Map; import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.HibernateException; -import org.hibernate.exception.JDBCExceptionHelper; -import org.hibernate.exception.SQLExceptionConverter; -import org.hibernate.mapping.Table; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.Configuration; import org.hibernate.dialect.Dialect; -import org.hibernate.util.StringHelper; +import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; +import org.hibernate.exception.spi.SQLExceptionConverter; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.mapping.Table; +import org.jboss.logging.Logger; + /** * JDBC database metadata * @author Christoph Sturm, Teodor Danciu + * @author Brett Meyer */ public class DatabaseMetadata { - - private static final Logger log = LoggerFactory.getLogger(DatabaseMetadata.class); - + + private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, DatabaseMetaData.class.getName()); + private final Map tables = new HashMap(); private final Set sequences = new HashSet(); private final boolean extras; private DatabaseMetaData meta; private SQLExceptionConverter sqlExceptionConverter; + private final String[] types; + /** + * @deprecated Use {@link #DatabaseMetadata(Connection, Dialect, Configuration)} instead + */ + @Deprecated public DatabaseMetadata(Connection connection, Dialect dialect) throws SQLException { - this(connection, dialect, true); + this(connection, dialect, null, true); } + /** + * @deprecated Use {@link #DatabaseMetadata(Connection, Dialect, Configuration, boolean)} instead + */ + @Deprecated public DatabaseMetadata(Connection connection, Dialect dialect, boolean extras) throws SQLException { + this(connection, dialect, null, extras); + } + + public DatabaseMetadata(Connection connection, Dialect dialect, Configuration config) throws SQLException { + this(connection, dialect, config, true); + } + + public DatabaseMetadata(Connection connection, Dialect dialect, Configuration config, boolean extras) + throws SQLException { sqlExceptionConverter = dialect.buildSQLExceptionConverter(); meta = connection.getMetaData(); this.extras = extras; - initSequences(connection, dialect); + initSequences( connection, dialect ); + if ( config != null + && ConfigurationHelper.getBoolean( AvailableSettings.ENABLE_SYNONYMS, config.getProperties(), false ) ) { + types = new String[] { "TABLE", "VIEW", "SYNONYM" }; + } + else { + types = new String[] { "TABLE", "VIEW" }; + } } - private static final String[] TYPES = {"TABLE", "VIEW"}; - public TableMetadata getTableMetadata(String name, String schema, String catalog, boolean isQuoted) throws HibernateException { Object identifier = identifier(catalog, schema, name); @@ -79,34 +107,34 @@ return table; } else { - + try { ResultSet rs = null; try { if ( (isQuoted && meta.storesMixedCaseQuotedIdentifiers())) { - rs = meta.getTables(catalog, schema, name, TYPES); - } else if ( (isQuoted && meta.storesUpperCaseQuotedIdentifiers()) + rs = meta.getTables(catalog, schema, name, types); + } else if ( (isQuoted && meta.storesUpperCaseQuotedIdentifiers()) || (!isQuoted && meta.storesUpperCaseIdentifiers() )) { - rs = meta.getTables( - StringHelper.toUpperCase(catalog), - StringHelper.toUpperCase(schema), - StringHelper.toUpperCase(name), - TYPES + rs = meta.getTables( + StringHelper.toUpperCase(catalog), + StringHelper.toUpperCase(schema), + StringHelper.toUpperCase(name), + types ); } else if ( (isQuoted && meta.storesLowerCaseQuotedIdentifiers()) || (!isQuoted && meta.storesLowerCaseIdentifiers() )) { rs = meta.getTables( - StringHelper.toLowerCase(catalog), + StringHelper.toLowerCase( catalog ), StringHelper.toLowerCase(schema), StringHelper.toLowerCase(name), - TYPES + types ); } else { - rs = meta.getTables(catalog, schema, name, TYPES); + rs = meta.getTables(catalog, schema, name, types); } - + while ( rs.next() ) { String tableName = rs.getString("TABLE_NAME"); if ( name.equalsIgnoreCase(tableName) ) { @@ -115,21 +143,18 @@ return table; } } - - log.info("table not found: " + name); + + LOG.tableNotFound( name ); return null; } finally { - if (rs!=null) rs.close(); + rs.close(); } } - catch (SQLException sqle) { - throw JDBCExceptionHelper.convert( - sqlExceptionConverter, - sqle, - "could not get table metadata: " + name - ); + catch (SQLException sqlException) { + throw new SqlExceptionHelper( sqlExceptionConverter ) + .convert( sqlException, "could not get table metadata: " + name ); } } @@ -143,30 +168,30 @@ if ( dialect.supportsSequences() ) { String sql = dialect.getQuerySequencesString(); if (sql!=null) { - + Statement statement = null; ResultSet rs = null; try { statement = connection.createStatement(); rs = statement.executeQuery(sql); - + while ( rs.next() ) { - sequences.add( rs.getString(1).toLowerCase().trim() ); + sequences.add( StringHelper.toLowerCase(rs.getString(1)).trim() ); } } finally { - if (rs!=null) rs.close(); - if (statement!=null) statement.close(); + rs.close(); + statement.close(); } - + } } } public boolean isSequence(Object key) { if (key instanceof String){ String[] strings = StringHelper.split(".", (String) key); - return sequences.contains( strings[strings.length-1].toLowerCase()); + return sequences.contains( StringHelper.toLowerCase(strings[strings.length-1])); } return false; } @@ -192,13 +217,9 @@ } return false; } - - public String toString() { + + @Override + public String toString() { return "DatabaseMetadata" + tables.keySet().toString() + sequences.toString(); } } - - - - - Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/Exporter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/FileExporter.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ForeignKeyMetadata.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ForeignKeyMetadata.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ForeignKeyMetadata.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ForeignKeyMetadata.java 30 Jul 2014 16:15:43 -0000 1.1.2.1 @@ -20,39 +20,73 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.tool.hbm2ddl; - import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.mapping.Column; +import org.hibernate.mapping.ForeignKey; + /** * JDBC foreign key metadata + * * @author Christoph Sturm */ public class ForeignKeyMetadata { private final String name; - private final List columns = new ArrayList(); + private final String refTable; + private final Map references = new HashMap(); ForeignKeyMetadata(ResultSet rs) throws SQLException { name = rs.getString("FK_NAME"); + refTable = rs.getString("PKTABLE_NAME"); } public String getName() { return name; } - void addColumn(ColumnMetadata column) { - if (column != null) columns.add(column); + public String getReferencedTableName() { + return refTable; } - public ColumnMetadata[] getColumns() { - return (ColumnMetadata[]) columns.toArray(new ColumnMetadata[0]); + void addReference(ResultSet rs) throws SQLException { + references.put( StringHelper.toLowerCase(rs.getString("FKCOLUMN_NAME")), rs.getString("PKCOLUMN_NAME") ); } + private boolean hasReference(Column column, Column ref) { + String refName = (String) references.get(StringHelper.toLowerCase(column.getName())); + return ref.getName().equalsIgnoreCase(refName); + } + + public boolean matches(ForeignKey fk) { + if ( refTable.equalsIgnoreCase( fk.getReferencedTable().getName() ) ) { + if ( fk.getColumnSpan() == references.size() ) { + List fkRefs; + if ( fk.isReferenceToPrimaryKey() ) { + fkRefs = fk.getReferencedTable().getPrimaryKey().getColumns(); + } + else { + fkRefs = fk.getReferencedColumns(); + } + for ( int i = 0; i < fk.getColumnSpan(); i++ ) { + Column column = fk.getColumn( i ); + Column ref = ( Column ) fkRefs.get( i ); + if ( !hasReference( column, ref ) ) { + return false; + } + } + return true; + } + } + return false; + } + public String toString() { return "ForeignKeyMetadata(" + name + ')'; } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ImportScriptException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ImportSqlCommandExtractor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ImportSqlCommandExtractorInitiator.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/IndexMetadata.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/IndexMetadata.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/IndexMetadata.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/IndexMetadata.java 30 Jul 2014 16:15:44 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.tool.hbm2ddl; - import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ManagedProviderConnectionHelper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ManagedProviderConnectionHelper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ManagedProviderConnectionHelper.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ManagedProviderConnectionHelper.java 30 Jul 2014 16:15:43 -0000 1.1.2.1 @@ -24,14 +24,17 @@ */ package org.hibernate.tool.hbm2ddl; -import org.hibernate.connection.ConnectionProvider; -import org.hibernate.connection.ConnectionProviderFactory; -import org.hibernate.util.JDBCExceptionReporter; - -import java.util.Properties; import java.sql.Connection; import java.sql.SQLException; +import java.util.Properties; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; +import org.hibernate.cfg.Environment; +import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; +import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; +import org.hibernate.internal.util.config.ConfigurationHelper; + /** * A {@link ConnectionHelper} implementation based on an internally * built and managed {@link ConnectionProvider}. @@ -40,36 +43,65 @@ */ class ManagedProviderConnectionHelper implements ConnectionHelper { private Properties cfgProperties; - private ConnectionProvider connectionProvider; + private StandardServiceRegistryImpl serviceRegistry; private Connection connection; public ManagedProviderConnectionHelper(Properties cfgProperties) { this.cfgProperties = cfgProperties; } public void prepare(boolean needsAutoCommit) throws SQLException { - connectionProvider = ConnectionProviderFactory.newConnectionProvider( cfgProperties ); - connection = connectionProvider.getConnection(); - if ( needsAutoCommit && !connection.getAutoCommit() ) { + serviceRegistry = createServiceRegistry( cfgProperties ); + connection = serviceRegistry.getService( ConnectionProvider.class ).getConnection(); + if ( needsAutoCommit && ! connection.getAutoCommit() ) { connection.commit(); connection.setAutoCommit( true ); } } + private static StandardServiceRegistryImpl createServiceRegistry(Properties properties) { + Environment.verifyProperties( properties ); + ConfigurationHelper.resolvePlaceHolders( properties ); + return (StandardServiceRegistryImpl) new StandardServiceRegistryBuilder().applySettings( properties ).build(); + } + public Connection getConnection() throws SQLException { return connection; } public void release() throws SQLException { + try { + releaseConnection(); + } + finally { + releaseServiceRegistry(); + } + } + + private void releaseConnection() throws SQLException { if ( connection != null ) { try { - JDBCExceptionReporter.logAndClearWarnings( connection ); - connectionProvider.closeConnection( connection ); + new SqlExceptionHelper().logAndClearWarnings( connection ); } finally { - connectionProvider.close(); + try { + serviceRegistry.getService( ConnectionProvider.class ).closeConnection( connection ); + } + finally { + connection = null; + } } } - connection = null; } + + private void releaseServiceRegistry() { + if ( serviceRegistry != null ) { + try { + serviceRegistry.destroy(); + } + finally { + serviceRegistry = null; + } + } + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/MultipleLinesSqlCommandExtractor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaExport.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaExport.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaExport.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaExport.java 30 Jul 2014 16:15:43 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,14 +20,12 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.tool.hbm2ddl; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; -import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -41,111 +39,194 @@ import java.util.List; import java.util.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import org.hibernate.HibernateException; -import org.hibernate.JDBCException; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; +import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.cfg.NamingStrategy; -import org.hibernate.cfg.Settings; import org.hibernate.dialect.Dialect; -import org.hibernate.jdbc.util.FormatStyle; -import org.hibernate.jdbc.util.Formatter; -import org.hibernate.jdbc.util.SQLStatementLogger; -import org.hibernate.util.ConfigHelper; -import org.hibernate.util.JDBCExceptionReporter; -import org.hibernate.util.PropertiesHelper; -import org.hibernate.util.ReflectHelper; +import org.hibernate.engine.config.spi.ConfigurationService; +import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; +import org.hibernate.engine.jdbc.internal.FormatStyle; +import org.hibernate.engine.jdbc.internal.Formatter; +import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; +import org.hibernate.engine.jdbc.spi.SqlStatementLogger; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.ConfigHelper; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.metamodel.source.MetadataImplementor; +import org.hibernate.service.ServiceRegistry; +import org.jboss.logging.Logger; + /** * Commandline tool to export table schema to the database. This class may also be called from inside an application. * * @author Daniel Bradby * @author Gavin King + * @author Steve Ebersole */ public class SchemaExport { + private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, SchemaExport.class.getName()); + private static final String DEFAULT_IMPORT_FILE = "/import.sql"; - private static final Logger log = LoggerFactory.getLogger( SchemaExport.class ); + public static enum Type { + CREATE, + DROP, + NONE, + BOTH; - private ConnectionHelper connectionHelper; - private String[] dropSQL; - private String[] createSQL; - private String outputFile = null; - private String importFile = "/import.sql"; - private Dialect dialect; - private String delimiter; - private final List exceptions = new ArrayList(); - private boolean haltOnError = false; + public boolean doCreate() { + return this == BOTH || this == CREATE; + } + + public boolean doDrop() { + return this == BOTH || this == DROP; + } + } + + private final ConnectionHelper connectionHelper; + private final SqlStatementLogger sqlStatementLogger; + private final SqlExceptionHelper sqlExceptionHelper; + private final String[] dropSQL; + private final String[] createSQL; + private final String importFiles; + + private final List exceptions = new ArrayList(); + private Formatter formatter; - private SQLStatementLogger sqlStatementLogger; + private ImportSqlCommandExtractor importSqlCommandExtractor = ImportSqlCommandExtractorInitiator.DEFAULT_EXTRACTOR; - /** - * Create a schema exporter for the given Configuration - * - * @param cfg The configuration from which to build a schema export. - * @throws HibernateException Indicates problem preparing for schema export. - */ - public SchemaExport(Configuration cfg) throws HibernateException { - this( cfg, cfg.getProperties() ); + private String outputFile; + private String delimiter; + private boolean haltOnError; + + public SchemaExport(ServiceRegistry serviceRegistry, Configuration configuration) { + this.connectionHelper = new SuppliedConnectionProviderConnectionHelper( + serviceRegistry.getService( ConnectionProvider.class ) + ); + this.sqlStatementLogger = serviceRegistry.getService( JdbcServices.class ).getSqlStatementLogger(); + this.formatter = ( sqlStatementLogger.isFormat() ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter(); + this.sqlExceptionHelper = serviceRegistry.getService( JdbcServices.class ).getSqlExceptionHelper(); + + this.importFiles = ConfigurationHelper.getString( + AvailableSettings.HBM2DDL_IMPORT_FILES, + configuration.getProperties(), + DEFAULT_IMPORT_FILE + ); + + final Dialect dialect = serviceRegistry.getService( JdbcServices.class ).getDialect(); + this.dropSQL = configuration.generateDropSchemaScript( dialect ); + this.createSQL = configuration.generateSchemaCreationScript( dialect ); } + public SchemaExport(MetadataImplementor metadata) { + ServiceRegistry serviceRegistry = metadata.getServiceRegistry(); + this.connectionHelper = new SuppliedConnectionProviderConnectionHelper( + serviceRegistry.getService( ConnectionProvider.class ) + ); + JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class ); + this.sqlStatementLogger = jdbcServices.getSqlStatementLogger(); + this.formatter = ( sqlStatementLogger.isFormat() ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter(); + this.sqlExceptionHelper = jdbcServices.getSqlExceptionHelper(); + + this.importFiles = ConfigurationHelper.getString( + AvailableSettings.HBM2DDL_IMPORT_FILES, + serviceRegistry.getService( ConfigurationService.class ).getSettings(), + DEFAULT_IMPORT_FILE + ); + + final Dialect dialect = jdbcServices.getDialect(); + this.dropSQL = metadata.getDatabase().generateDropSchemaScript( dialect ); + this.createSQL = metadata.getDatabase().generateSchemaCreationScript( dialect ); + } + /** - * Create a schema exporter for the given Configuration and given settings + * Create a schema exporter for the given Configuration * - * @param cfg The configuration from which to build a schema export. - * @param settings The 'parsed' settings. + * @param configuration The configuration from which to build a schema export. * @throws HibernateException Indicates problem preparing for schema export. */ - public SchemaExport(Configuration cfg, Settings settings) throws HibernateException { - dialect = settings.getDialect(); - connectionHelper = new SuppliedConnectionProviderConnectionHelper( settings.getConnectionProvider() ); - dropSQL = cfg.generateDropSchemaScript( dialect ); - createSQL = cfg.generateSchemaCreationScript( dialect ); - sqlStatementLogger = settings.getSqlStatementLogger(); - formatter = ( sqlStatementLogger.isFormatSql() ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter(); + public SchemaExport(Configuration configuration) { + this( configuration, configuration.getProperties() ); } /** * Create a schema exporter for the given Configuration, with the given * database connection properties. * - * @param cfg The configuration from which to build a schema export. + * @param configuration The configuration from which to build a schema export. * @param properties The properties from which to configure connectivity etc. * @throws HibernateException Indicates problem preparing for schema export. * * @deprecated properties may be specified via the Configuration object */ - public SchemaExport(Configuration cfg, Properties properties) throws HibernateException { - dialect = Dialect.getDialect( properties ); + @Deprecated + public SchemaExport(Configuration configuration, Properties properties) throws HibernateException { + final Dialect dialect = Dialect.getDialect( properties ); Properties props = new Properties(); props.putAll( dialect.getDefaultProperties() ); props.putAll( properties ); + this.connectionHelper = new ManagedProviderConnectionHelper( props ); - connectionHelper = new ManagedProviderConnectionHelper( props ); - dropSQL = cfg.generateDropSchemaScript( dialect ); - createSQL = cfg.generateSchemaCreationScript( dialect ); + this.sqlStatementLogger = new SqlStatementLogger( false, true ); + this.formatter = FormatStyle.DDL.getFormatter(); + this.sqlExceptionHelper = new SqlExceptionHelper(); - formatter = ( PropertiesHelper.getBoolean( Environment.FORMAT_SQL, props ) ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter(); + this.importFiles = ConfigurationHelper.getString( + AvailableSettings.HBM2DDL_IMPORT_FILES, + properties, + DEFAULT_IMPORT_FILE + ); + + this.dropSQL = configuration.generateDropSchemaScript( dialect ); + this.createSQL = configuration.generateSchemaCreationScript( dialect ); } /** * Create a schema exporter for the given Configuration, using the supplied connection for connectivity. * - * @param cfg The configuration to use. + * @param configuration The configuration to use. * @param connection The JDBC connection to use. * @throws HibernateException Indicates problem preparing for schema export. */ - public SchemaExport(Configuration cfg, Connection connection) throws HibernateException { + public SchemaExport(Configuration configuration, Connection connection) throws HibernateException { this.connectionHelper = new SuppliedConnectionHelper( connection ); - dialect = Dialect.getDialect( cfg.getProperties() ); - dropSQL = cfg.generateDropSchemaScript( dialect ); - createSQL = cfg.generateSchemaCreationScript( dialect ); - formatter = ( PropertiesHelper.getBoolean( Environment.FORMAT_SQL, cfg.getProperties() ) ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter(); + + this.sqlStatementLogger = new SqlStatementLogger( false, true ); + this.formatter = FormatStyle.DDL.getFormatter(); + this.sqlExceptionHelper = new SqlExceptionHelper(); + + this.importFiles = ConfigurationHelper.getString( + AvailableSettings.HBM2DDL_IMPORT_FILES, + configuration.getProperties(), + DEFAULT_IMPORT_FILE + ); + + final Dialect dialect = Dialect.getDialect( configuration.getProperties() ); + this.dropSQL = configuration.generateDropSchemaScript( dialect ); + this.createSQL = configuration.generateSchemaCreationScript( dialect ); } + public SchemaExport( + ConnectionHelper connectionHelper, + String[] dropSql, + String[] createSql) { + this.connectionHelper = connectionHelper; + this.dropSQL = dropSql; + this.createSQL = createSql; + this.importFiles = ""; + this.sqlStatementLogger = new SqlStatementLogger( false, true ); + this.sqlExceptionHelper = new SqlExceptionHelper(); + this.formatter = FormatStyle.DDL.getFormatter(); + } + /** * For generating a export script file, this is the file which will be written. * @@ -158,17 +239,6 @@ } /** - * An import file, containing raw SQL statements to be executed. - * - * @param filename The import file name. - * @return this - */ - public SchemaExport setImportFile(String filename) { - importFile = filename; - return this; - } - - /** * Set the end of statement delimiter * * @param delimiter The delimiter @@ -191,6 +261,17 @@ } /** + * Set import.sql command extractor. By default {@link SingleLineSqlCommandExtractor} is used. + * + * @param importSqlCommandExtractor import.sql command extractor. + * @return this + */ + public SchemaExport setImportSqlCommandExtractor(ImportSqlCommandExtractor importSqlCommandExtractor) { + this.importSqlCommandExtractor = importSqlCommandExtractor; + return this; + } + + /** * Should we stop once an error occurs? * * @param haltOnError True if export should stop after error. @@ -202,179 +283,211 @@ } /** - * Run the schema creation script. + * Run the schema creation script; drop script is automatically + * executed before running the creation script. * * @param script print the DDL to the console * @param export export the script to the database */ public void create(boolean script, boolean export) { - execute( script, export, false, false ); + create( Target.interpret( script, export ) ); } /** + * Run the schema creation script; drop script is automatically + * executed before running the creation script. + * + * @param output the target of the script. + */ + public void create(Target output) { + // need to drop tables before creating so need to specify Type.BOTH + execute( output, Type.BOTH ); + } + + /** * Run the drop schema script. * * @param script print the DDL to the console * @param export export the script to the database */ public void drop(boolean script, boolean export) { - execute( script, export, true, false ); + drop( Target.interpret( script, export ) ); } + public void drop(Target output) { + execute( output, Type.DROP ); + } + public void execute(boolean script, boolean export, boolean justDrop, boolean justCreate) { + execute( Target.interpret( script, export ), interpretType( justDrop, justCreate ) ); + } - log.info( "Running hbm2ddl schema export" ); + private Type interpretType(boolean justDrop, boolean justCreate) { + if ( justDrop ) { + return Type.DROP; + } + else if ( justCreate ) { + return Type.CREATE; + } + else { + return Type.BOTH; + } + } - Connection connection = null; - Writer outputFileWriter = null; - Reader importFileReader = null; - Statement statement = null; - + public void execute(Target output, Type type) { + if ( (outputFile == null && output == Target.NONE) || type == SchemaExport.Type.NONE ) { + return; + } exceptions.clear(); - try { + LOG.runningHbm2ddlSchemaExport(); + final List importFileReaders = new ArrayList(); + for ( String currentFile : importFiles.split(",") ) { try { - InputStream stream = ConfigHelper.getResourceAsStream( importFile ); - importFileReader = new InputStreamReader( stream ); + final String resourceName = currentFile.trim(); + InputStream stream = ConfigHelper.getResourceAsStream( resourceName ); + importFileReaders.add( new NamedReader( resourceName, stream ) ); } catch ( HibernateException e ) { - log.debug( "import file not found: " + importFile ); + LOG.debugf("Import file not found: %s", currentFile); } + } + final List exporters = new ArrayList(); + try { + // prepare exporters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + if ( output.doScript() ) { + exporters.add( new ScriptExporter() ); + } if ( outputFile != null ) { - log.info( "writing generated schema to file: " + outputFile ); - outputFileWriter = new FileWriter( outputFile ); + exporters.add( new FileExporter( outputFile ) ); } - - if ( export ) { - log.info( "exporting generated schema to database" ); - connectionHelper.prepare( true ); - connection = connectionHelper.getConnection(); - statement = connection.createStatement(); + if ( output.doExport() ) { + exporters.add( new DatabaseExporter( connectionHelper, sqlExceptionHelper ) ); } - if ( !justCreate ) { - drop( script, export, outputFileWriter, statement ); + // perform exporters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + if ( type.doDrop() ) { + perform( dropSQL, exporters ); } - - if ( !justDrop ) { - create( script, export, outputFileWriter, statement ); - if ( export && importFileReader != null ) { - importScript( importFileReader, statement ); + if ( type.doCreate() ) { + perform( createSQL, exporters ); + if ( ! importFileReaders.isEmpty() ) { + for ( NamedReader namedReader : importFileReaders ) { + importScript( namedReader, exporters ); + } } } - - log.info( "schema export complete" ); - } - - catch ( Exception e ) { + catch (Exception e) { exceptions.add( e ); - log.error( "schema export unsuccessful", e ); + LOG.schemaExportUnsuccessful( e ); } - finally { - - try { - if ( statement != null ) { - statement.close(); + // release exporters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + for ( Exporter exporter : exporters ) { + try { + exporter.release(); } - if ( connection != null ) { - connectionHelper.release(); + catch (Exception ignore) { } } - catch ( Exception e ) { - exceptions.add( e ); - log.error( "Could not close connection", e ); - } - try { - if ( outputFileWriter != null ) { - outputFileWriter.close(); + // release the named readers from import scripts + for ( NamedReader namedReader : importFileReaders ) { + try { + namedReader.getReader().close(); } - if ( importFileReader != null ) { - importFileReader.close(); + catch (Exception ignore) { } } - catch ( IOException ioe ) { - exceptions.add( ioe ); - log.error( "Error closing output file: " + outputFile, ioe ); - } - + LOG.schemaExportComplete(); } } - private void importScript(Reader importFileReader, Statement statement) - throws IOException { - log.info( "Executing import script: " + importFile ); - BufferedReader reader = new BufferedReader( importFileReader ); - long lineNo = 0; - for ( String sql = reader.readLine(); sql != null; sql = reader.readLine() ) { - try { - lineNo++; - String trimmedSql = sql.trim(); - if ( trimmedSql.length() == 0 || - trimmedSql.startsWith( "--" ) || - trimmedSql.startsWith( "//" ) || - trimmedSql.startsWith( "/*" ) ) { - continue; + private void perform(String[] sqlCommands, List exporters) { + for ( String sqlCommand : sqlCommands ) { + String formatted = formatter.format( sqlCommand ); + if ( delimiter != null ) { + formatted += delimiter; + } + sqlStatementLogger.logStatement( sqlCommand, formatter ); + for ( Exporter exporter : exporters ) { + try { + exporter.export( formatted ); } - else { - if ( trimmedSql.endsWith( ";" ) ) { - trimmedSql = trimmedSql.substring( 0, trimmedSql.length() - 1 ); + catch (Exception e) { + if ( haltOnError ) { + throw new HibernateException( "Error during DDL export", e ); } - log.debug( trimmedSql ); - statement.execute( trimmedSql ); + exceptions.add( e ); + LOG.unsuccessfulCreate( sqlCommand ); + LOG.error( e.getMessage() ); } } - catch ( SQLException e ) { - throw new JDBCException( "Error during import script execution at line " + lineNo, e ); - } } } - private void create(boolean script, boolean export, Writer fileOutput, Statement statement) - throws IOException { - for ( int j = 0; j < createSQL.length; j++ ) { - try { - execute( script, export, fileOutput, statement, createSQL[j] ); - } - catch ( SQLException e ) { - if ( haltOnError ) { - throw new JDBCException( "Error during DDL export", e ); + private void importScript(NamedReader namedReader, List exporters) throws Exception { + BufferedReader reader = new BufferedReader( namedReader.getReader() ); + String[] statements = importSqlCommandExtractor.extractCommands( reader ); + if (statements != null) { + for ( String statement : statements ) { + if ( statement != null ) { + String trimmedSql = statement.trim(); + if ( trimmedSql.endsWith( ";" )) { + trimmedSql = trimmedSql.substring( 0, statement.length() - 1 ); + } + if ( !StringHelper.isEmpty( trimmedSql ) ) { + try { + for ( Exporter exporter : exporters ) { + if ( exporter.acceptsImportScripts() ) { + exporter.export( trimmedSql ); + } + } + } + catch ( Exception e ) { + if (haltOnError) { + throw new ImportScriptException( "Error during statement execution (file: '" + + namedReader.getName() + "'): " + trimmedSql, e ); + } + exceptions.add(e); + LOG.unsuccessful(trimmedSql); + LOG.error(e.getMessage()); + } + } } - exceptions.add( e ); - log.error( "Unsuccessful: " + createSQL[j] ); - log.error( e.getMessage() ); } } } - private void drop(boolean script, boolean export, Writer fileOutput, Statement statement) - throws IOException { - for ( int i = 0; i < dropSQL.length; i++ ) { - try { - execute( script, export, fileOutput, statement, dropSQL[i] ); - } - catch ( SQLException e ) { - exceptions.add( e ); - log.debug( "Unsuccessful: " + dropSQL[i] ); - log.debug( e.getMessage() ); - } + private static class NamedReader { + private final Reader reader; + private final String name; + + public NamedReader(String name, InputStream stream) { + this.name = name; + this.reader = new InputStreamReader( stream ); } + + public Reader getReader() { + return reader; + } + + public String getName() { + return name; + } } private void execute(boolean script, boolean export, Writer fileOutput, Statement statement, final String sql) throws IOException, SQLException { + final SqlExceptionHelper sqlExceptionHelper = new SqlExceptionHelper(); + String formatted = formatter.format( sql ); - if ( delimiter != null ) { - formatted += delimiter; - } - if ( script ) { - System.out.println( formatted ); - } - log.debug( formatted ); + if (delimiter != null) formatted += delimiter; + if (script) System.out.println(formatted); + LOG.debug(formatted); if ( outputFile != null ) { fileOutput.write( formatted + "\n" ); } @@ -384,17 +497,22 @@ try { SQLWarning warnings = statement.getWarnings(); if ( warnings != null) { - JDBCExceptionReporter.logAndClearWarnings( connectionHelper.getConnection() ); + sqlExceptionHelper.logAndClearWarnings( connectionHelper.getConnection() ); } } catch( SQLException sqle ) { - log.warn( "unable to log SQLWarnings : " + sqle ); + LOG.unableToLogSqlWarnings(sqle); } } - } + private static StandardServiceRegistryImpl createServiceRegistry(Properties properties) { + Environment.verifyProperties( properties ); + ConfigurationHelper.resolvePlaceHolders( properties ); + return (StandardServiceRegistryImpl) new StandardServiceRegistryBuilder().applySettings( properties ).build(); + } + public static void main(String[] args) { try { Configuration cfg = new Configuration(); @@ -405,7 +523,7 @@ boolean halt = false; boolean export = true; String outFile = null; - String importFile = "/import.sql"; + String importFile = DEFAULT_IMPORT_FILE; String propFile = null; boolean format = false; String delim = null; @@ -471,19 +589,28 @@ cfg.setProperties( props ); } - SchemaExport se = new SchemaExport( cfg ) - .setHaltOnError( halt ) - .setOutputFile( outFile ) - .setImportFile( importFile ) - .setDelimiter( delim ); - if ( format ) { - se.setFormat( true ); + if (importFile != null) { + cfg.setProperty( AvailableSettings.HBM2DDL_IMPORT_FILES, importFile ); } - se.execute( script, export, drop, create ); + StandardServiceRegistryImpl serviceRegistry = createServiceRegistry( cfg.getProperties() ); + try { + SchemaExport se = new SchemaExport( serviceRegistry, cfg ) + .setHaltOnError( halt ) + .setOutputFile( outFile ) + .setDelimiter( delim ) + .setImportSqlCommandExtractor( serviceRegistry.getService( ImportSqlCommandExtractor.class ) ); + if ( format ) { + se.setFormat( true ); + } + se.execute( script, export, drop, create ); + } + finally { + serviceRegistry.destroy(); + } } catch ( Exception e ) { - log.error( "Error creating schema ", e ); + LOG.unableToCreateSchema(e); e.printStackTrace(); } } @@ -496,4 +623,5 @@ public List getExceptions() { return exceptions; } + } Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaExportTask.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaExportTask.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaExportTask.java 17 Aug 2012 14:36:37 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaExportTask.java 30 Jul 2014 16:15:43 -0000 1.1.2.1 @@ -24,27 +24,27 @@ */ package org.hibernate.tool.hbm2ddl; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; + import org.hibernate.HibernateException; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.NamingStrategy; -import org.hibernate.util.ArrayHelper; -import org.hibernate.util.ReflectHelper; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.internal.util.collections.ArrayHelper; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.MatchingTask; import org.apache.tools.ant.types.FileSet; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Properties; - /** * An Ant task for SchemaExport. * @@ -72,16 +72,16 @@ public class SchemaExportTask extends MatchingTask { private List fileSets = new LinkedList(); - private File propertiesFile = null; - private File configurationFile = null; - private File outputFile = null; - private boolean quiet = false; - private boolean text = false; - private boolean drop = false; - private boolean create = false; - private boolean haltOnError = false; - private String delimiter = null; - private String namingStrategy = null; + private File propertiesFile; + private File configurationFile; + private File outputFile; + private boolean quiet; + private boolean text; + private boolean drop; + private boolean create; + private boolean haltOnError; + private String delimiter; + private String namingStrategy; public void addFileset(FileSet set) { fileSets.add(set); @@ -164,7 +164,8 @@ /** * Execute the task */ - public void execute() throws BuildException { + @Override + public void execute() throws BuildException { try { getSchemaExport( getConfiguration() ).execute(!quiet, !text, drop, create); } Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaUpdate.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaUpdate.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaUpdate.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaUpdate.java 30 Jul 2014 16:15:43 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.tool.hbm2ddl; @@ -36,65 +35,84 @@ import org.hibernate.HibernateException; import org.hibernate.JDBCException; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.cfg.NamingStrategy; -import org.hibernate.cfg.Settings; import org.hibernate.dialect.Dialect; -import org.hibernate.jdbc.util.FormatStyle; -import org.hibernate.jdbc.util.Formatter; -import org.hibernate.jdbc.util.SQLStatementLogger; -import org.hibernate.util.PropertiesHelper; -import org.hibernate.util.ReflectHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.hibernate.engine.jdbc.internal.FormatStyle; +import org.hibernate.engine.jdbc.internal.Formatter; +import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; +import org.hibernate.engine.jdbc.spi.SqlStatementLogger; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.service.ServiceRegistry; +import org.jboss.logging.Logger; + /** - * A commandline tool to update a database schema. May also be called from - * inside an application. + * A commandline tool to update a database schema. May also be called from inside an application. * * @author Christoph Sturm + * @author Steve Ebersole */ public class SchemaUpdate { + private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, SchemaUpdate.class.getName()); - private static final Logger log = LoggerFactory.getLogger( SchemaUpdate.class ); - private ConnectionHelper connectionHelper; - private Configuration configuration; - private Dialect dialect; - private List exceptions; - private boolean haltOnError = false; + private final Configuration configuration; + private final ConnectionHelper connectionHelper; + private final SqlStatementLogger sqlStatementLogger; + private final SqlExceptionHelper sqlExceptionHelper; + private final Dialect dialect; + + private final List exceptions = new ArrayList(); + + private Formatter formatter; + + private boolean haltOnError; private boolean format = true; - private String outputFile = null; + private String outputFile; private String delimiter; - private Formatter formatter; - private SQLStatementLogger sqlStatementLogger; public SchemaUpdate(Configuration cfg) throws HibernateException { this( cfg, cfg.getProperties() ); } - public SchemaUpdate(Configuration cfg, Properties connectionProperties) throws HibernateException { - this.configuration = cfg; - dialect = Dialect.getDialect( connectionProperties ); + public SchemaUpdate(Configuration configuration, Properties properties) throws HibernateException { + this.configuration = configuration; + this.dialect = Dialect.getDialect( properties ); + Properties props = new Properties(); props.putAll( dialect.getDefaultProperties() ); - props.putAll( connectionProperties ); - connectionHelper = new ManagedProviderConnectionHelper( props ); - exceptions = new ArrayList(); - formatter = ( PropertiesHelper.getBoolean( Environment.FORMAT_SQL, props ) ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter(); + props.putAll( properties ); + this.connectionHelper = new ManagedProviderConnectionHelper( props ); + + this.sqlExceptionHelper = new SqlExceptionHelper(); + this.sqlStatementLogger = new SqlStatementLogger( false, true ); + this.formatter = FormatStyle.DDL.getFormatter(); } - public SchemaUpdate(Configuration cfg, Settings settings) throws HibernateException { + public SchemaUpdate(ServiceRegistry serviceRegistry, Configuration cfg) throws HibernateException { this.configuration = cfg; - dialect = settings.getDialect(); - connectionHelper = new SuppliedConnectionProviderConnectionHelper( - settings.getConnectionProvider() - ); - exceptions = new ArrayList(); - sqlStatementLogger = settings.getSqlStatementLogger(); - formatter = ( sqlStatementLogger.isFormatSql() ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter(); + + final JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class ); + this.dialect = jdbcServices.getDialect(); + this.connectionHelper = new SuppliedConnectionProviderConnectionHelper( jdbcServices.getConnectionProvider() ); + + this.sqlExceptionHelper = new SqlExceptionHelper(); + this.sqlStatementLogger = jdbcServices.getSqlStatementLogger(); + this.formatter = ( sqlStatementLogger.isFormat() ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter(); } + private static StandardServiceRegistryImpl createServiceRegistry(Properties properties) { + Environment.verifyProperties( properties ); + ConfigurationHelper.resolvePlaceHolders( properties ); + return (StandardServiceRegistryImpl) new StandardServiceRegistryBuilder().applySettings( properties ).build(); + } + public static void main(String[] args) { try { Configuration cfg = new Configuration(); @@ -137,10 +155,16 @@ cfg.setProperties( props ); } - new SchemaUpdate( cfg ).execute( script, doUpdate ); + StandardServiceRegistryImpl serviceRegistry = createServiceRegistry( cfg.getProperties() ); + try { + new SchemaUpdate( serviceRegistry, cfg ).execute( script, doUpdate ); + } + finally { + serviceRegistry.destroy(); + } } catch ( Exception e ) { - log.error( "Error running schema update", e ); + LOG.unableToRunSchemaUpdate(e); e.printStackTrace(); } } @@ -151,75 +175,76 @@ * @param script print all DDL to the console */ public void execute(boolean script, boolean doUpdate) { + execute( Target.interpret( script, doUpdate ) ); + } + + public void execute(Target target) { + LOG.runningHbm2ddlSchemaUpdate(); - log.info( "Running hbm2ddl schema update" ); - Connection connection = null; Statement stmt = null; Writer outputFileWriter = null; exceptions.clear(); try { - DatabaseMetadata meta; try { - log.info( "fetching database metadata" ); + LOG.fetchingDatabaseMetadata(); connectionHelper.prepare( true ); connection = connectionHelper.getConnection(); - meta = new DatabaseMetadata( connection, dialect ); + meta = new DatabaseMetadata( connection, dialect, configuration ); stmt = connection.createStatement(); } catch ( SQLException sqle ) { exceptions.add( sqle ); - log.error( "could not get database metadata", sqle ); + LOG.unableToGetDatabaseMetadata(sqle); throw sqle; } - log.info( "updating schema" ); + LOG.updatingSchema(); - if ( outputFile != null ) { - log.info( "writing generated schema to file: " + outputFile ); + LOG.writingGeneratedSchemaToFile( outputFile ); outputFileWriter = new FileWriter( outputFile ); } - - String[] createSQL = configuration.generateSchemaUpdateScript( dialect, meta ); - for ( int j = 0; j < createSQL.length; j++ ) { - final String sql = createSQL[j]; - String formatted = formatter.format( sql ); + List scripts = configuration.generateSchemaUpdateScriptList( dialect, meta ); + for ( SchemaUpdateScript script : scripts ) { + String formatted = formatter.format( script.getScript() ); try { if ( delimiter != null ) { formatted += delimiter; } - if ( script ) { + if ( target.doScript() ) { System.out.println( formatted ); } if ( outputFile != null ) { outputFileWriter.write( formatted + "\n" ); } - if ( doUpdate ) { - log.debug( sql ); + if ( target.doExport() ) { + LOG.debug( script.getScript() ); stmt.executeUpdate( formatted ); } } catch ( SQLException e ) { - if ( haltOnError ) { - throw new JDBCException( "Error during DDL export", e ); + if (!script.isQuiet()) { + if ( haltOnError ) { + throw new JDBCException( "Error during DDL export", e ); + } + exceptions.add( e ); + LOG.unsuccessful(script.getScript()); + LOG.error(e.getMessage()); } - exceptions.add( e ); - log.error( "Unsuccessful: " + sql ); - log.error( e.getMessage() ); } } - log.info( "schema update complete" ); + LOG.schemaUpdateComplete(); } catch ( Exception e ) { exceptions.add( e ); - log.error( "could not complete schema update", e ); + LOG.unableToCompleteSchemaUpdate(e); } finally { @@ -231,7 +256,7 @@ } catch ( Exception e ) { exceptions.add( e ); - log.error( "Error closing connection", e ); + LOG.unableToCloseConnection(e); } try { if( outputFileWriter != null ) { @@ -240,7 +265,7 @@ } catch(Exception e) { exceptions.add(e); - log.error( "Error closing connection", e ); + LOG.unableToCloseConnection(e); } } } @@ -269,5 +294,4 @@ public void setDelimiter(String delimiter) { this.delimiter = delimiter; } - } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaUpdateScript.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaUpdateTask.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaUpdateTask.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaUpdateTask.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaUpdateTask.java 30 Jul 2014 16:15:44 -0000 1.1.2.1 @@ -24,27 +24,27 @@ */ package org.hibernate.tool.hbm2ddl; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; + import org.hibernate.HibernateException; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.NamingStrategy; -import org.hibernate.util.ArrayHelper; -import org.hibernate.util.ReflectHelper; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.internal.util.collections.ArrayHelper; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.MatchingTask; import org.apache.tools.ant.types.FileSet; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Properties; - /** * An Ant task for SchemaUpdate. * @@ -68,14 +68,14 @@ public class SchemaUpdateTask extends MatchingTask { private List fileSets = new LinkedList(); - private File propertiesFile = null; - private File configurationFile = null; - private File outputFile = null; - private boolean quiet = false; + private File propertiesFile; + private File configurationFile; + private File outputFile; + private boolean quiet; private boolean text = true; - private boolean haltOnError = false; - private String delimiter = null; - private String namingStrategy = null; + private boolean haltOnError; + private String delimiter; + private String namingStrategy; public void addFileset(FileSet set) { @@ -124,7 +124,8 @@ /** * Execute the task */ - public void execute() throws BuildException { + @Override + public void execute() throws BuildException { try { log("Running Hibernate Core SchemaUpdate."); log("This is an Ant task supporting only mapping files, if you want to use annotations see http://tools.hibernate.org."); @@ -164,14 +165,14 @@ } } - return ArrayHelper.toStringArray(files); + return ArrayHelper.toStringArray( files ); } private Configuration getConfiguration() throws Exception { Configuration cfg = new Configuration(); if (namingStrategy!=null) { cfg.setNamingStrategy( - (NamingStrategy) ReflectHelper.classForName(namingStrategy).newInstance() + (NamingStrategy) ReflectHelper.classForName( namingStrategy ).newInstance() ); } if (configurationFile!=null) { @@ -237,4 +238,3 @@ } } - Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaValidator.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaValidator.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaValidator.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaValidator.java 30 Jul 2014 16:15:44 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.tool.hbm2ddl; @@ -29,24 +28,30 @@ import java.sql.SQLException; import java.util.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.hibernate.HibernateException; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.boot.registry.internal.StandardServiceRegistryImpl; import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; import org.hibernate.cfg.NamingStrategy; -import org.hibernate.cfg.Settings; import org.hibernate.dialect.Dialect; -import org.hibernate.util.ReflectHelper; +import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.service.ServiceRegistry; +import org.jboss.logging.Logger; + /** * A commandline tool to update a database schema. May also be called from * inside an application. * * @author Christoph Sturm */ public class SchemaValidator { + private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, SchemaValidator.class.getName()); - private static final Logger log = LoggerFactory.getLogger( SchemaValidator.class ); private ConnectionHelper connectionHelper; private Configuration configuration; private Dialect dialect; @@ -64,14 +69,19 @@ connectionHelper = new ManagedProviderConnectionHelper( props ); } - public SchemaValidator(Configuration cfg, Settings settings) throws HibernateException { + public SchemaValidator(ServiceRegistry serviceRegistry, Configuration cfg ) throws HibernateException { this.configuration = cfg; - dialect = settings.getDialect(); - connectionHelper = new SuppliedConnectionProviderConnectionHelper( - settings.getConnectionProvider() - ); + final JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class ); + this.dialect = jdbcServices.getDialect(); + this.connectionHelper = new SuppliedConnectionProviderConnectionHelper( jdbcServices.getConnectionProvider() ); } + private static StandardServiceRegistryImpl createServiceRegistry(Properties properties) { + Environment.verifyProperties( properties ); + ConfigurationHelper.resolvePlaceHolders( properties ); + return (StandardServiceRegistryImpl) new StandardServiceRegistryBuilder().applySettings( properties ).build(); + } + public static void main(String[] args) { try { Configuration cfg = new Configuration(); @@ -105,10 +115,16 @@ cfg.setProperties( props ); } - new SchemaValidator( cfg ).validate(); + StandardServiceRegistryImpl serviceRegistry = createServiceRegistry( cfg.getProperties() ); + try { + new SchemaValidator( serviceRegistry, cfg ).validate(); + } + finally { + serviceRegistry.destroy(); + } } catch ( Exception e ) { - log.error( "Error running schema update", e ); + LOG.unableToRunSchemaUpdate(e); e.printStackTrace(); } } @@ -118,40 +134,39 @@ */ public void validate() { - log.info( "Running schema validator" ); + LOG.runningSchemaValidator(); Connection connection = null; try { DatabaseMetadata meta; try { - log.info( "fetching database metadata" ); + LOG.fetchingDatabaseMetadata(); connectionHelper.prepare( false ); connection = connectionHelper.getConnection(); - meta = new DatabaseMetadata( connection, dialect, false ); + meta = new DatabaseMetadata( connection, dialect, configuration, false ); } catch ( SQLException sqle ) { - log.error( "could not get database metadata", sqle ); + LOG.unableToGetDatabaseMetadata(sqle); throw sqle; } configuration.validateSchema( dialect, meta ); } catch ( SQLException e ) { - log.error( "could not complete schema validation", e ); + LOG.unableToCompleteSchemaValidation(e); } finally { try { connectionHelper.release(); } catch ( Exception e ) { - log.error( "Error closing connection", e ); + LOG.unableToCloseConnection(e); } } } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaValidatorTask.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaValidatorTask.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaValidatorTask.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SchemaValidatorTask.java 30 Jul 2014 16:15:43 -0000 1.1.2.1 @@ -24,27 +24,27 @@ */ package org.hibernate.tool.hbm2ddl; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; + import org.hibernate.HibernateException; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.NamingStrategy; -import org.hibernate.util.ArrayHelper; -import org.hibernate.util.ReflectHelper; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.internal.util.collections.ArrayHelper; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.MatchingTask; import org.apache.tools.ant.types.FileSet; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Properties; - /** * An Ant task for SchemaUpdate. * @@ -67,9 +67,9 @@ public class SchemaValidatorTask extends MatchingTask { private List fileSets = new LinkedList(); - private File propertiesFile = null; - private File configurationFile = null; - private String namingStrategy = null; + private File propertiesFile; + private File configurationFile; + private String namingStrategy; public void addFileset(FileSet set) { fileSets.add(set); @@ -99,7 +99,8 @@ /** * Execute the task */ - public void execute() throws BuildException { + @Override + public void execute() throws BuildException { try { Configuration cfg = getConfiguration(); getSchemaValidator(cfg).validate(); @@ -137,7 +138,7 @@ } } - return ArrayHelper.toStringArray(files); + return ArrayHelper.toStringArray( files ); } private Configuration getConfiguration() throws Exception { Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/ScriptExporter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SingleLineSqlCommandExtractor.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SuppliedConnectionHelper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SuppliedConnectionHelper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SuppliedConnectionHelper.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SuppliedConnectionHelper.java 30 Jul 2014 16:15:43 -0000 1.1.2.1 @@ -24,11 +24,11 @@ */ package org.hibernate.tool.hbm2ddl; -import org.hibernate.util.JDBCExceptionReporter; - import java.sql.Connection; import java.sql.SQLException; +import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; + /** * A {@link ConnectionHelper} implementation based on an explicitly supplied * connection. @@ -61,7 +61,7 @@ } public void release() throws SQLException { - JDBCExceptionReporter.logAndClearWarnings( connection ); + new SqlExceptionHelper().logAndClearWarnings( connection ); if ( toggleAutoCommit ) { connection.setAutoCommit( false ); } Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SuppliedConnectionProviderConnectionHelper.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SuppliedConnectionProviderConnectionHelper.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SuppliedConnectionProviderConnectionHelper.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/SuppliedConnectionProviderConnectionHelper.java 30 Jul 2014 16:15:43 -0000 1.1.2.1 @@ -24,12 +24,12 @@ */ package org.hibernate.tool.hbm2ddl; -import org.hibernate.connection.ConnectionProvider; -import org.hibernate.util.JDBCExceptionReporter; - import java.sql.Connection; import java.sql.SQLException; +import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; +import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; + /** * A {@link ConnectionHelper} implementation based on a provided * {@link ConnectionProvider}. Essentially, ensures that the connection @@ -68,7 +68,7 @@ public void release() throws SQLException { // we only release the connection if ( connection != null ) { - JDBCExceptionReporter.logAndClearWarnings( connection ); + new SqlExceptionHelper().logAndClearWarnings( connection ); if ( toggleAutoCommit ) { connection.setAutoCommit( false ); } Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/TableMetadata.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/TableMetadata.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/TableMetadata.java 17 Aug 2012 14:36:36 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/TableMetadata.java 30 Jul 2014 16:15:44 -0000 1.1.2.1 @@ -20,27 +20,31 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.tool.hbm2ddl; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.mapping.ForeignKey; +import org.jboss.logging.Logger; /** * JDBC table metadata - * @author Christoph Sturm, Max Rydahl Andersen + * + * @author Christoph Sturm + * @author Max Rydahl Andersen */ public class TableMetadata { - - private static final Logger log = LoggerFactory.getLogger(TableMetadata.class); - + + private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, TableMetadata.class.getName()); + private final String catalog; private final String schema; private final String name; @@ -59,11 +63,11 @@ } String cat = catalog==null ? "" : catalog + '.'; String schem = schema==null ? "" : schema + '.'; - log.info( "table found: " + cat + schem + name ); - log.info( "columns: " + columns.keySet() ); + LOG.tableFound( cat + schem + name ); + LOG.columns( columns.keySet() ); if (extras) { - log.info( "foreign keys: " + foreignKeys.keySet() ); - log.info( "indexes: " + indexes.keySet() ); + LOG.foreignKeys( foreignKeys.keySet() ); + LOG.indexes( indexes.keySet() ); } } @@ -74,50 +78,66 @@ public String getCatalog() { return catalog; } - + public String getSchema() { return schema; } - - public String toString() { + + @Override + public String toString() { return "TableMetadata(" + name + ')'; } public ColumnMetadata getColumnMetadata(String columnName) { - return (ColumnMetadata) columns.get( columnName.toLowerCase() ); + return (ColumnMetadata) columns.get( StringHelper.toLowerCase(columnName) ); } public ForeignKeyMetadata getForeignKeyMetadata(String keyName) { - return (ForeignKeyMetadata) foreignKeys.get( keyName.toLowerCase() ); + return (ForeignKeyMetadata) foreignKeys.get( StringHelper.toLowerCase(keyName) ); } + public ForeignKeyMetadata getForeignKeyMetadata(ForeignKey fk) { + Iterator it = foreignKeys.values().iterator(); + while ( it.hasNext() ) { + ForeignKeyMetadata existingFk = ( ForeignKeyMetadata ) it.next(); + if ( existingFk.matches( fk ) ) { + return existingFk; + } + } + return null; + } + public IndexMetadata getIndexMetadata(String indexName) { - return (IndexMetadata) indexes.get( indexName.toLowerCase() ); + return (IndexMetadata) indexes.get( StringHelper.toLowerCase(indexName) ); } private void addForeignKey(ResultSet rs) throws SQLException { String fk = rs.getString("FK_NAME"); - if (fk == null) return; + if (fk == null) { + return; + } ForeignKeyMetadata info = getForeignKeyMetadata(fk); if (info == null) { info = new ForeignKeyMetadata(rs); - foreignKeys.put( info.getName().toLowerCase(), info ); + foreignKeys.put( StringHelper.toLowerCase(info.getName()), info ); } - info.addColumn( getColumnMetadata( rs.getString("FKCOLUMN_NAME") ) ); + info.addReference( rs ); } private void addIndex(ResultSet rs) throws SQLException { String index = rs.getString("INDEX_NAME"); - if (index == null) return; + if (index == null) { + return; + } IndexMetadata info = getIndexMetadata(index); if (info == null) { info = new IndexMetadata(rs); - indexes.put( info.getName().toLowerCase(), info ); + indexes.put( StringHelper.toLowerCase(info.getName()), info ); } info.addColumn( getColumnMetadata( rs.getString("COLUMN_NAME") ) ); @@ -126,11 +146,13 @@ public void addColumn(ResultSet rs) throws SQLException { String column = rs.getString("COLUMN_NAME"); - if (column==null) return; + if (column==null) { + return; + } if ( getColumnMetadata(column) == null ) { ColumnMetadata info = new ColumnMetadata(rs); - columns.put( info.getName().toLowerCase(), info ); + columns.put( StringHelper.toLowerCase(info.getName()), info ); } } @@ -139,10 +161,14 @@ try { rs = meta.getImportedKeys(catalog, schema, name); - while ( rs.next() ) addForeignKey(rs); + while ( rs.next() ) { + addForeignKey(rs); + } } finally { - if (rs != null) rs.close(); + if (rs != null) { + rs.close(); + } } } @@ -151,33 +177,34 @@ try { rs = meta.getIndexInfo(catalog, schema, name, false, true); - + while ( rs.next() ) { - if ( rs.getShort("TYPE") == DatabaseMetaData.tableIndexStatistic ) continue; + if ( rs.getShort("TYPE") == DatabaseMetaData.tableIndexStatistic ) { + continue; + } addIndex(rs); } } finally { - if (rs != null) rs.close(); + if (rs != null) { + rs.close(); + } } } private void initColumns(DatabaseMetaData meta) throws SQLException { ResultSet rs = null; - + try { rs = meta.getColumns(catalog, schema, name, "%"); - while ( rs.next() ) addColumn(rs); + while ( rs.next() ) { + addColumn(rs); + } } finally { - if (rs != null) rs.close(); + if (rs != null) { + rs.close(); + } } } - } - - - - - - Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/Target.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/tool/hbm2ddl/UniqueConstraintSchemaUpdateStrategy.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/instrument/BasicInstrumentationTask.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/instrument/BasicInstrumentationTask.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/instrument/BasicInstrumentationTask.java 17 Aug 2012 14:36:41 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/instrument/BasicInstrumentationTask.java 30 Jul 2014 16:17:07 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,52 +20,39 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.tool.instrument; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.types.FileSet; -import org.hibernate.bytecode.util.ClassDescriptor; -import org.hibernate.bytecode.util.ByteCodeHelper; -import org.hibernate.bytecode.util.FieldFilter; -import org.hibernate.bytecode.ClassTransformer; - -import java.util.List; +import java.io.File; import java.util.ArrayList; +import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Set; -import java.util.HashSet; -import java.util.zip.ZipInputStream; -import java.util.zip.ZipOutputStream; -import java.util.zip.ZipEntry; -import java.util.zip.CRC32; -import java.io.File; -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.io.IOException; -import java.io.FileInputStream; -import java.io.DataInputStream; -import java.io.ByteArrayInputStream; +import org.hibernate.bytecode.buildtime.spi.Instrumenter; +import org.hibernate.bytecode.buildtime.spi.Logger; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.FileSet; + /** - * Super class for all Hibernate instrumentation tasks. Provides the basic - * templating of how instrumentation should occur. + * Super class for all Hibernate instrumentation tasks. Provides the basic templating of how instrumentation + * should occur; subclasses simply plug in to that process appropriately for the given bytecode provider. * * @author Steve Ebersole */ -public abstract class BasicInstrumentationTask extends Task { +public abstract class BasicInstrumentationTask extends Task implements Instrumenter.Options { - private static final int ZIP_MAGIC = 0x504B0304; - private static final int CLASS_MAGIC = 0xCAFEBABE; + private final LoggerBridge logger = new LoggerBridge(); - protected final Logger logger = new Logger(); private List filesets = new ArrayList(); - private Set classNames = new HashSet(); private boolean extended; + + // deprecated option... private boolean verbose; public void addFileset(FileSet set) { @@ -92,32 +79,25 @@ this.verbose = verbose; } - public void execute() throws BuildException { - if ( isExtended() ) { - collectClassNames(); + public final boolean performExtendedInstrumentation() { + return isExtended(); + } + + protected abstract Instrumenter buildInstrumenter(Logger logger, Instrumenter.Options options); + + @Override + public void execute() throws BuildException { + try { + buildInstrumenter( logger, this ) + .execute( collectSpecifiedFiles() ); } - logger.info( "starting instrumentation" ); - Project project = getProject(); - Iterator filesets = filesets(); - while ( filesets.hasNext() ) { - FileSet fs = ( FileSet ) filesets.next(); - DirectoryScanner ds = fs.getDirectoryScanner( project ); - String[] includedFiles = ds.getIncludedFiles(); - File d = fs.getDir( project ); - for ( int i = 0; i < includedFiles.length; ++i ) { - File file = new File( d, includedFiles[i] ); - try { - processFile( file ); - } - catch ( Exception e ) { - throw new BuildException( e ); - } - } + catch ( Throwable t ) { + throw new BuildException( t ); } } - private void collectClassNames() { - logger.info( "collecting class names for extended instrumentation determination" ); + private Set collectSpecifiedFiles() { + HashSet files = new HashSet(); Project project = getProject(); Iterator filesets = filesets(); while ( filesets.hasNext() ) { @@ -126,239 +106,14 @@ String[] includedFiles = ds.getIncludedFiles(); File d = fs.getDir( project ); for ( int i = 0; i < includedFiles.length; ++i ) { - File file = new File( d, includedFiles[i] ); - try { - collectClassNames( file ); - } - catch ( Exception e ) { - throw new BuildException( e ); - } + files.add( new File( d, includedFiles[i] ) ); } } - logger.info( classNames.size() + " class(es) being checked" ); + return files; } - private void collectClassNames(File file) throws Exception { - if ( isClassFile( file ) ) { - byte[] bytes = ByteCodeHelper.readByteCode( file ); - ClassDescriptor descriptor = getClassDescriptor( bytes ); - classNames.add( descriptor.getName() ); - } - else if ( isJarFile( file ) ) { - ZipEntryHandler collector = new ZipEntryHandler() { - public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception { - if ( !entry.isDirectory() ) { - // see if the entry represents a class file - DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) ); - if ( din.readInt() == CLASS_MAGIC ) { - classNames.add( getClassDescriptor( byteCode ).getName() ); - } - } - } - }; - ZipFileProcessor processor = new ZipFileProcessor( collector ); - processor.process( file ); - } - } - - protected void processFile(File file) throws Exception { - logger.verbose( "processing file : " + file.toURL() ); - if ( isClassFile( file ) ) { - processClassFile(file); - } - else if ( isJarFile( file ) ) { - processJarFile(file); - } - else { - logger.verbose( "ignoring " + file.toURL() ); - - } - } - - protected final boolean isClassFile(File file) throws IOException { - return checkMagic( file, CLASS_MAGIC ); - } - - protected final boolean isJarFile(File file) throws IOException { - return checkMagic(file, ZIP_MAGIC); - } - - protected final boolean checkMagic(File file, long magic) throws IOException { - DataInputStream in = new DataInputStream( new FileInputStream( file ) ); - try { - int m = in.readInt(); - return magic == m; - } - finally { - in.close(); - } - } - - protected void processClassFile(File file) throws Exception { - logger.verbose( "Starting class file : " + file.toURL() ); - byte[] bytes = ByteCodeHelper.readByteCode( file ); - ClassDescriptor descriptor = getClassDescriptor( bytes ); - ClassTransformer transformer = getClassTransformer( descriptor ); - if ( transformer == null ) { - logger.verbose( "skipping file : " + file.toURL() ); - return; - } - - logger.info( "processing class [" + descriptor.getName() + "]; file = " + file.toURL() ); - byte[] transformedBytes = transformer.transform( - getClass().getClassLoader(), - descriptor.getName(), - null, - null, - descriptor.getBytes() - ); - - OutputStream out = new FileOutputStream( file ); - try { - out.write( transformedBytes ); - out.flush(); - } - finally { - try { - out.close(); - } - catch ( IOException ignore) { - // intentionally empty - } - } - } - - protected void processJarFile(final File file) throws Exception { - logger.verbose( "starting jar file : " + file.toURL() ); - - File tempFile = File.createTempFile( - file.getName(), - null, - new File( file.getAbsoluteFile().getParent() ) - ); - - try { - FileOutputStream fout = new FileOutputStream( tempFile, false ); - try { - final ZipOutputStream out = new ZipOutputStream( fout ); - ZipEntryHandler transformer = new ZipEntryHandler() { - public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception { - logger.verbose( "starting entry : " + entry.toString() ); - if ( !entry.isDirectory() ) { - // see if the entry represents a class file - DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) ); - if ( din.readInt() == CLASS_MAGIC ) { - ClassDescriptor descriptor = getClassDescriptor( byteCode ); - ClassTransformer transformer = getClassTransformer( descriptor ); - if ( transformer == null ) { - logger.verbose( "skipping entry : " + entry.toString() ); - } - else { - logger.info( "processing class [" + descriptor.getName() + "]; entry = " + file.toURL() ); - byteCode = transformer.transform( - getClass().getClassLoader(), - descriptor.getName(), - null, - null, - descriptor.getBytes() - ); - } - } - else { - logger.verbose( "ignoring zip entry : " + entry.toString() ); - } - } - - ZipEntry outEntry = new ZipEntry( entry.getName() ); - outEntry.setMethod( entry.getMethod() ); - outEntry.setComment( entry.getComment() ); - outEntry.setSize( byteCode.length ); - - if ( outEntry.getMethod() == ZipEntry.STORED ){ - CRC32 crc = new CRC32(); - crc.update( byteCode ); - outEntry.setCrc( crc.getValue() ); - outEntry.setCompressedSize( byteCode.length ); - } - out.putNextEntry( outEntry ); - out.write( byteCode ); - out.closeEntry(); - } - }; - ZipFileProcessor processor = new ZipFileProcessor( transformer ); - processor.process( file ); - out.close(); - } - finally{ - fout.close(); - } - - if ( file.delete() ) { - File newFile = new File( tempFile.getAbsolutePath() ); - if( !newFile.renameTo( file ) ) { - throw new IOException( "can not rename " + tempFile + " to " + file ); - } - } - else { - throw new IOException("can not delete " + file); - } - } - finally { - tempFile.delete(); - } - } - - protected boolean isBeingIntrumented(String className) { - logger.verbose( "checking to see if class [" + className + "] is set to be instrumented" ); - return classNames.contains( className ); - } - - protected abstract ClassDescriptor getClassDescriptor(byte[] byecode) throws Exception; - - protected abstract ClassTransformer getClassTransformer(ClassDescriptor descriptor); - - protected class CustomFieldFilter implements FieldFilter { - private final ClassDescriptor descriptor; - - public CustomFieldFilter(ClassDescriptor descriptor) { - this.descriptor = descriptor; - } - - public boolean shouldInstrumentField(String className, String fieldName) { - if ( descriptor.getName().equals( className ) ) { - logger.verbose( "accepting transformation of field [" + className + "." + fieldName + "]" ); - return true; - } - else { - logger.verbose( "rejecting transformation of field [" + className + "." + fieldName + "]" ); - return false; - } - } - - public boolean shouldTransformFieldAccess( - String transformingClassName, - String fieldOwnerClassName, - String fieldName) { - if ( descriptor.getName().equals( fieldOwnerClassName ) ) { - logger.verbose( "accepting transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]" ); - return true; - } - else if ( isExtended() && isBeingIntrumented( fieldOwnerClassName ) ) { - logger.verbose( "accepting extended transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]" ); - return true; - } - else { - logger.verbose( "rejecting transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]; caller = " + transformingClassName ); - return false; - } - } - } - - protected class Logger { - public void verbose(String message) { - if ( verbose ) { - System.out.println( message ); - } + protected class LoggerBridge implements Logger { + public void trace(String message) { log( message, Project.MSG_VERBOSE ); } @@ -373,34 +128,10 @@ public void warn(String message) { log( message, Project.MSG_WARN ); } - } - - private static interface ZipEntryHandler { - public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception; - } - - private static class ZipFileProcessor { - private final ZipEntryHandler entryHandler; - - public ZipFileProcessor(ZipEntryHandler entryHandler) { - this.entryHandler = entryHandler; + public void error(String message) { + log( message, Project.MSG_ERR ); } - - public void process(File file) throws Exception { - ZipInputStream zip = new ZipInputStream( new FileInputStream( file ) ); - - try { - ZipEntry entry; - while ( (entry = zip.getNextEntry()) != null ) { - byte bytes[] = ByteCodeHelper.readByteCode( zip ); - entryHandler.handleEntry( entry, bytes ); - zip.closeEntry(); - } - } - finally { - zip.close(); - } - } } + } Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/tool/instrument/cglib/InstrumentTask.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/tool/instrument/javassist/InstrumentTask.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/tool/instrument/javassist/InstrumentTask.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/tool/instrument/javassist/InstrumentTask.java 17 Aug 2012 14:36:56 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/tool/instrument/javassist/InstrumentTask.java 30 Jul 2014 16:17:02 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,22 +20,13 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.tool.instrument.javassist; -import java.io.DataInputStream; -import java.io.IOException; -import java.io.ByteArrayInputStream; - -import javassist.bytecode.ClassFile; - +import org.hibernate.bytecode.buildtime.internal.JavassistInstrumenter; +import org.hibernate.bytecode.buildtime.spi.Instrumenter; +import org.hibernate.bytecode.buildtime.spi.Logger; import org.hibernate.tool.instrument.BasicInstrumentationTask; -import org.hibernate.bytecode.util.ClassDescriptor; -import org.hibernate.bytecode.util.BasicClassFilter; -import org.hibernate.bytecode.ClassTransformer; -import org.hibernate.bytecode.javassist.BytecodeProviderImpl; -import org.hibernate.bytecode.javassist.FieldHandled; /** * An Ant task for instrumenting persistent classes in order to enable @@ -73,51 +64,8 @@ * @author Steve Ebersole */ public class InstrumentTask extends BasicInstrumentationTask { - - private static final BasicClassFilter CLASS_FILTER = new BasicClassFilter(); - - private final BytecodeProviderImpl provider = new BytecodeProviderImpl(); - - protected ClassDescriptor getClassDescriptor(byte[] bytecode) throws IOException { - return new CustomClassDescriptor( bytecode ); + @Override + protected Instrumenter buildInstrumenter(Logger logger, Instrumenter.Options options) { + return new JavassistInstrumenter( logger, options ); } - - protected ClassTransformer getClassTransformer(ClassDescriptor descriptor) { - if ( descriptor.isInstrumented() ) { - logger.verbose( "class [" + descriptor.getName() + "] already instrumented" ); - return null; - } - else { - return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor ) ); - } - } - - private static class CustomClassDescriptor implements ClassDescriptor { - private final byte[] bytes; - private final ClassFile classFile; - - public CustomClassDescriptor(byte[] bytes) throws IOException { - this.bytes = bytes; - this.classFile = new ClassFile( new DataInputStream( new ByteArrayInputStream( bytes ) ) ); - } - - public String getName() { - return classFile.getName(); - } - - public boolean isInstrumented() { - String[] intfs = classFile.getInterfaces(); - for ( int i = 0; i < intfs.length; i++ ) { - if ( FieldHandled.class.getName().equals( intfs[i] ) ) { - return true; - } - } - return false; - } - - public byte[] getBytes() { - return bytes; - } - } - } Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/BESTransactionManagerLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/BTMTransactionManagerLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/CMTTransaction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/CMTTransactionFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/CacheSynchronization.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/JBossTransactionManagerLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/JDBCTransaction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/JDBCTransactionFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/JNDITransactionManagerLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/JOTMTransactionManagerLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/JOnASTransactionManagerLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/JRun4TransactionManagerLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/JTATransaction.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/JTATransactionFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/OC4JTransactionManagerLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/OrionTransactionManagerLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/ResinTransactionManagerLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/SunONETransactionManagerLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/TransactionFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/TransactionFactoryFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/TransactionManagerLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/TransactionManagerLookupFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/WebSphereExtendedJTATransactionLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/WebSphereTransactionManagerLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/WeblogicTransactionManagerLookup.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1.2.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/transaction/package.html'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/AbstractBynaryType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/AbstractBynaryType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/AbstractBynaryType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/AbstractBynaryType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,30 +20,29 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.ResultSet; -import java.sql.Types; import java.io.ByteArrayInputStream; -import java.io.InputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; import java.util.Comparator; import org.hibernate.HibernateException; -import org.hibernate.EntityMode; -import org.hibernate.engine.SessionImplementor; import org.hibernate.cfg.Environment; +import org.hibernate.engine.spi.SessionImplementor; /** * Logic to bind stream of byte into a VARBINARY * * @author Gavin King * @author Emmanuel Bernard + * + * @deprecated Use the {@link AbstractStandardBasicType} approach instead */ public abstract class AbstractBynaryType extends MutableType implements VersionType, Comparator { @@ -123,16 +122,14 @@ return this; } - public int compare(Object o1, Object o2) { - return compare( o1, o2, null ); - } + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public boolean isEqual(Object x, Object y) { return x==y || ( x!=null && y!=null && java.util.Arrays.equals( toInternalFormat(x), toInternalFormat(y) ) ); } - public int getHashCode(Object x, EntityMode entityMode) { + public int getHashCode(Object x) { byte[] bytes = toInternalFormat(x); int hashCode = 1; for ( int j=0; j extends AbstractSingleColumnStandardBasicType { + private final AbstractStandardBasicType baseMutableType; - public AdaptedImmutableType(NullableType mutableType) { - this.mutableType = mutableType; + public AdaptedImmutableType(AbstractStandardBasicType baseMutableType) { + super( baseMutableType.getSqlTypeDescriptor(), baseMutableType.getJavaTypeDescriptor() ); + this.baseMutableType = baseMutableType; } - public Object get(ResultSet rs, String name) throws HibernateException, SQLException { - return mutableType.get(rs, name); + @Override + @SuppressWarnings({ "unchecked" }) + protected MutabilityPlan getMutabilityPlan() { + return ImmutableMutabilityPlan.INSTANCE; } - public void set(PreparedStatement st, Object value, int index) throws HibernateException, - SQLException { - mutableType.set(st, value, index); - } - - public int sqlType() { - return mutableType.sqlType(); - } - - public String toString(Object value) throws HibernateException { - return mutableType.toString(value); - } - - public Object fromStringValue(String xml) throws HibernateException { - return mutableType.fromStringValue(xml); - } - - public Class getReturnedClass() { - return mutableType.getReturnedClass(); - } - public String getName() { - return "imm_" + mutableType.getName(); + return "imm_" + baseMutableType.getName(); } - - public boolean isEqual(Object x, Object y) { - return mutableType.isEqual(x, y); - } - - public int getHashCode(Object x, EntityMode entityMode) { - return mutableType.getHashCode(x, entityMode); - } - - public int compare(Object x, Object y, EntityMode entityMode) { - return mutableType.compare(x, y, entityMode); - } } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/AnyType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/AnyType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/AnyType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/AnyType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; @@ -31,362 +30,507 @@ import java.sql.SQLException; import java.util.Arrays; import java.util.Map; +import java.util.Set; -import org.dom4j.Node; import org.hibernate.EntityMode; +import org.hibernate.EntityNameResolver; import org.hibernate.FetchMode; -import org.hibernate.Hibernate; import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.TransientObjectException; -import org.hibernate.engine.CascadeStyle; -import org.hibernate.engine.ForeignKeys; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.internal.ForeignKeys; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.CascadeStyles; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.metamodel.relational.Size; +import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Joinable; +import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.HibernateProxyHelper; -import org.hibernate.util.ArrayHelper; +import org.hibernate.proxy.LazyInitializer; +import org.dom4j.Node; + /** - * Handles "any" mappings and the old deprecated "object" type + * Handles "any" mappings + * * @author Gavin King */ -public class AnyType extends AbstractType implements AbstractComponentType, AssociationType { - +public class AnyType extends AbstractType implements CompositeType, AssociationType { + private final TypeFactory.TypeScope scope; private final Type identifierType; - private final Type metaType; + private final Type discriminatorType; - public AnyType(Type metaType, Type identifierType) { + /** + * Intended for use only from legacy {@link ObjectType} type definition + * + * @param discriminatorType + * @param identifierType + */ + protected AnyType(Type discriminatorType, Type identifierType) { + this( null, discriminatorType, identifierType ); + } + + public AnyType(TypeFactory.TypeScope scope, Type discriminatorType, Type identifierType) { + this.scope = scope; + this.discriminatorType = discriminatorType; this.identifierType = identifierType; - this.metaType = metaType; } - public AnyType() { - this(Hibernate.STRING, Hibernate.SERIALIZABLE); + public Type getIdentifierType() { + return identifierType; } - public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) - throws HibernateException { - return value; + public Type getDiscriminatorType() { + return discriminatorType; } - - public boolean isMethodOf(Method method) { - return false; + + + // general Type metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + @Override + public String getName() { + return "object"; } - public boolean isSame(Object x, Object y, EntityMode entityMode) throws HibernateException { - return x==y; + @Override + public Class getReturnedClass() { + return Object.class; } - public int compare(Object x, Object y, EntityMode entityMode) { - return 0; //TODO: entities CAN be compared, by PK and entity name, fix this! + @Override + public int[] sqlTypes(Mapping mapping) throws MappingException { + return ArrayHelper.join( discriminatorType.sqlTypes( mapping ), identifierType.sqlTypes( mapping ) ); } - public int getColumnSpan(Mapping session) - throws MappingException { - return 2; + @Override + public Size[] dictatedSizes(Mapping mapping) throws MappingException { + return ArrayHelper.join( discriminatorType.dictatedSizes( mapping ), identifierType.dictatedSizes( mapping ) ); } - public String getName() { - return "object"; + @Override + public Size[] defaultSizes(Mapping mapping) throws MappingException { + return ArrayHelper.join( discriminatorType.defaultSizes( mapping ), identifierType.defaultSizes( mapping ) ); } + @Override + public Object[] getPropertyValues(Object component, EntityMode entityMode) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isAnyType() { + return true; + } + + @Override + public boolean isAssociationType() { + return true; + } + + @Override + public boolean isComponentType() { + return true; + } + + @Override + public boolean isEmbedded() { + return false; + } + + @Override public boolean isMutable() { return false; } - public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) - throws HibernateException, SQLException { + @Override + public Object deepCopy(Object value, SessionFactoryImplementor factory) { + return value; + } - throw new UnsupportedOperationException("object is a multicolumn type"); + + // general Type functionality ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + @Override + public int compare(Object x, Object y) { + if ( x == null ) { + // if y is also null, return that they are the same (no option for "UNKNOWN") + // if y is not null, return that y is "greater" (-1 because the result is from the perspective of + // the first arg: x) + return y == null ? 0 : -1; + } + else if ( y == null ) { + // x is not null, but y is. return that x is "greater" + return 1; + } + + // At this point we know both are non-null. + final Object xId = extractIdentifier( x ); + final Object yId = extractIdentifier( y ); + + return getIdentifierType().compare( xId, yId ); } + private Object extractIdentifier(Object entity) { + final EntityPersister concretePersister = guessEntityPersister( entity ); + return concretePersister == null + ? null + : concretePersister.getEntityTuplizer().getIdentifier( entity, null ); + } + + private EntityPersister guessEntityPersister(Object object) { + if ( scope == null ) { + return null; + } + + String entityName = null; + + // this code is largely copied from Session's bestGuessEntityName + Object entity = object; + if ( entity instanceof HibernateProxy ) { + final LazyInitializer initializer = ( (HibernateProxy) entity ).getHibernateLazyInitializer(); + if ( initializer.isUninitialized() ) { + entityName = initializer.getEntityName(); + } + entity = initializer.getImplementation(); + } + + if ( entityName == null ) { + for ( EntityNameResolver resolver : scope.resolveFactory().iterateEntityNameResolvers() ) { + entityName = resolver.resolveEntityName( entity ); + if ( entityName != null ) { + break; + } + } + } + + if ( entityName == null ) { + // the old-time stand-by... + entityName = object.getClass().getName(); + } + + return scope.resolveFactory().getEntityPersister( entityName ); + } + + @Override + public boolean isSame(Object x, Object y) throws HibernateException { + return x == y; + } + + @Override + public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session) + throws HibernateException { + if ( current == null ) { + return old != null; + } + else if ( old == null ) { + return true; + } + + final ObjectTypeCacheEntry holder = (ObjectTypeCacheEntry) old; + final boolean[] idCheckable = new boolean[checkable.length-1]; + System.arraycopy( checkable, 1, idCheckable, 0, idCheckable.length ); + return ( checkable[0] && !holder.entityName.equals( session.bestGuessEntityName( current ) ) ) + || identifierType.isModified( holder.id, getIdentifier( current, session ), idCheckable, session ); + } + + @Override + public boolean[] toColumnNullness(Object value, Mapping mapping) { + final boolean[] result = new boolean[ getColumnSpan( mapping ) ]; + if ( value != null ) { + Arrays.fill( result, true ); + } + return result; + } + + @Override + public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) + throws HibernateException { + return isDirty( old, current, session ); + } + + @Override + public int getColumnSpan(Mapping session) { + return 2; + } + + @Override public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) - throws HibernateException, SQLException { + throws HibernateException, SQLException { return resolveAny( - (String) metaType.nullSafeGet(rs, names[0], session, owner), - (Serializable) identifierType.nullSafeGet(rs, names[1], session, owner), + (String) discriminatorType.nullSafeGet( rs, names[0], session, owner ), + (Serializable) identifierType.nullSafeGet( rs, names[1], session, owner ), session - ); + ); } + @Override public Object hydrate(ResultSet rs, String[] names, SessionImplementor session, Object owner) - throws HibernateException, SQLException { - String entityName = (String) metaType.nullSafeGet(rs, names[0], session, owner); - Serializable id = (Serializable) identifierType.nullSafeGet(rs, names[1], session, owner); - return new ObjectTypeCacheEntry(entityName, id); + throws HibernateException, SQLException { + final String entityName = (String) discriminatorType.nullSafeGet( rs, names[0], session, owner ); + final Serializable id = (Serializable) identifierType.nullSafeGet( rs, names[1], session, owner ); + return new ObjectTypeCacheEntry( entityName, id ); } - public Object resolve(Object value, SessionImplementor session, Object owner) - throws HibernateException { - ObjectTypeCacheEntry holder = (ObjectTypeCacheEntry) value; - return resolveAny(holder.entityName, holder.id, session); + @Override + public Object resolve(Object value, SessionImplementor session, Object owner) throws HibernateException { + final ObjectTypeCacheEntry holder = (ObjectTypeCacheEntry) value; + return resolveAny( holder.entityName, holder.id, session ); } - public Object semiResolve(Object value, SessionImplementor session, Object owner) - throws HibernateException { - throw new UnsupportedOperationException("any mappings may not form part of a property-ref"); - } - private Object resolveAny(String entityName, Serializable id, SessionImplementor session) - throws HibernateException { - return entityName==null || id==null ? - null : session.internalLoad( entityName, id, false, false ); + throws HibernateException { + return entityName==null || id==null + ? null + : session.internalLoad( entityName, id, false, false ); } + @Override public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) - throws HibernateException, SQLException { - nullSafeSet(st, value, index, null, session); + throws HibernateException, SQLException { + nullSafeSet( st, value, index, null, session ); } - - public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session) - throws HibernateException, SQLException { + @Override + public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session) + throws HibernateException, SQLException { Serializable id; String entityName; - if (value==null) { - id=null; - entityName=null; + if ( value == null ) { + id = null; + entityName = null; } else { - entityName = session.bestGuessEntityName(value); - id = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, value, session); + entityName = session.bestGuessEntityName( value ); + id = ForeignKeys.getEntityIdentifierIfNotUnsaved( entityName, value, session ); } - - // metaType is assumed to be single-column type - if ( settable==null || settable[0] ) { - metaType.nullSafeSet(st, entityName, index, session); + + // discriminatorType is assumed to be single-column type + if ( settable == null || settable[0] ) { + discriminatorType.nullSafeSet( st, entityName, index, session ); } - if (settable==null) { - identifierType.nullSafeSet(st, id, index+1, session); + if ( settable == null ) { + identifierType.nullSafeSet( st, id, index+1, session ); } else { - boolean[] idsettable = new boolean[ settable.length-1 ]; - System.arraycopy(settable, 1, idsettable, 0, idsettable.length); - identifierType.nullSafeSet(st, id, index+1, idsettable, session); + final boolean[] idSettable = new boolean[ settable.length-1 ]; + System.arraycopy( settable, 1, idSettable, 0, idSettable.length ); + identifierType.nullSafeSet( st, id, index+1, idSettable, session ); } } - public Class getReturnedClass() { - return Object.class; + @Override + public String toLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException { + //TODO: terrible implementation! + return value == null + ? "null" + : factory.getTypeHelper() + .entity( HibernateProxyHelper.getClassWithoutInitializingProxy( value ) ) + .toLoggableString( value, factory ); } - public int[] sqlTypes(Mapping mapping) throws MappingException { - return ArrayHelper.join( - metaType.sqlTypes(mapping), - identifierType.sqlTypes(mapping) - ); + @Override + public Object assemble(Serializable cached, SessionImplementor session, Object owner) throws HibernateException { + final ObjectTypeCacheEntry e = (ObjectTypeCacheEntry) cached; + return e == null ? null : session.internalLoad( e.entityName, e.id, false, false ); } - public void setToXMLNode(Node xml, Object value, SessionFactoryImplementor factory) { - throw new UnsupportedOperationException("any types cannot be stringified"); + @Override + public Serializable disassemble(Object value, SessionImplementor session, Object owner) throws HibernateException { + if ( value == null ) { + return null; + } + else { + return new ObjectTypeCacheEntry( + session.bestGuessEntityName( value ), + ForeignKeys.getEntityIdentifierIfNotUnsaved( + session.bestGuessEntityName( value ), + value, + session + ) + ); + } } - public String toLoggableString(Object value, SessionFactoryImplementor factory) - throws HibernateException { - //TODO: terrible implementation! - return value==null ? - "null" : - Hibernate.entity( HibernateProxyHelper.getClassWithoutInitializingProxy(value) ) - .toLoggableString(value, factory); + @Override + public Object replace(Object original, Object target, SessionImplementor session, Object owner, Map copyCache) + throws HibernateException { + if ( original == null ) { + return null; + } + else { + final String entityName = session.bestGuessEntityName( original ); + final Serializable id = ForeignKeys.getEntityIdentifierIfNotUnsaved( entityName, original, session ); + return session.internalLoad( entityName, id, false, false ); + } } - public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException { - throw new UnsupportedOperationException(); //TODO: is this right?? + @Override + public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) { + throw new UnsupportedOperationException( "object is a multicolumn type" ); } - public static final class ObjectTypeCacheEntry implements Serializable { - String entityName; - Serializable id; - ObjectTypeCacheEntry(String entityName, Serializable id) { - this.entityName = entityName; - this.id = id; - } + @Override + public Object semiResolve(Object value, SessionImplementor session, Object owner) { + throw new UnsupportedOperationException( "any mappings may not form part of a property-ref" ); } - public Object assemble( - Serializable cached, - SessionImplementor session, - Object owner) - throws HibernateException { - - ObjectTypeCacheEntry e = (ObjectTypeCacheEntry) cached; - return e==null ? null : session.internalLoad(e.entityName, e.id, false, false); + @Override + public void setToXMLNode(Node xml, Object value, SessionFactoryImplementor factory) { + throw new UnsupportedOperationException("any types cannot be stringified"); } - public Serializable disassemble(Object value, SessionImplementor session, Object owner) - throws HibernateException { - return value==null ? - null : - new ObjectTypeCacheEntry( - session.bestGuessEntityName(value), - ForeignKeys.getEntityIdentifierIfNotUnsaved( - session.bestGuessEntityName(value), value, session - ) - ); + @Override + public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException { + throw new UnsupportedOperationException(); } - public boolean isAnyType() { - return true; - } - public Object replace( - Object original, - Object target, - SessionImplementor session, - Object owner, - Map copyCache) - throws HibernateException { - if (original==null) { - return null; - } - else { - String entityName = session.bestGuessEntityName(original); - Serializable id = ForeignKeys.getEntityIdentifierIfNotUnsaved( - entityName, - original, - session - ); - return session.internalLoad( - entityName, - id, - false, - false - ); - } - } - public CascadeStyle getCascadeStyle(int i) { - return CascadeStyle.NONE; - } - public FetchMode getFetchMode(int i) { - return FetchMode.SELECT; + // CompositeType implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + @Override + public boolean isMethodOf(Method method) { + return false; } private static final String[] PROPERTY_NAMES = new String[] { "class", "id" }; + @Override public String[] getPropertyNames() { return PROPERTY_NAMES; } - public Object getPropertyValue(Object component, int i, SessionImplementor session) - throws HibernateException { - - return i==0 ? - session.bestGuessEntityName(component) : - getIdentifier(component, session); + @Override + public Object getPropertyValue(Object component, int i, SessionImplementor session) throws HibernateException { + return i==0 + ? session.bestGuessEntityName( component ) + : getIdentifier( component, session ); } - public Object[] getPropertyValues(Object component, SessionImplementor session) - throws HibernateException { - - return new Object[] { session.bestGuessEntityName(component), getIdentifier(component, session) }; + @Override + public Object[] getPropertyValues(Object component, SessionImplementor session) throws HibernateException { + return new Object[] { + session.bestGuessEntityName( component ), + getIdentifier( component, session ) + }; } private Serializable getIdentifier(Object value, SessionImplementor session) throws HibernateException { try { - return ForeignKeys.getEntityIdentifierIfNotUnsaved( session.bestGuessEntityName(value), value, session ); + return ForeignKeys.getEntityIdentifierIfNotUnsaved( + session.bestGuessEntityName( value ), + value, + session + ); } catch (TransientObjectException toe) { return null; } } - public Type[] getSubtypes() { - return new Type[] { metaType, identifierType }; + @Override + public void setPropertyValues(Object component, Object[] values, EntityMode entityMode) { + throw new UnsupportedOperationException(); } - public void setPropertyValues(Object component, Object[] values, EntityMode entityMode) - throws HibernateException { + private static final boolean[] NULLABILITY = new boolean[] { false, false }; - throw new UnsupportedOperationException(); + @Override + public boolean[] getPropertyNullability() { + return NULLABILITY; + } + @Override + public Type[] getSubtypes() { + return new Type[] {discriminatorType, identifierType }; } - public Object[] getPropertyValues(Object component, EntityMode entityMode) { - throw new UnsupportedOperationException(); + @Override + public CascadeStyle getCascadeStyle(int i) { + return CascadeStyles.NONE; } - public boolean isComponentType() { - return true; + @Override + public FetchMode getFetchMode(int i) { + return FetchMode.SELECT; } + + // AssociationType implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + @Override public ForeignKeyDirection getForeignKeyDirection() { - //return AssociationType.FOREIGN_KEY_TO_PARENT; //this is better but causes a transient object exception... return ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT; } - public boolean isAssociationType() { - return true; - } - + @Override public boolean useLHSPrimaryKey() { return false; } - public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) { - throw new UnsupportedOperationException("any types do not have a unique referenced persister"); - } - - public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session) - throws HibernateException { - if (current==null) return old!=null; - if (old==null) return current!=null; - ObjectTypeCacheEntry holder = (ObjectTypeCacheEntry) old; - boolean[] idcheckable = new boolean[checkable.length-1]; - System.arraycopy(checkable, 1, idcheckable, 0, idcheckable.length); - return ( checkable[0] && !holder.entityName.equals( session.bestGuessEntityName(current) ) ) || - identifierType.isModified(holder.id, getIdentifier(current, session), idcheckable, session); - } - - public String getAssociatedEntityName(SessionFactoryImplementor factory) - throws MappingException { - throw new UnsupportedOperationException("any types do not have a unique referenced persister"); - } - - public boolean[] getPropertyNullability() { + @Override + public String getLHSPropertyName() { return null; } - public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters) - throws MappingException { - throw new UnsupportedOperationException(); - } - public boolean isReferenceToPrimaryKey() { return true; } - + + @Override public String getRHSUniqueKeyPropertyName() { return null; } - public String getLHSPropertyName() { - return null; - } - + @Override public boolean isAlwaysDirtyChecked() { return false; } + @Override public boolean isEmbeddedInXML() { return false; } - - public boolean[] toColumnNullness(Object value, Mapping mapping) { - boolean[] result = new boolean[ getColumnSpan(mapping) ]; - if (value!=null) Arrays.fill(result, true); - return result; + + @Override + public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) { + throw new UnsupportedOperationException("any types do not have a unique referenced persister"); } - public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) - throws HibernateException { - //TODO!!! - return isDirty(old, current, session); + @Override + public String getAssociatedEntityName(SessionFactoryImplementor factory) { + throw new UnsupportedOperationException("any types do not have a unique referenced persister"); } - public boolean isEmbedded() { - return false; + @Override + public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters) { + throw new UnsupportedOperationException(); } + + @Override + public String getOnCondition( + String alias, + SessionFactoryImplementor factory, + Map enabledFilters, + Set treatAsDeclarations) { + throw new UnsupportedOperationException(); + } + + /** + * Used to externalize discrimination per a given identifier. For example, when writing to + * second level cache we write the discrimination resolved concrete type for each entity written. + */ + public static final class ObjectTypeCacheEntry implements Serializable { + final String entityName; + final Serializable id; + + ObjectTypeCacheEntry(String entityName, Serializable id) { + this.entityName = entityName; + this.id = id; + } + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/ArrayType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/ArrayType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/ArrayType.java 17 Aug 2012 14:36:27 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/ArrayType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; @@ -32,12 +31,11 @@ import java.util.List; import java.util.Map; -import org.hibernate.EntityMode; import org.hibernate.HibernateException; -import org.hibernate.collection.PersistentArrayHolder; -import org.hibernate.collection.PersistentCollection; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.collection.internal.PersistentArrayHolder; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; /** @@ -49,17 +47,28 @@ private final Class elementClass; private final Class arrayClass; - public ArrayType(String role, String propertyRef, Class elementClass, boolean isEmbeddedInXML) { - super(role, propertyRef, isEmbeddedInXML); + /** + * @deprecated Use {@link #ArrayType(TypeFactory.TypeScope, String, String, Class )} instead. + * See Jira issue: HHH-7771 + */ + @Deprecated + public ArrayType(TypeFactory.TypeScope typeScope, String role, String propertyRef, Class elementClass, boolean isEmbeddedInXML) { + super( typeScope, role, propertyRef, isEmbeddedInXML ); this.elementClass = elementClass; arrayClass = Array.newInstance(elementClass, 0).getClass(); } + public ArrayType(TypeFactory.TypeScope typeScope, String role, String propertyRef, Class elementClass) { + super( typeScope, role, propertyRef ); + this.elementClass = elementClass; + arrayClass = Array.newInstance(elementClass, 0).getClass(); + } + public Class getReturnedClass() { return arrayClass; } - public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) + public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) throws HibernateException { return new PersistentArrayHolder(session, persister); } @@ -127,18 +136,19 @@ int length = Array.getLength(array); for ( int i=0; i treatAsDeclarations); /** * Do we dirty check this association, even when there are * no columns to be updated? */ public abstract boolean isAlwaysDirtyChecked(); - + + /** + * @deprecated To be removed in 5. Removed as part of removing the notion of DOM entity-mode. + * See Jira issue: HHH-7771 + */ + @Deprecated public boolean isEmbeddedInXML(); } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/BagType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/BagType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/BagType.java 17 Aug 2012 14:36:30 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/BagType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,50 +20,45 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; -import org.dom4j.Element; -import org.hibernate.EntityMode; import org.hibernate.HibernateException; -import org.hibernate.collection.PersistentBag; -import org.hibernate.collection.PersistentCollection; -import org.hibernate.collection.PersistentElementHolder; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.collection.internal.PersistentBag; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; public class BagType extends CollectionType { - public BagType(String role, String propertyRef, boolean isEmbeddedInXML) { - super(role, propertyRef, isEmbeddedInXML); + /** + * @deprecated Use {@link #BagType(TypeFactory.TypeScope, String, String )} + * See Jira issue: HHH-7771 + */ + @Deprecated + public BagType(TypeFactory.TypeScope typeScope, String role, String propertyRef, boolean isEmbeddedInXML) { + super( typeScope, role, propertyRef, isEmbeddedInXML ); } + public BagType(TypeFactory.TypeScope typeScope, String role, String propertyRef) { + super( typeScope, role, propertyRef ); + } + public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) throws HibernateException { - if ( session.getEntityMode()==EntityMode.DOM4J ) { - return new PersistentElementHolder(session, persister, key); - } - else { - return new PersistentBag(session); - } + return new PersistentBag(session); } public Class getReturnedClass() { return java.util.Collection.class; } public PersistentCollection wrap(SessionImplementor session, Object collection) { - if ( session.getEntityMode()==EntityMode.DOM4J ) { - return new PersistentElementHolder( session, (Element) collection ); - } - else { - return new PersistentBag( session, (Collection) collection ); - } + return new PersistentBag( session, (Collection) collection ); } public Object instantiate(int anticipatedSize) { Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/BasicType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/BasicTypeRegistry.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/BigDecimalType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/BigDecimalType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/BigDecimalType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/BigDecimalType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,70 +20,35 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.math.BigDecimal; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; import java.sql.Types; -import org.hibernate.EntityMode; -import org.hibernate.HibernateException; +import org.hibernate.type.descriptor.java.BigDecimalTypeDescriptor; +import org.hibernate.type.descriptor.sql.NumericTypeDescriptor; /** - * big_decimal: A type that maps an SQL NUMERIC to a - * java.math.BigDecimal - * @see java.math.BigDecimal + * A type that maps between a {@link Types#NUMERIC NUMERIC} and {@link BigDecimal}. + * * @author Gavin King + * @author Steve Ebersole */ -public class BigDecimalType extends ImmutableType { +public class BigDecimalType extends AbstractSingleColumnStandardBasicType { + public static final BigDecimalType INSTANCE = new BigDecimalType(); - public Object get(ResultSet rs, String name) - throws HibernateException, SQLException { - return rs.getBigDecimal(name); + public BigDecimalType() { + super( NumericTypeDescriptor.INSTANCE, BigDecimalTypeDescriptor.INSTANCE ); } - public void set(PreparedStatement st, Object value, int index) - throws HibernateException, SQLException { - st.setBigDecimal(index, (BigDecimal) value); - } - - public int sqlType() { - return Types.NUMERIC; - } - - public String toString(Object value) throws HibernateException { - return value.toString(); - } - - public Class getReturnedClass() { - return BigDecimal.class; - } - - public boolean isEqual(Object x, Object y) { - return x==y || ( x!=null && y!=null && ( (BigDecimal) x ).compareTo( (BigDecimal) y )==0 ); - } - - public int getHashCode(Object x, EntityMode entityMode) { - return ( (BigDecimal) x ).intValue(); - } - + @Override public String getName() { return "big_decimal"; } - public Object fromStringValue(String xml) { - return new BigDecimal(xml); + @Override + protected boolean registerUnderJavaType() { + return true; } - - } - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/BigIntegerType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/BigIntegerType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/BigIntegerType.java 17 Aug 2012 14:36:30 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/BigIntegerType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,83 +20,49 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; -import java.math.BigDecimal; import java.math.BigInteger; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; import java.sql.Types; -import org.hibernate.EntityMode; -import org.hibernate.HibernateException; import org.hibernate.dialect.Dialect; +import org.hibernate.type.descriptor.java.BigIntegerTypeDescriptor; +import org.hibernate.type.descriptor.sql.NumericTypeDescriptor; /** - * big_integer: A type that maps an SQL NUMERIC to a - * java.math.BigInteger - * @see java.math.BigInteger + * A type that maps between a {@link Types#NUMERIC NUMERIC} and {@link BigInteger}. + * * @author Gavin King + * @author Steve Ebersole */ -public class BigIntegerType extends ImmutableType implements DiscriminatorType { +public class BigIntegerType + extends AbstractSingleColumnStandardBasicType + implements DiscriminatorType { - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return value.toString(); - } + public static final BigIntegerType INSTANCE = new BigIntegerType(); - public Object stringToObject(String xml) throws Exception { - return new BigInteger(xml); + public BigIntegerType() { + super( NumericTypeDescriptor.INSTANCE, BigIntegerTypeDescriptor.INSTANCE ); } - public Object get(ResultSet rs, String name) - throws HibernateException, SQLException { - //return rs.getBigDecimal(name).toBigIntegerExact(); this 1.5 only. - BigDecimal bigDecimal = rs.getBigDecimal(name); - return bigDecimal==null ? null : - bigDecimal.setScale(0, BigDecimal.ROUND_UNNECESSARY).unscaledValue(); - } - - public void set(PreparedStatement st, Object value, int index) - throws HibernateException, SQLException { - st.setBigDecimal( index, new BigDecimal( (BigInteger) value ) ); - } - - public int sqlType() { - return Types.NUMERIC; - } - - public String toString(Object value) throws HibernateException { - return value.toString(); - } - - public Class getReturnedClass() { - return BigInteger.class; - } - - public boolean isEqual(Object x, Object y) { - return x==y || ( x!=null && y!=null && ( (BigInteger) x ).compareTo( (BigInteger) y )==0 ); - } - - public int getHashCode(Object x, EntityMode entityMode) { - return ( (BigInteger) x ).intValue(); - } - + @Override public String getName() { return "big_integer"; } - public Object fromStringValue(String xml) { - return new BigInteger(xml); + @Override + protected boolean registerUnderJavaType() { + return true; } + @Override + public String objectToSQLString(BigInteger value, Dialect dialect) { + return BigIntegerTypeDescriptor.INSTANCE.toString( value ); + } + @Override + public BigInteger stringToObject(String string) { + return BigIntegerTypeDescriptor.INSTANCE.fromString( string ); + } } - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/BinaryType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/BinaryType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/BinaryType.java 17 Aug 2012 14:36:27 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/BinaryType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,28 +20,56 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; +import java.util.Comparator; + +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.type.descriptor.java.PrimitiveByteArrayTypeDescriptor; +import org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor; + /** - * binary: A type that maps an SQL VARBINARY to a Java byte[]. + * A type that maps between a {@link java.sql.Types#VARBINARY VARBINARY} and {@code byte[]} + * * @author Gavin King + * @author Steve Ebersole */ -public class BinaryType extends AbstractBynaryType { +public class BinaryType + extends AbstractSingleColumnStandardBasicType + implements VersionType { - protected Object toExternalFormat(byte[] bytes) { - return bytes; + public static final BinaryType INSTANCE = new BinaryType(); + + public String getName() { + return "binary"; } - protected byte[] toInternalFormat(Object bytes) { - return (byte[]) bytes; + public BinaryType() { + super( VarbinaryTypeDescriptor.INSTANCE, PrimitiveByteArrayTypeDescriptor.INSTANCE ); } - public Class getReturnedClass() { - return byte[].class; + @Override + public String[] getRegistrationKeys() { + return new String[] { getName(), "byte[]", byte[].class.getName() }; } - public String getName() { return "binary"; } + @Override + public byte[] seed(SessionImplementor session) { + // Note : simply returns null for seed() and next() as the only known + // application of binary types for versioning is for use with the + // TIMESTAMP datatype supported by Sybase and SQL Server, which + // are completely db-generated values... + return null; + } + @Override + public byte[] next(byte[] current, SessionImplementor session) { + return current; + } + + @Override + public Comparator getComparator() { + return PrimitiveByteArrayTypeDescriptor.INSTANCE.getComparator(); + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/BlobType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/BlobType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/BlobType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/BlobType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,163 +20,40 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; - -import java.io.Serializable; import java.sql.Blob; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Map; -import org.dom4j.Node; -import org.hibernate.EntityMode; -import org.hibernate.HibernateException; -import org.hibernate.MappingException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.lob.BlobImpl; -import org.hibernate.lob.SerializableBlob; -import org.hibernate.util.ArrayHelper; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.type.descriptor.java.BlobTypeDescriptor; /** - * blob: A type that maps an SQL BLOB to a java.sql.Blob. + * A type that maps between {@link java.sql.Types#BLOB BLOB} and {@link Blob} + * * @author Gavin King + * @author Steve Ebersole */ -public class BlobType extends AbstractType { +public class BlobType extends AbstractSingleColumnStandardBasicType { + public static final BlobType INSTANCE = new BlobType(); - public void set(PreparedStatement st, Object value, int index, SessionImplementor session) - throws HibernateException, SQLException { - - if (value==null) { - st.setNull(index, Types.BLOB); - } - else { - - if (value instanceof SerializableBlob) { - value = ( (SerializableBlob) value ).getWrappedBlob(); - } - - final boolean useInputStream = session.getFactory().getDialect().useInputStreamToInsertBlob() && - (value instanceof BlobImpl); - - if ( useInputStream ) { - BlobImpl blob = (BlobImpl) value; - st.setBinaryStream( index, blob.getBinaryStream(), (int) blob.length() ); - } - else { - st.setBlob(index, (Blob) value); - } - - } - + public BlobType() { + super( org.hibernate.type.descriptor.sql.BlobTypeDescriptor.DEFAULT, BlobTypeDescriptor.INSTANCE ); } - public Object get(ResultSet rs, String name) throws HibernateException, SQLException { - Blob value = rs.getBlob(name); - return rs.wasNull() ? null : new SerializableBlob(value); - } - - public Class getReturnedClass() { - return Blob.class; - } - - public boolean isEqual(Object x, Object y, EntityMode entityMode) { - return x == y; - } - - public int getHashCode(Object x, EntityMode entityMode) { - return System.identityHashCode(x); - } - - public int compare(Object x, Object y, EntityMode entityMode) { - return 0; //lobs cannot be compared - } - + @Override public String getName() { return "blob"; } - - public Serializable disassemble(Object value, SessionImplementor session, Object owner) - throws HibernateException { - throw new UnsupportedOperationException("Blobs are not cacheable"); - } - public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) { - return value; + @Override + protected boolean registerUnderJavaType() { + return true; } - - public Object fromXMLNode(Node xml, Mapping factory) { - throw new UnsupportedOperationException("todo"); - } - - public int getColumnSpan(Mapping mapping) { - return 1; - } - - public boolean isMutable() { - return false; - } - - public Object nullSafeGet(ResultSet rs, String name, - SessionImplementor session, Object owner) - throws HibernateException, SQLException { - return get(rs, name); - } - - public Object nullSafeGet(ResultSet rs, String[] names, - SessionImplementor session, Object owner) - throws HibernateException, SQLException { - return get( rs, names[0] ); - } - - public void nullSafeSet(PreparedStatement st, Object value, int index, - boolean[] settable, SessionImplementor session) - throws HibernateException, SQLException { - if ( settable[0] ) set(st, value, index, session); - } - - public void nullSafeSet(PreparedStatement st, Object value, int index, - SessionImplementor session) throws HibernateException, SQLException { - set(st, value, index, session); - } - - public Object replace(Object original, Object target, - SessionImplementor session, Object owner, Map copyCache) - throws HibernateException { - //Blobs are ignored by merge() - return target; - } - - public int[] sqlTypes(Mapping mapping) throws MappingException { - return new int[] { Types.BLOB }; - } - - public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) { - throw new UnsupportedOperationException("todo"); - } - - public String toLoggableString(Object value, SessionFactoryImplementor factory) - throws HibernateException { - return value==null ? "null" : value.toString(); - } - - public boolean[] toColumnNullness(Object value, Mapping mapping) { - return value==null ? ArrayHelper.FALSE : ArrayHelper.TRUE; - } - public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException { - return checkable[0] && isDirty(old, current, session); + @Override + protected Blob getReplacement(Blob original, Blob target, SessionImplementor session) { + return session.getFactory().getDialect().getLobMergeStrategy().mergeBlob( original, target, session ); } } - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/BooleanType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/BooleanType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/BooleanType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/BooleanType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,63 +20,59 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; import org.hibernate.dialect.Dialect; +import org.hibernate.type.descriptor.java.BooleanTypeDescriptor; +import org.hibernate.type.descriptor.sql.SqlTypeDescriptor; /** - * boolean: A type that maps an SQL BIT to a Java Boolean. + * A type that maps between {@link java.sql.Types#BOOLEAN BOOLEAN} and {@link Boolean} + * * @author Gavin King + * @author Steve Ebersole */ -public class BooleanType extends PrimitiveType implements DiscriminatorType { +public class BooleanType + extends AbstractSingleColumnStandardBasicType + implements PrimitiveType, DiscriminatorType { + public static final BooleanType INSTANCE = new BooleanType(); - public Serializable getDefaultValue() { - return Boolean.FALSE; + public BooleanType() { + this( org.hibernate.type.descriptor.sql.BooleanTypeDescriptor.INSTANCE, BooleanTypeDescriptor.INSTANCE ); } - - public Object get(ResultSet rs, String name) throws SQLException { - return rs.getBoolean(name) ? Boolean.TRUE : Boolean.FALSE; - } - public Class getPrimitiveClass() { - return boolean.class; + protected BooleanType(SqlTypeDescriptor sqlTypeDescriptor, BooleanTypeDescriptor javaTypeDescriptor) { + super( sqlTypeDescriptor, javaTypeDescriptor ); } - - public Class getReturnedClass() { - return Boolean.class; + @Override + public String getName() { + return "boolean"; } - public void set(PreparedStatement st, Object value, int index) - throws SQLException { - st.setBoolean( index, ( (Boolean) value ).booleanValue() ); + @Override + public String[] getRegistrationKeys() { + return new String[] { getName(), boolean.class.getName(), Boolean.class.getName() }; } - - public int sqlType() { - return Types.BIT; + @Override + public Class getPrimitiveClass() { + return boolean.class; } - - public String getName() { return "boolean"; } - - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return dialect.toBooleanValueString( ( (Boolean) value ).booleanValue() ); + @Override + public Serializable getDefaultValue() { + return Boolean.FALSE; } - - public Object stringToObject(String xml) throws Exception { - return fromStringValue(xml); + @Override + public Boolean stringToObject(String string) { + return fromString( string ); } - public Object fromStringValue(String xml) { - return Boolean.valueOf(xml); + @Override + public String objectToSQLString(Boolean value, Dialect dialect) { + return dialect.toBooleanValueString( value ); } - } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/ByteArrayBlobType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/ByteType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/ByteType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/ByteType.java 17 Aug 2012 14:36:27 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/ByteType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,77 +20,73 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; import java.util.Comparator; -import org.hibernate.util.ComparableComparator; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.type.descriptor.java.ByteTypeDescriptor; +import org.hibernate.type.descriptor.sql.TinyIntTypeDescriptor; /** - * byte: A type that maps an SQL TINYINT to a Java Byte. + * A type that maps between {@link java.sql.Types#TINYINT TINYINT} and {@link Byte} + * * @author Gavin King + * @author Steve Ebersole */ -public class ByteType extends PrimitiveType implements DiscriminatorType, VersionType { +public class ByteType + extends AbstractSingleColumnStandardBasicType + implements PrimitiveType, DiscriminatorType, VersionType { - private static final Byte ZERO = new Byte( (byte) 0 ); + public static final ByteType INSTANCE = new ByteType(); - public Serializable getDefaultValue() { - return ZERO; - } - - public Object get(ResultSet rs, String name) throws SQLException { - return new Byte( rs.getByte(name) ); - } + private static final Byte ZERO = (byte) 0; - public Class getPrimitiveClass() { - return byte.class; + public ByteType() { + super( TinyIntTypeDescriptor.INSTANCE, ByteTypeDescriptor.INSTANCE ); } - - public Class getReturnedClass() { - return Byte.class; + @Override + public String getName() { + return "byte"; } - public void set(PreparedStatement st, Object value, int index) throws SQLException { - st.setByte( index, ( (Byte) value ).byteValue() ); + @Override + public String[] getRegistrationKeys() { + return new String[] { getName(), byte.class.getName(), Byte.class.getName() }; } - - public int sqlType() { - return Types.TINYINT; + @Override + public Serializable getDefaultValue() { + return ZERO; } - - public String getName() { return "byte"; } - - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return value.toString(); + @Override + public Class getPrimitiveClass() { + return byte.class; } - - public Object stringToObject(String xml) throws Exception { - return new Byte(xml); + @Override + public String objectToSQLString(Byte value, Dialect dialect) { + return toString( value ); } - - public Object fromStringValue(String xml) { - return new Byte(xml); + @Override + public Byte stringToObject(String xml) { + return fromString( xml ); } - - public Object next(Object current, SessionImplementor session) { - return new Byte( (byte) ( ( (Byte) current ).byteValue() + 1 ) ); + @Override + public Byte fromStringValue(String xml) { + return fromString( xml ); } - - public Object seed(SessionImplementor session) { + @Override + public Byte next(Byte current, SessionImplementor session) { + return (byte) ( current + 1 ); + } + @Override + public Byte seed(SessionImplementor session) { return ZERO; } - - public Comparator getComparator() { - return ComparableComparator.INSTANCE; + @Override + public Comparator getComparator() { + return getJavaTypeDescriptor().getComparator(); } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/CalendarDateType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/CalendarDateType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/CalendarDateType.java 17 Aug 2012 14:36:30 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/CalendarDateType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,97 +20,27 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; -import java.sql.Date; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; import java.util.Calendar; -import java.util.GregorianCalendar; -import org.hibernate.EntityMode; -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; -import org.hibernate.util.CalendarComparator; +import org.hibernate.type.descriptor.java.CalendarDateTypeDescriptor; +import org.hibernate.type.descriptor.sql.DateTypeDescriptor; /** - * calendar_date: A type mapping for a Calendar - * object that represents a date. + * A type mapping {@link java.sql.Types#DATE DATE} and {@link Calendar} + * * @author Gavin King + * @author Steve Ebersole */ -public class CalendarDateType extends MutableType { +public class CalendarDateType extends AbstractSingleColumnStandardBasicType { + public static final CalendarDateType INSTANCE = new CalendarDateType(); - public Object get(ResultSet rs, String name) throws HibernateException, SQLException { - - Date date = rs.getDate(name); - if (date!=null) { - Calendar cal = new GregorianCalendar(); - cal.setTime(date); - return cal; - } - else { - return null; - } - + public CalendarDateType() { + super( DateTypeDescriptor.INSTANCE, CalendarDateTypeDescriptor.INSTANCE ); } - public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { - final Calendar cal = (Calendar) value; - //st.setDate( index, new Date( cal.getTimeInMillis() ), cal ); //JDK 1.5 only - st.setDate( index, new Date( cal.getTime().getTime() ), cal ); - } - - public int sqlType() { - return Types.DATE; - } - - public String toString(Object value) throws HibernateException { - return Hibernate.DATE.toString( ( (Calendar) value ).getTime() ); - } - - public Object fromStringValue(String xml) throws HibernateException { - Calendar result = new GregorianCalendar(); - result.setTime( ( (java.util.Date) Hibernate.DATE.fromStringValue(xml) ) ); - return result; - } - - public Object deepCopyNotNull(Object value) { - return ( (Calendar) value ).clone(); - } - - public Class getReturnedClass() { - return Calendar.class; - } - - public int compare(Object x, Object y, EntityMode entityMode) { - return CalendarComparator.INSTANCE.compare(x, y); - } - - public boolean isEqual(Object x, Object y) { - if (x==y) return true; - if (x==null || y==null) return false; - - Calendar calendar1 = (Calendar) x; - Calendar calendar2 = (Calendar) y; - - return calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH) - && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH) - && calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR); - } - - public int getHashCode(Object x, EntityMode entityMode) { - Calendar calendar = (Calendar) x; - int hashCode = 1; - hashCode = 31 * hashCode + calendar.get(Calendar.DAY_OF_MONTH); - hashCode = 31 * hashCode + calendar.get(Calendar.MONTH); - hashCode = 31 * hashCode + calendar.get(Calendar.YEAR); - return hashCode; - } - public String getName() { return "calendar_date"; } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/CalendarTimeType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/CalendarType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/CalendarType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/CalendarType.java 17 Aug 2012 14:36:27 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/CalendarType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,128 +20,51 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.sql.Types; import java.util.Calendar; import java.util.Comparator; -import java.util.Date; import java.util.GregorianCalendar; -import org.hibernate.EntityMode; -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.cfg.Environment; -import org.hibernate.util.CalendarComparator; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.type.descriptor.java.CalendarTypeDescriptor; +import org.hibernate.type.descriptor.sql.TimestampTypeDescriptor; /** - * calendar: A type mapping for a Calendar object that - * represents a datetime. + * A type that maps between {@link java.sql.Types#TIMESTAMP TIMESTAMP} and {@link Calendar} + * * @author Gavin King + * @author Steve Ebersole */ -public class CalendarType extends MutableType implements VersionType { +public class CalendarType + extends AbstractSingleColumnStandardBasicType + implements VersionType { - public Object get(ResultSet rs, String name) throws HibernateException, SQLException { + public static final CalendarType INSTANCE = new CalendarType(); - Timestamp ts = rs.getTimestamp(name); - if (ts!=null) { - Calendar cal = new GregorianCalendar(); - if ( Environment.jvmHasTimestampBug() ) { - cal.setTime( new Date( ts.getTime() + ts.getNanos() / 1000000 ) ); - } - else { - cal.setTime(ts); - } - return cal; - } - else { - return null; - } - + public CalendarType() { + super( TimestampTypeDescriptor.INSTANCE, CalendarTypeDescriptor.INSTANCE ); } - public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { - final Calendar cal = (Calendar) value; - //st.setTimestamp( index, new Timestamp( cal.getTimeInMillis() ), cal ); //JDK 1.5 only - st.setTimestamp( index, new Timestamp( cal.getTime().getTime() ), cal ); - } - - public int sqlType() { - return Types.TIMESTAMP; - } - - public String toString(Object value) throws HibernateException { - return Hibernate.TIMESTAMP.toString( ( (Calendar) value ).getTime() ); - } - - public Object fromStringValue(String xml) throws HibernateException { - Calendar result = new GregorianCalendar(); - result.setTime( ( (Date) Hibernate.TIMESTAMP.fromStringValue(xml) ) ); - return result; - } - - public Object deepCopyNotNull(Object value) throws HibernateException { - return ( (Calendar) value ).clone(); - } - - public Class getReturnedClass() { - return Calendar.class; - } - - public int compare(Object x, Object y, EntityMode entityMode) { - return CalendarComparator.INSTANCE.compare(x, y); - } - - public boolean isEqual(Object x, Object y) { - if (x==y) return true; - if (x==null || y==null) return false; - - Calendar calendar1 = (Calendar) x; - Calendar calendar2 = (Calendar) y; - - return calendar1.get(Calendar.MILLISECOND) == calendar2.get(Calendar.MILLISECOND) - && calendar1.get(Calendar.SECOND) == calendar2.get(Calendar.SECOND) - && calendar1.get(Calendar.MINUTE) == calendar2.get(Calendar.MINUTE) - && calendar1.get(Calendar.HOUR_OF_DAY) == calendar2.get(Calendar.HOUR_OF_DAY) - && calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH) - && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH) - && calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR); - } - - public int getHashCode(Object x, EntityMode entityMode) { - Calendar calendar = (Calendar) x; - int hashCode = 1; - hashCode = 31 * hashCode + calendar.get(Calendar.MILLISECOND); - hashCode = 31 * hashCode + calendar.get(Calendar.SECOND); - hashCode = 31 * hashCode + calendar.get(Calendar.MINUTE); - hashCode = 31 * hashCode + calendar.get(Calendar.HOUR_OF_DAY); - hashCode = 31 * hashCode + calendar.get(Calendar.DAY_OF_MONTH); - hashCode = 31 * hashCode + calendar.get(Calendar.MONTH); - hashCode = 31 * hashCode + calendar.get(Calendar.YEAR); - return hashCode; - } - public String getName() { return "calendar"; } - public Object next(Object current, SessionImplementor session) { + @Override + public String[] getRegistrationKeys() { + return new String[] { getName(), Calendar.class.getName(), GregorianCalendar.class.getName() }; + } + + public Calendar next(Calendar current, SessionImplementor session) { return seed( session ); } - public Object seed(SessionImplementor session) { + public Calendar seed(SessionImplementor session) { return Calendar.getInstance(); } - public Comparator getComparator() { - return CalendarComparator.INSTANCE; + public Comparator getComparator() { + return getJavaTypeDescriptor().getComparator(); } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/CharArrayType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/CharArrayType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/CharArrayType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/CharArrayType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,27 +20,30 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; +import org.hibernate.type.descriptor.java.PrimitiveCharacterArrayTypeDescriptor; +import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor; /** - * put char[] into VARCHAR + * A type that maps between {@link java.sql.Types#VARCHAR VARCHAR} and {@code char[]} + * * @author Emmanuel Bernard + * @author Steve Ebersole */ -public class CharArrayType extends AbstractCharArrayType { +public class CharArrayType extends AbstractSingleColumnStandardBasicType { + public static final CharArrayType INSTANCE = new CharArrayType(); - protected Object toExternalFormat(char[] chars) { - return chars; + public CharArrayType() { + super( VarcharTypeDescriptor.INSTANCE, PrimitiveCharacterArrayTypeDescriptor.INSTANCE ); } - protected char[] toInternalFormat(Object chars) { - return (char[]) chars; + public String getName() { + return "characters"; } - public Class getReturnedClass() { - return char[].class; + @Override + public String[] getRegistrationKeys() { + return new String[] { getName(), "char[]", char[].class.getName() }; } - - public String getName() { return "characters"; } } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/CharBooleanType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/CharBooleanType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/CharBooleanType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/CharBooleanType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,74 +20,41 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; +import org.hibernate.type.descriptor.java.BooleanTypeDescriptor; +import org.hibernate.type.descriptor.sql.CharTypeDescriptor; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; - -import org.hibernate.HibernateException; -import org.hibernate.dialect.Dialect; - - /** * Superclass for types that map Java boolean to SQL CHAR(1). + * * @author Gavin King + * + * @deprecated Use the {@link AbstractStandardBasicType} approach instead */ public abstract class CharBooleanType extends BooleanType { + private final String stringValueTrue; + private final String stringValueFalse; - protected abstract String getTrueString(); - protected abstract String getFalseString(); + protected CharBooleanType(char characterValueTrue, char characterValueFalse) { + super( CharTypeDescriptor.INSTANCE, new BooleanTypeDescriptor( characterValueTrue, characterValueFalse ) ); - public Object get(ResultSet rs, String name) throws SQLException { - String code = rs.getString(name); - if ( code==null || code.length()==0 ) { - return null; - } - else { - return getTrueString().equalsIgnoreCase( code.trim() ) ? - Boolean.TRUE : Boolean.FALSE; - } + stringValueTrue = String.valueOf( characterValueTrue ); + stringValueFalse = String.valueOf( characterValueFalse ); } - public void set(PreparedStatement st, Object value, int index) - throws SQLException { - st.setString( index, toCharacter(value) ); - + /** + * @deprecated Pass the true/false values into constructor instead. + */ + protected final String getTrueString() { + return stringValueTrue; } - public int sqlType() { - return Types.CHAR; + /** + * @deprecated Pass the true/false values into constructor instead. + */ + protected final String getFalseString() { + return stringValueFalse; } - private String toCharacter(Object value) { - return ( (Boolean) value ).booleanValue() ? getTrueString() : getFalseString(); - } - - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return "'" + toCharacter(value) + "'"; - } - - public Object stringToObject(String xml) throws Exception { - if ( getTrueString().equalsIgnoreCase(xml) ) { - return Boolean.TRUE; - } - else if ( getFalseString().equalsIgnoreCase(xml) ) { - return Boolean.FALSE; - } - else { - throw new HibernateException("Could not interpret: " + xml); - } - } - } - - - - - - - Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/CharacterArrayClobType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/CharacterArrayNClobType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/CharacterArrayType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/CharacterArrayType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/CharacterArrayType.java 17 Aug 2012 14:36:30 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/CharacterArrayType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,41 +20,30 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; +import org.hibernate.type.descriptor.java.CharacterArrayTypeDescriptor; +import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor; -import org.hibernate.HibernateException; - /** - * Bridge Character[] and VARCHAR + * A type that maps between {@link java.sql.Types#VARCHAR VARCHAR} and {@link Character Character[]} + * * @author Emmanuel Bernard + * @author Steve Ebersole */ -public class CharacterArrayType extends AbstractCharArrayType { - protected Object toExternalFormat(char[] chars) { - if (chars == null) return null; - Character[] characters = new Character[chars.length]; - for (int i = 0 ; i < chars.length ; i++) { - characters[i] = new Character( chars[i] ); - } - return characters; - } +public class CharacterArrayType extends AbstractSingleColumnStandardBasicType { + public static final CharacterArrayType INSTANCE = new CharacterArrayType(); - protected char[] toInternalFormat(Object value) { - if (value == null) return null; - Character[] characters = (Character[]) value; - char[] chars = new char[characters.length]; - for (int i = 0 ; i < characters.length ; i++) { - if (characters[i] == null) - throw new HibernateException("Unable to store an Character[] when one of its element is null"); - chars[i] = characters[i].charValue(); - } - return chars; + public CharacterArrayType() { + super( VarcharTypeDescriptor.INSTANCE, CharacterArrayTypeDescriptor.INSTANCE ); } - public Class getReturnedClass() { - return Character[].class; + public String getName() { + return "wrapper-characters"; } - public String getName() { return "wrapper-characters"; } + @Override + public String[] getRegistrationKeys() { + return new String[] { getName(), Character[].class.getName(), "Character[]" }; + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/CharacterNCharType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/CharacterType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/CharacterType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/CharacterType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/CharacterType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,72 +20,54 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import org.hibernate.MappingException; import org.hibernate.dialect.Dialect; +import org.hibernate.type.descriptor.java.CharacterTypeDescriptor; +import org.hibernate.type.descriptor.sql.CharTypeDescriptor; /** - * character: A type that maps an SQL CHAR(1) to a Java Character. + * A type that maps between {@link java.sql.Types#CHAR CHAR(1)} and {@link Character} + * * @author Gavin King + * @author Steve Ebersole */ -public class CharacterType extends PrimitiveType implements DiscriminatorType { +public class CharacterType + extends AbstractSingleColumnStandardBasicType + implements PrimitiveType, DiscriminatorType { - public Serializable getDefaultValue() { - throw new UnsupportedOperationException("not a valid id type"); - } - - public Object get(ResultSet rs, String name) throws SQLException { - String str = rs.getString(name); - if (str==null) { - return null; - } - else { - return new Character( str.charAt(0) ); - } - } + public static final CharacterType INSTANCE = new CharacterType(); - public Class getPrimitiveClass() { - return char.class; + public CharacterType() { + super( CharTypeDescriptor.INSTANCE, CharacterTypeDescriptor.INSTANCE ); } - public Class getReturnedClass() { - return Character.class; + public String getName() { + return "character"; } - public void set(PreparedStatement st, Object value, int index) throws SQLException { - st.setString( index, (value).toString() ); + @Override + public String[] getRegistrationKeys() { + return new String[] { getName(), char.class.getName(), Character.class.getName() }; } - public int sqlType() { - return Types.CHAR; + public Serializable getDefaultValue() { + throw new UnsupportedOperationException( "not a valid id type" ); } - public String getName() { return "character"; } - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return '\'' + value.toString() + '\''; + public Class getPrimitiveClass() { + return char.class; } - public Object stringToObject(String xml) throws Exception { - if ( xml.length() != 1 ) throw new MappingException("multiple or zero characters found parsing string"); - return new Character( xml.charAt(0) ); + public String objectToSQLString(Character value, Dialect dialect) { + return '\'' + toString( value ) + '\''; } - public Object fromStringValue(String xml) { - return new Character( xml.charAt(0) ); + public Character stringToObject(String xml) { + return fromString( xml ); } } - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/ClassType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/ClassType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/ClassType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/ClassType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,73 +20,31 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; +import org.hibernate.type.descriptor.java.ClassTypeDescriptor; +import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; -import org.hibernate.util.ReflectHelper; - /** - * class: A type that maps an SQL VARCHAR to a Java Class. + * A type that maps between {@link java.sql.Types#VARCHAR VARCHAR} and {@link Class} + * * @author Gavin King + * @author Steve Ebersole */ -public class ClassType extends ImmutableType { +public class ClassType extends AbstractSingleColumnStandardBasicType { + public static final ClassType INSTANCE = new ClassType(); - public Object get(ResultSet rs, String name) throws HibernateException, SQLException { - String str = (String) Hibernate.STRING.get(rs, name); - if (str == null) { - return null; - } - else { - try { - return ReflectHelper.classForName(str); - } - catch (ClassNotFoundException cnfe) { - throw new HibernateException("Class not found: " + str); - } - } + public ClassType() { + super( VarcharTypeDescriptor.INSTANCE, ClassTypeDescriptor.INSTANCE ); } - public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { - //TODO: would be nice to handle proxy classes elegantly! - Hibernate.STRING.set(st, ( (Class) value ).getName(), index); - } - - public int sqlType() { - return Hibernate.STRING.sqlType(); - } - - public String toString(Object value) throws HibernateException { - return ( (Class) value ).getName(); - } - - public Class getReturnedClass() { - return Class.class; - } - public String getName() { return "class"; } - public Object fromStringValue(String xml) throws HibernateException { - try { - return ReflectHelper.classForName(xml); - } - catch (ClassNotFoundException cnfe) { - throw new HibernateException("could not parse xml", cnfe); - } + @Override + protected boolean registerUnderJavaType() { + return true; } } - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/ClobType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/ClobType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/ClobType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/ClobType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,173 +20,38 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; - -import java.io.Serializable; import java.sql.Clob; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import java.util.Map; -import org.dom4j.Node; -import org.hibernate.EntityMode; -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; -import org.hibernate.MappingException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.lob.ClobImpl; -import org.hibernate.lob.SerializableClob; -import org.hibernate.util.ArrayHelper; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.type.descriptor.java.ClobTypeDescriptor; /** - * clob: A type that maps an SQL CLOB to a java.sql.Clob. + * A type that maps between {@link java.sql.Types#CLOB CLOB} and {@link Clob} + * * @author Gavin King + * @author Steve Ebersole */ -public class ClobType extends AbstractType { +public class ClobType extends AbstractSingleColumnStandardBasicType { + public static final ClobType INSTANCE = new ClobType(); - public void set(PreparedStatement st, Object value, int index, SessionImplementor session) - throws HibernateException, SQLException { - - if (value==null) { - st.setNull(index, Types.CLOB); - } - else { - - if (value instanceof SerializableClob) { - value = ( (SerializableClob) value ).getWrappedClob(); - } - - final boolean useReader = session.getFactory().getDialect().useInputStreamToInsertBlob() && - (value instanceof ClobImpl); - - if ( useReader ) { - ClobImpl clob = (ClobImpl) value; - st.setCharacterStream( index, clob.getCharacterStream(), (int) clob.length() ); - } - else { - st.setClob(index, (Clob) value); - } - - } - + public ClobType() { + super( org.hibernate.type.descriptor.sql.ClobTypeDescriptor.DEFAULT, ClobTypeDescriptor.INSTANCE ); } - public Object get(ResultSet rs, String name) throws HibernateException, SQLException { - Clob value = rs.getClob(name); - return rs.wasNull() ? null : new SerializableClob(value); - } - - public Class getReturnedClass() { - return Clob.class; - } - - public boolean isEqual(Object x, Object y, EntityMode entityMode) { - return x == y; - } - - public int getHashCode(Object x, EntityMode entityMode) { - return System.identityHashCode(x); - } - - public int compare(Object x, Object y, EntityMode entityMode) { - return 0; //lobs cannot be compared - } - public String getName() { return "clob"; } - - public Serializable disassemble(Object value, SessionImplementor session, Object owner) - throws HibernateException { - throw new UnsupportedOperationException("Clobs are not cacheable"); - } - public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) { - return value; + @Override + protected boolean registerUnderJavaType() { + return true; } - - public Object fromXMLNode(Node xml, Mapping factory) { - return Hibernate.createClob( xml.getText() ); - } - - public int getColumnSpan(Mapping mapping) { - return 1; - } - - public boolean isMutable() { - return false; - } - - public Object nullSafeGet(ResultSet rs, String name, - SessionImplementor session, Object owner) - throws HibernateException, SQLException { - return get(rs, name); - } - - public Object nullSafeGet(ResultSet rs, String[] names, - SessionImplementor session, Object owner) - throws HibernateException, SQLException { - return get( rs, names[0] ); - } - - public void nullSafeSet(PreparedStatement st, Object value, int index, - boolean[] settable, SessionImplementor session) - throws HibernateException, SQLException { - if ( settable[0] ) set(st, value, index, session); - } - - public void nullSafeSet(PreparedStatement st, Object value, int index, - SessionImplementor session) throws HibernateException, SQLException { - set(st, value, index, session); - } - - public Object replace(Object original, Object target, - SessionImplementor session, Object owner, Map copyCache) - throws HibernateException { - //Clobs are ignored by merge() operation - return target; - } - - public int[] sqlTypes(Mapping mapping) throws MappingException { - return new int[] { Types.CLOB }; - } - - public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) { - if (value!=null) { - Clob clob = (Clob) value; - try { - int len = (int) clob.length(); - node.setText( clob.getSubString(0, len) ); - } - catch (SQLException sqle) { - throw new HibernateException("could not read XML from Clob", sqle); - } - } - } - - public String toLoggableString(Object value, SessionFactoryImplementor factory) - throws HibernateException { - return value==null ? "null" : value.toString(); - } - public boolean[] toColumnNullness(Object value, Mapping mapping) { - return value==null ? ArrayHelper.FALSE : ArrayHelper.TRUE; + @Override + protected Clob getReplacement(Clob original, Clob target, SessionImplementor session) { + return session.getFactory().getDialect().getLobMergeStrategy().mergeClob( original, target, session ); } - public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException { - return checkable[0] && isDirty(old, current, session); - } - } - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/CollectionType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/CollectionType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/CollectionType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/CollectionType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; @@ -30,53 +29,81 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; -import org.dom4j.Element; -import org.dom4j.Node; - import org.hibernate.EntityMode; import org.hibernate.Hibernate; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.collection.PersistentCollection; -import org.hibernate.engine.CollectionKey; -import org.hibernate.engine.EntityEntry; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.PersistenceContext; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.spi.CollectionEntry; +import org.hibernate.engine.spi.CollectionKey; +import org.hibernate.engine.spi.EntityEntry; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.PersistenceContext; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.MarkerObject; +import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.internal.util.collections.CollectionHelper; +import org.hibernate.metamodel.relational.Size; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.collection.QueryableCollection; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Joinable; +import org.hibernate.pretty.MessageHelper; import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.LazyInitializer; -import org.hibernate.util.ArrayHelper; -import org.hibernate.util.MarkerObject; +import org.jboss.logging.Logger; + +import org.dom4j.Element; +import org.dom4j.Node; + /** * A type that handles Hibernate PersistentCollections (including arrays). * * @author Gavin King */ public abstract class CollectionType extends AbstractType implements AssociationType { + private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, CollectionType.class.getName()); + private static final Object NOT_NULL_COLLECTION = new MarkerObject( "NOT NULL COLLECTION" ); public static final Object UNFETCHED_COLLECTION = new MarkerObject( "UNFETCHED COLLECTION" ); + private final TypeFactory.TypeScope typeScope; private final String role; private final String foreignKeyPropertyName; private final boolean isEmbeddedInXML; - public CollectionType(String role, String foreignKeyPropertyName, boolean isEmbeddedInXML) { + /** + * @deprecated Use {@link #CollectionType(TypeFactory.TypeScope, String, String)} instead + * See Jira issue: HHH-7771 + */ + @Deprecated + public CollectionType(TypeFactory.TypeScope typeScope, String role, String foreignKeyPropertyName, boolean isEmbeddedInXML) { + this.typeScope = typeScope; this.role = role; this.foreignKeyPropertyName = foreignKeyPropertyName; this.isEmbeddedInXML = isEmbeddedInXML; } - + + public CollectionType(TypeFactory.TypeScope typeScope, String role, String foreignKeyPropertyName) { + this.typeScope = typeScope; + this.role = role; + this.foreignKeyPropertyName = foreignKeyPropertyName; + this.isEmbeddedInXML = true; + } + + @Override public boolean isEmbeddedInXML() { return isEmbeddedInXML; } @@ -105,22 +132,26 @@ return false; } + @Override public boolean isCollectionType() { return true; } - public final boolean isEqual(Object x, Object y, EntityMode entityMode) { + @Override + public final boolean isEqual(Object x, Object y) { return x == y || ( x instanceof PersistentCollection && ( (PersistentCollection) x ).isWrapper( y ) ) || ( y instanceof PersistentCollection && ( (PersistentCollection) y ).isWrapper( x ) ); } - public int compare(Object x, Object y, EntityMode entityMode) { + @Override + public int compare(Object x, Object y) { return 0; // collections cannot be compared } - public int getHashCode(Object x, EntityMode entityMode) { - throw new UnsupportedOperationException( "cannot perform lookups on collections" ); + @Override + public int getHashCode(Object x) { + throw new UnsupportedOperationException( "cannot doAfterTransactionCompletion lookups on collections" ); } /** @@ -134,32 +165,49 @@ */ public abstract PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key); + @Override public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) throws SQLException { return nullSafeGet( rs, new String[] { name }, session, owner ); } + @Override public Object nullSafeGet(ResultSet rs, String[] name, SessionImplementor session, Object owner) throws HibernateException, SQLException { return resolve( null, session, owner ); } + @Override public final void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session) throws HibernateException, SQLException { //NOOP } + @Override public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException { } + @Override public int[] sqlTypes(Mapping session) throws MappingException { return ArrayHelper.EMPTY_INT_ARRAY; } + @Override + public Size[] dictatedSizes(Mapping mapping) throws MappingException { + return new Size[] { LEGACY_DICTATED_SIZE }; + } + + @Override + public Size[] defaultSizes(Mapping mapping) throws MappingException { + return new Size[] { LEGACY_DEFAULT_SIZE }; + } + + @Override public int getColumnSpan(Mapping session) throws MappingException { return 0; } + @Override public String toLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException { if ( value == null ) { @@ -173,29 +221,23 @@ } } - protected String renderLoggableString(Object value, SessionFactoryImplementor factory) - throws HibernateException { - if ( Element.class.isInstance( value ) ) { - // for DOM4J "collections" only - // TODO: it would be better if this was done at the higher level by Printer - return ( ( Element ) value ).asXML(); + protected String renderLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException { + final List list = new ArrayList(); + Type elemType = getElementType( factory ); + Iterator itr = getElementsIterator( value ); + while ( itr.hasNext() ) { + list.add( elemType.toLoggableString( itr.next(), factory ) ); } - else { - List list = new ArrayList(); - Type elemType = getElementType( factory ); - Iterator iter = getElementsIterator( value ); - while ( iter.hasNext() ) { - list.add( elemType.toLoggableString( iter.next(), factory ) ); - } - return list.toString(); - } + return list.toString(); } - public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) + @Override + public Object deepCopy(Object value, SessionFactoryImplementor factory) throws HibernateException { return value; } + @Override public String getName() { return getReturnedClass().getName() + '(' + getRole() + ')'; } @@ -208,22 +250,7 @@ * @return The iterator. */ public Iterator getElementsIterator(Object collection, SessionImplementor session) { - if ( session.getEntityMode()==EntityMode.DOM4J ) { - final SessionFactoryImplementor factory = session.getFactory(); - final CollectionPersister persister = factory.getCollectionPersister( getRole() ); - final Type elementType = persister.getElementType(); - - List elements = ( (Element) collection ).elements( persister.getElementNodeName() ); - ArrayList results = new ArrayList(); - for ( int i=0; iAssociationType. Not because * all collections are associations. */ + @Override public boolean isAssociationType() { return true; } + @Override public ForeignKeyDirection getForeignKeyDirection() { return ForeignKeyDirection.FOREIGN_KEY_TO_PARENT; } @@ -363,14 +397,14 @@ id = entityEntry.getLoadedValue( foreignKeyPropertyName ); } else { - id = entityEntry.getPersister().getPropertyValue( owner, foreignKeyPropertyName, session.getEntityMode() ); + id = entityEntry.getPersister().getPropertyValue( owner, foreignKeyPropertyName ); } // NOTE VERY HACKISH WORKAROUND!! // TODO: Fix this so it will work for non-POJO entity mode Type keyType = getPersister( session ).getKeyType(); if ( !keyType.getReturnedClass().isInstance( id ) ) { - id = (Serializable) keyType.semiResolve( + id = keyType.semiResolve( entityEntry.getLoadedValue( foreignKeyPropertyName ), session, owner @@ -399,11 +433,11 @@ Type keyType = getPersister( session ).getKeyType(); EntityPersister ownerPersister = getPersister( session ).getOwnerEntityPersister(); // TODO: Fix this so it will work for non-POJO entity mode - Class ownerMappedClass = ownerPersister.getMappedClass( session.getEntityMode() ); + Class ownerMappedClass = ownerPersister.getMappedClass(); if ( ownerMappedClass.isAssignableFrom( keyType.getReturnedClass() ) && keyType.getReturnedClass().isInstance( key ) ) { // the key is the owning entity itself, so get the ID from the key - ownerId = ownerPersister.getIdentifier( key, session.getEntityMode() ); + ownerId = ownerPersister.getIdentifier( key, session ); } else { // TODO: check if key contains the owner ID @@ -412,12 +446,14 @@ return ownerId; } + @Override public Object hydrate(ResultSet rs, String[] name, SessionImplementor session, Object owner) { // can't just return null here, since that would // cause an owning component to become null return NOT_NULL_COLLECTION; } + @Override public Object resolve(Object value, SessionImplementor session, Object owner) throws HibernateException { @@ -431,6 +467,7 @@ getCollection( key, session, owner ); } + @Override public Object semiResolve(Object value, SessionImplementor session, Object owner) throws HibernateException { throw new UnsupportedOperationException( @@ -441,23 +478,28 @@ return false; } + @Override public boolean useLHSPrimaryKey() { return foreignKeyPropertyName == null; } + @Override public String getRHSUniqueKeyPropertyName() { return null; } + @Override public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) throws MappingException { return (Joinable) factory.getCollectionPersister( role ); } + @Override public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException { return false; } + @Override public String getAssociatedEntityName(SessionFactoryImplementor factory) throws MappingException { try { @@ -516,15 +558,91 @@ // on the target because we simply do not know... if ( original instanceof PersistentCollection ) { if ( result instanceof PersistentCollection ) { - if ( ! ( ( PersistentCollection ) original ).isDirty() ) { - ( ( PersistentCollection ) result ).clearDirty(); + final PersistentCollection originalPersistentCollection = (PersistentCollection) original; + final PersistentCollection resultPersistentCollection = (PersistentCollection) result; + + preserveSnapshot( originalPersistentCollection, resultPersistentCollection, elemType, owner, copyCache, session ); + + if ( ! originalPersistentCollection.isDirty() ) { + resultPersistentCollection.clearDirty(); } } } return result; } + private void preserveSnapshot( + PersistentCollection original, + PersistentCollection result, + Type elemType, + Object owner, + Map copyCache, + SessionImplementor session) { + Serializable originalSnapshot = original.getStoredSnapshot(); + Serializable resultSnapshot = result.getStoredSnapshot(); + Serializable targetSnapshot; + + if ( originalSnapshot instanceof List ) { + targetSnapshot = new ArrayList( + ( (List) originalSnapshot ).size() ); + for ( Object obj : (List) originalSnapshot ) { + ( (List) targetSnapshot ).add( elemType.replace( obj, null, session, owner, copyCache ) ); + } + + } + else if ( originalSnapshot instanceof Map ) { + if ( originalSnapshot instanceof SortedMap ) { + targetSnapshot = new TreeMap( ( (SortedMap) originalSnapshot ).comparator() ); + } + else { + targetSnapshot = new HashMap( + CollectionHelper.determineProperSizing( ( (Map) originalSnapshot ).size() ), + CollectionHelper.LOAD_FACTOR + ); + } + + for ( Map.Entry entry : ( (Map) originalSnapshot ).entrySet() ) { + Object key = entry.getKey(); + Object value = entry.getValue(); + Object resultSnapshotValue = ( resultSnapshot == null ) + ? null + : ( (Map) resultSnapshot ).get( key ); + + Object newValue = elemType.replace( value, resultSnapshotValue, session, owner, copyCache ); + + if ( key == value ) { + ( (Map) targetSnapshot ).put( newValue, newValue ); + + } + else { + ( (Map) targetSnapshot ).put( key, newValue ); + } + + } + + } + else if ( originalSnapshot instanceof Object[] ) { + Object[] arr = (Object[]) originalSnapshot; + for ( int i = 0; i < arr.length; i++ ) { + arr[i] = elemType.replace( arr[i], null, session, owner, copyCache ); + } + targetSnapshot = originalSnapshot; + + } + else { + // retain the same snapshot + targetSnapshot = resultSnapshot; + + } + + CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( result ); + if ( ce != null ) { + ce.resetStoredSnapshot( result, targetSnapshot ); + } + + } + /** * Instantiate a new "underlying" collection exhibiting the same capacity * charactersitcs and the passed "original". @@ -549,9 +667,7 @@ */ public abstract Object instantiate(int anticipatedSize); - /** - * {@inheritDoc} - */ + @Override public Object replace( final Object original, final Object target, @@ -599,15 +715,26 @@ return factory.getCollectionPersister( getRole() ).getElementType(); } + @Override public String toString() { return getClass().getName() + '(' + getRole() + ')'; } + @Override public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters) throws MappingException { return getAssociatedJoinable( factory ).filterFragment( alias, enabledFilters ); } + @Override + public String getOnCondition( + String alias, + SessionFactoryImplementor factory, + Map enabledFilters, + Set treatAsDeclarations) { + return getAssociatedJoinable( factory ).filterFragment( alias, enabledFilters, treatAsDeclarations ); + } + /** * instantiate a collection wrapper (called when loading an object) * @@ -620,12 +747,8 @@ CollectionPersister persister = getPersister( session ); final PersistenceContext persistenceContext = session.getPersistenceContext(); - final EntityMode entityMode = session.getEntityMode(); + final EntityMode entityMode = persister.getOwnerEntityPersister().getEntityMode(); - if (entityMode==EntityMode.DOM4J && !isEmbeddedInXML) { - return UNFETCHED_COLLECTION; - } - // check if collection is currently being loaded PersistentCollection collection = persistenceContext.getLoadContexts().locateLoadingCollection( persister, key ); @@ -637,53 +760,64 @@ if ( collection == null ) { // create a new collection wrapper, to be initialized later collection = instantiate( session, persister, key ); + collection.setOwner(owner); persistenceContext.addUninitializedCollection( persister, collection, key ); // some collections are not lazy: - if ( initializeImmediately( entityMode ) ) { + if ( initializeImmediately() ) { session.initializeCollection( collection, false ); } else if ( !persister.isLazy() ) { persistenceContext.addNonLazyCollection( collection ); } - if ( hasHolder( entityMode ) ) { + if ( hasHolder() ) { session.getPersistenceContext().addCollectionHolder( collection ); } } + if ( LOG.isTraceEnabled() ) { + LOG.tracef( "Created collection wrapper: %s", + MessageHelper.collectionInfoString( persister, collection, + key, session ) ); + } + } collection.setOwner(owner); return collection.getValue(); } - public boolean hasHolder(EntityMode entityMode) { - return entityMode == EntityMode.DOM4J; + public boolean hasHolder() { + return false; } - protected boolean initializeImmediately(EntityMode entityMode) { - return entityMode == EntityMode.DOM4J; + protected boolean initializeImmediately() { + return false; } + @Override public String getLHSPropertyName() { return foreignKeyPropertyName; } + @Override public boolean isXMLElement() { return true; } + @Override public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException { return xml; } - public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) - throws HibernateException { + @Override + public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) + throws HibernateException { if ( !isEmbeddedInXML ) { node.detach(); } @@ -697,10 +831,12 @@ * need to incremement version number of owner and also because of * how assemble/disassemble is implemented for uks */ + @Override public boolean isAlwaysDirtyChecked() { return true; } + @Override public boolean[] toColumnNullness(Object value, Mapping mapping) { return ArrayHelper.EMPTY_BOOLEAN_ARRAY; } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/ComponentType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/ComponentType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/ComponentType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/ComponentType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,53 +20,59 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; import java.lang.reflect.Method; +import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; -import org.dom4j.Element; -import org.dom4j.Node; import org.hibernate.EntityMode; import org.hibernate.FetchMode; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.engine.CascadeStyle; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.tuple.component.ComponentTuplizer; -import org.hibernate.tuple.component.ComponentMetamodel; +import org.hibernate.PropertyNotFoundException; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.util.StringHelper; +import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.metamodel.relational.Size; import org.hibernate.tuple.StandardProperty; -import org.hibernate.tuple.EntityModeToTuplizerMapping; -import org.hibernate.util.ArrayHelper; -import org.hibernate.util.StringHelper; +import org.hibernate.tuple.component.ComponentMetamodel; +import org.hibernate.tuple.component.ComponentTuplizer; +import org.dom4j.Element; +import org.dom4j.Node; + /** * Handles "component" mappings * * @author Gavin King */ -public class ComponentType extends AbstractType implements AbstractComponentType { +public class ComponentType extends AbstractType implements CompositeType, ProcedureParameterExtractionAware { + private final TypeFactory.TypeScope typeScope; private final String[] propertyNames; private final Type[] propertyTypes; private final boolean[] propertyNullability; protected final int propertySpan; private final CascadeStyle[] cascade; private final FetchMode[] joinedFetch; private final boolean isKey; + private boolean hasNotNullProperty; - protected final EntityModeToTuplizerMapping tuplizerMapping; + protected final EntityMode entityMode; + protected final ComponentTuplizer componentTuplizer; - public ComponentType(ComponentMetamodel metamodel) { + public ComponentType(TypeFactory.TypeScope typeScope, ComponentMetamodel metamodel) { + this.typeScope = typeScope; // for now, just "re-flatten" the metamodel since this is temporary stuff anyway (HHH-1907) this.isKey = metamodel.isKey(); this.propertySpan = metamodel.getPropertySpan(); @@ -83,41 +89,86 @@ this.propertyNullability[i] = prop.isNullable(); this.cascade[i] = prop.getCascadeStyle(); this.joinedFetch[i] = prop.getFetchMode(); + if (!prop.isNullable()) { + hasNotNullProperty = true; + } } - this.tuplizerMapping = metamodel.getTuplizerMapping(); + this.entityMode = metamodel.getEntityMode(); + this.componentTuplizer = metamodel.getComponentTuplizer(); } + public boolean isKey() { + return isKey; + } + + public EntityMode getEntityMode() { + return entityMode; + } + + public ComponentTuplizer getComponentTuplizer() { + return componentTuplizer; + } + @Override + public int getColumnSpan(Mapping mapping) throws MappingException { + int span = 0; + for ( int i = 0; i < propertySpan; i++ ) { + span += propertyTypes[i].getColumnSpan( mapping ); + } + return span; + } + @Override public int[] sqlTypes(Mapping mapping) throws MappingException { //Not called at runtime so doesn't matter if its slow :) int[] sqlTypes = new int[getColumnSpan( mapping )]; int n = 0; for ( int i = 0; i < propertySpan; i++ ) { int[] subtypes = propertyTypes[i].sqlTypes( mapping ); - for ( int j = 0; j < subtypes.length; j++ ) { - sqlTypes[n++] = subtypes[j]; + for ( int subtype : subtypes ) { + sqlTypes[n++] = subtype; } } return sqlTypes; } - public int getColumnSpan(Mapping mapping) throws MappingException { - int span = 0; - for ( int i = 0; i < propertySpan; i++ ) { - span += propertyTypes[i].getColumnSpan( mapping ); + @Override + public Size[] dictatedSizes(Mapping mapping) throws MappingException { + //Not called at runtime so doesn't matter if its slow :) + final Size[] sizes = new Size[ getColumnSpan( mapping ) ]; + int soFar = 0; + for ( Type propertyType : propertyTypes ) { + final Size[] propertySizes = propertyType.dictatedSizes( mapping ); + System.arraycopy( propertySizes, 0, sizes, soFar, propertySizes.length ); + soFar += propertySizes.length; } - return span; + return sizes; } - public final boolean isComponentType() { + @Override + public Size[] defaultSizes(Mapping mapping) throws MappingException { + //Not called at runtime so doesn't matter if its slow :) + final Size[] sizes = new Size[ getColumnSpan( mapping ) ]; + int soFar = 0; + for ( Type propertyType : propertyTypes ) { + final Size[] propertySizes = propertyType.defaultSizes( mapping ); + System.arraycopy( propertySizes, 0, sizes, soFar, propertySizes.length ); + soFar += propertySizes.length; + } + return sizes; + } + + + @Override + public final boolean isComponentType() { return true; } public Class getReturnedClass() { - return tuplizerMapping.getTuplizer( EntityMode.POJO ).getMappedClass(); //TODO + return componentTuplizer.getMappedClass(); } - public boolean isSame(Object x, Object y, EntityMode entityMode) throws HibernateException { + @Override + public boolean isSame(Object x, Object y) throws HibernateException { if ( x == y ) { return true; } @@ -127,57 +178,52 @@ Object[] xvalues = getPropertyValues( x, entityMode ); Object[] yvalues = getPropertyValues( y, entityMode ); for ( int i = 0; i < propertySpan; i++ ) { - if ( !propertyTypes[i].isSame( xvalues[i], yvalues[i], entityMode ) ) { + if ( !propertyTypes[i].isSame( xvalues[i], yvalues[i] ) ) { return false; } } return true; } - public boolean isEqual(Object x, Object y, EntityMode entityMode) - throws HibernateException { + @Override + public boolean isEqual(final Object x, final Object y) throws HibernateException { if ( x == y ) { return true; } if ( x == null || y == null ) { return false; } - Object[] xvalues = getPropertyValues( x, entityMode ); - Object[] yvalues = getPropertyValues( y, entityMode ); for ( int i = 0; i < propertySpan; i++ ) { - if ( !propertyTypes[i].isEqual( xvalues[i], yvalues[i], entityMode ) ) { + if ( !propertyTypes[i].isEqual( getPropertyValue( x, i ), getPropertyValue( y, i ) ) ) { return false; } } return true; } - public boolean isEqual(Object x, Object y, EntityMode entityMode, SessionFactoryImplementor factory) - throws HibernateException { + @Override + public boolean isEqual(final Object x, final Object y, final SessionFactoryImplementor factory) throws HibernateException { if ( x == y ) { return true; } if ( x == null || y == null ) { return false; } - Object[] xvalues = getPropertyValues( x, entityMode ); - Object[] yvalues = getPropertyValues( y, entityMode ); for ( int i = 0; i < propertySpan; i++ ) { - if ( !propertyTypes[i].isEqual( xvalues[i], yvalues[i], entityMode, factory ) ) { + if ( !propertyTypes[i].isEqual( getPropertyValue( x, i ), getPropertyValue( y, i ), factory ) ) { return false; } } return true; } - public int compare(Object x, Object y, EntityMode entityMode) { + @Override + public int compare(final Object x, final Object y) { if ( x == y ) { return 0; } - Object[] xvalues = getPropertyValues( x, entityMode ); - Object[] yvalues = getPropertyValues( y, entityMode ); for ( int i = 0; i < propertySpan; i++ ) { - int propertyCompare = propertyTypes[i].compare( xvalues[i], yvalues[i], entityMode ); + int propertyCompare = propertyTypes[i].compare( getPropertyValue( x, i ), getPropertyValue( y, i ) ); if ( propertyCompare != 0 ) { return propertyCompare; } @@ -189,76 +235,69 @@ return false; } - public int getHashCode(Object x, EntityMode entityMode) { + @Override + public int getHashCode(final Object x) { int result = 17; - Object[] values = getPropertyValues( x, entityMode ); for ( int i = 0; i < propertySpan; i++ ) { - Object y = values[i]; + Object y = getPropertyValue( x, i ); result *= 37; if ( y != null ) { - result += propertyTypes[i].getHashCode( y, entityMode ); + result += propertyTypes[i].getHashCode( y ); } } return result; } - public int getHashCode(Object x, EntityMode entityMode, SessionFactoryImplementor factory) { + @Override + public int getHashCode(final Object x, final SessionFactoryImplementor factory) { int result = 17; - Object[] values = getPropertyValues( x, entityMode ); for ( int i = 0; i < propertySpan; i++ ) { - Object y = values[i]; + Object y = getPropertyValue( x, i ); result *= 37; if ( y != null ) { - result += propertyTypes[i].getHashCode( y, entityMode, factory ); + result += propertyTypes[i].getHashCode( y, factory ); } } return result; } - public boolean isDirty(Object x, Object y, SessionImplementor session) - throws HibernateException { + @Override + public boolean isDirty(final Object x, final Object y, final SessionImplementor session) throws HibernateException { if ( x == y ) { return false; } if ( x == null || y == null ) { return true; } - EntityMode entityMode = session.getEntityMode(); - Object[] xvalues = getPropertyValues( x, entityMode ); - Object[] yvalues = getPropertyValues( y, entityMode ); - for ( int i = 0; i < xvalues.length; i++ ) { - if ( propertyTypes[i].isDirty( xvalues[i], yvalues[i], session ) ) { + for ( int i = 0; i < propertySpan; i++ ) { + if ( propertyTypes[i].isDirty( getPropertyValue( x, i ), getPropertyValue( y, i ), session ) ) { return true; } } return false; } - public boolean isDirty(Object x, Object y, boolean[] checkable, SessionImplementor session) - throws HibernateException { + public boolean isDirty(final Object x, final Object y, final boolean[] checkable, final SessionImplementor session) throws HibernateException { if ( x == y ) { return false; } if ( x == null || y == null ) { return true; } - EntityMode entityMode = session.getEntityMode(); - Object[] xvalues = getPropertyValues( x, entityMode ); - Object[] yvalues = getPropertyValues( y, entityMode ); int loc = 0; - for ( int i = 0; i < xvalues.length; i++ ) { + for ( int i = 0; i < propertySpan; i++ ) { int len = propertyTypes[i].getColumnSpan( session.getFactory() ); if ( len <= 1 ) { final boolean dirty = ( len == 0 || checkable[loc] ) && - propertyTypes[i].isDirty( xvalues[i], yvalues[i], session ); + propertyTypes[i].isDirty( getPropertyValue( x, i ), getPropertyValue( y, i ), session ); if ( dirty ) { return true; } } else { boolean[] subcheckable = new boolean[len]; System.arraycopy( checkable, loc, subcheckable, 0, len ); - final boolean dirty = propertyTypes[i].isDirty( xvalues[i], yvalues[i], subcheckable, session ); + final boolean dirty = propertyTypes[i].isDirty( getPropertyValue( x, i ), getPropertyValue( y, i ), subcheckable, session ); if ( dirty ) { return true; } @@ -268,47 +307,45 @@ return false; } - public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session) - throws HibernateException { - + @Override + public boolean isModified(final Object old, final Object current, final boolean[] checkable, final SessionImplementor session) throws HibernateException { if ( current == null ) { return old != null; } if ( old == null ) { - return current != null; + return true; } - Object[] currentValues = getPropertyValues( current, session ); Object[] oldValues = ( Object[] ) old; int loc = 0; - for ( int i = 0; i < currentValues.length; i++ ) { + for ( int i = 0; i < propertySpan; i++ ) { int len = propertyTypes[i].getColumnSpan( session.getFactory() ); boolean[] subcheckable = new boolean[len]; System.arraycopy( checkable, loc, subcheckable, 0, len ); - if ( propertyTypes[i].isModified( oldValues[i], currentValues[i], subcheckable, session ) ) { + if ( propertyTypes[i].isModified( oldValues[i], getPropertyValue( current, i ), subcheckable, session ) ) { return true; } loc += len; } return false; } - + @Override public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException { return resolve( hydrate( rs, names, session, owner ), session, owner ); } - + @Override public void nullSafeSet(PreparedStatement st, Object value, int begin, SessionImplementor session) throws HibernateException, SQLException { - Object[] subvalues = nullSafeGetValues( value, session.getEntityMode() ); + Object[] subvalues = nullSafeGetValues( value, entityMode ); for ( int i = 0; i < propertySpan; i++ ) { propertyTypes[i].nullSafeSet( st, subvalues[i], begin, session ); begin += propertyTypes[i].getColumnSpan( session.getFactory() ); } } - + @Override public void nullSafeSet( PreparedStatement st, Object value, @@ -317,7 +354,7 @@ SessionImplementor session) throws HibernateException, SQLException { - Object[] subvalues = nullSafeGetValues( value, session.getEntityMode() ); + Object[] subvalues = nullSafeGetValues( value, entityMode ); int loc = 0; for ( int i = 0; i < propertySpan; i++ ) { @@ -349,91 +386,111 @@ return getPropertyValues( value, entityMode ); } } - + @Override public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) throws HibernateException, SQLException { return nullSafeGet( rs, new String[] {name}, session, owner ); } - + @Override public Object getPropertyValue(Object component, int i, SessionImplementor session) throws HibernateException { - return getPropertyValue( component, i, session.getEntityMode() ); + return getPropertyValue( component, i ); } - public Object getPropertyValue(Object component, int i, EntityMode entityMode) throws HibernateException { - return tuplizerMapping.getTuplizer( entityMode ).getPropertyValue( component, i ); + return getPropertyValue( component, i ); } - public Object[] getPropertyValues(Object component, SessionImplementor session) + public Object getPropertyValue(Object component, int i) throws HibernateException { - return getPropertyValues( component, session.getEntityMode() ); + if ( component instanceof Object[] ) { + // A few calls to hashCode pass the property values already in an + // Object[] (ex: QueryKey hash codes for cached queries). + // It's easiest to just check for the condition here prior to + // trying reflection. + return (( Object[] ) component)[i]; + } else { + return componentTuplizer.getPropertyValue( component, i ); + } } + @Override + public Object[] getPropertyValues(Object component, SessionImplementor session) + throws HibernateException { + return getPropertyValues( component, entityMode ); + } + @Override public Object[] getPropertyValues(Object component, EntityMode entityMode) throws HibernateException { - return tuplizerMapping.getTuplizer( entityMode ).getPropertyValues( component ); + if ( component instanceof Object[] ) { + // A few calls to hashCode pass the property values already in an + // Object[] (ex: QueryKey hash codes for cached queries). + // It's easiest to just check for the condition here prior to + // trying reflection. + return ( Object[] ) component; + } else { + return componentTuplizer.getPropertyValues( component ); + } } - + @Override public void setPropertyValues(Object component, Object[] values, EntityMode entityMode) throws HibernateException { - tuplizerMapping.getTuplizer( entityMode ).setPropertyValues( component, values ); + componentTuplizer.setPropertyValues( component, values ); } - + @Override public Type[] getSubtypes() { return propertyTypes; } - + @Override public String getName() { return "component" + ArrayHelper.toString( propertyNames ); } - + @Override public String toLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException { if ( value == null ) { return "null"; } - Map result = new HashMap(); - EntityMode entityMode = tuplizerMapping.guessEntityMode( value ); + if ( entityMode == null ) { throw new ClassCastException( value.getClass().getName() ); } + Map result = new HashMap(); Object[] values = getPropertyValues( value, entityMode ); for ( int i = 0; i < propertyTypes.length; i++ ) { result.put( propertyNames[i], propertyTypes[i].toLoggableString( values[i], factory ) ); } return StringHelper.unqualify( getName() ) + result.toString(); } - + @Override public String[] getPropertyNames() { return propertyNames; } - - public Object deepCopy(Object component, EntityMode entityMode, SessionFactoryImplementor factory) + @Override + public Object deepCopy(Object component, SessionFactoryImplementor factory) throws HibernateException { if ( component == null ) { return null; } Object[] values = getPropertyValues( component, entityMode ); for ( int i = 0; i < propertySpan; i++ ) { - values[i] = propertyTypes[i].deepCopy( values[i], entityMode, factory ); + values[i] = propertyTypes[i].deepCopy( values[i], factory ); } Object result = instantiate( entityMode ); setPropertyValues( result, values, entityMode ); //not absolutely necessary, but helps for some //equals()/hashCode() implementations - ComponentTuplizer ct = ( ComponentTuplizer ) tuplizerMapping.getTuplizer( entityMode ); - if ( ct.hasParentProperty() ) { - ct.setParent( result, ct.getParent( component ), factory ); + if ( componentTuplizer.hasParentProperty() ) { + componentTuplizer.setParent( result, componentTuplizer.getParent( component ), factory ); } return result; } - + @Override public Object replace( Object original, Object target, @@ -451,8 +508,7 @@ ? instantiate( owner, session ) : target; - final EntityMode entityMode = session.getEntityMode(); - Object[] values = TypeFactory.replace( + Object[] values = TypeHelper.replace( getPropertyValues( original, entityMode ), getPropertyValues( result, entityMode ), propertyTypes, @@ -465,7 +521,8 @@ return result; } - public Object replace( + @Override + public Object replace( Object original, Object target, SessionImplementor session, @@ -483,8 +540,7 @@ instantiate( owner, session ) : target; - final EntityMode entityMode = session.getEntityMode(); - Object[] values = TypeFactory.replace( + Object[] values = TypeHelper.replace( getPropertyValues( original, entityMode ), getPropertyValues( result, entityMode ), propertyTypes, @@ -502,17 +558,16 @@ * This method does not populate the component parent */ public Object instantiate(EntityMode entityMode) throws HibernateException { - return tuplizerMapping.getTuplizer( entityMode ).instantiate(); + return componentTuplizer.instantiate(); } public Object instantiate(Object parent, SessionImplementor session) throws HibernateException { - Object result = instantiate( session.getEntityMode() ); + Object result = instantiate( entityMode ); - ComponentTuplizer ct = ( ComponentTuplizer ) tuplizerMapping.getTuplizer( session.getEntityMode() ); - if ( ct.hasParentProperty() && parent != null ) { - ct.setParent( + if ( componentTuplizer.hasParentProperty() && parent != null ) { + componentTuplizer.setParent( result, session.getPersistenceContext().proxyFor( parent ), session.getFactory() @@ -521,31 +576,33 @@ return result; } - + @Override public CascadeStyle getCascadeStyle(int i) { return cascade[i]; } - + @Override public boolean isMutable() { return true; } - public Serializable disassemble(Object value, SessionImplementor session, Object owner) + @Override + public Serializable disassemble(Object value, SessionImplementor session, Object owner) throws HibernateException { if ( value == null ) { return null; } else { - Object[] values = getPropertyValues( value, session.getEntityMode() ); + Object[] values = getPropertyValues( value, entityMode ); for ( int i = 0; i < propertyTypes.length; i++ ) { values[i] = propertyTypes[i].disassemble( values[i], session, owner ); } return values; } } - public Object assemble(Serializable object, SessionImplementor session, Object owner) + @Override + public Object assemble(Serializable object, SessionImplementor session, Object owner) throws HibernateException { if ( object == null ) { @@ -558,16 +615,17 @@ assembled[i] = propertyTypes[i].assemble( ( Serializable ) values[i], session, owner ); } Object result = instantiate( owner, session ); - setPropertyValues( result, assembled, session.getEntityMode() ); + setPropertyValues( result, assembled, entityMode ); return result; } } - + @Override public FetchMode getFetchMode(int i) { return joinedFetch[i]; } - public Object hydrate( + @Override + public Object hydrate( final ResultSet rs, final String[] names, final SessionImplementor session, @@ -596,7 +654,8 @@ return notNull ? values : null; } - public Object resolve(Object value, SessionImplementor session, Object owner) + @Override + public Object resolve(Object value, SessionImplementor session, Object owner) throws HibernateException { if ( value != null ) { @@ -606,37 +665,39 @@ for ( int i = 0; i < values.length; i++ ) { resolvedValues[i] = propertyTypes[i].resolve( values[i], session, owner ); } - setPropertyValues( result, resolvedValues, session.getEntityMode() ); + setPropertyValues( result, resolvedValues, entityMode ); return result; } else { return null; } } - public Object semiResolve(Object value, SessionImplementor session, Object owner) + @Override + public Object semiResolve(Object value, SessionImplementor session, Object owner) throws HibernateException { //note that this implementation is kinda broken //for components with many-to-one associations return resolve( value, session, owner ); } - + @Override public boolean[] getPropertyNullability() { return propertyNullability; } - public boolean isXMLElement() { + @Override + public boolean isXMLElement() { return true; } - + @Override public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException { return xml; } - + @Override public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) throws HibernateException { replaceNode( node, ( Element ) value ); } - + @Override public boolean[] toColumnNullness(Object value, Mapping mapping) { boolean[] result = new boolean[ getColumnSpan( mapping ) ]; if ( value == null ) { @@ -651,9 +712,105 @@ } return result; } - + @Override public boolean isEmbedded() { return false; } + public int getPropertyIndex(String name) { + String[] names = getPropertyNames(); + for ( int i = 0, max = names.length; i < max; i++ ) { + if ( names[i].equals( name ) ) { + return i; + } + } + throw new PropertyNotFoundException( + "Unable to locate property named " + name + " on " + getReturnedClass().getName() + ); + } + + private Boolean canDoExtraction; + + @Override + public boolean canDoExtraction() { + if ( canDoExtraction == null ) { + canDoExtraction = determineIfProcedureParamExtractionCanBePerformed(); + } + return canDoExtraction; + } + + private boolean determineIfProcedureParamExtractionCanBePerformed() { + for ( Type propertyType : propertyTypes ) { + if ( ! ProcedureParameterExtractionAware.class.isInstance( propertyType ) ) { + return false; + } + if ( ! ( (ProcedureParameterExtractionAware) propertyType ).canDoExtraction() ) { + return false; + } + } + return true; + } + + @Override + public Object extract(CallableStatement statement, int startIndex, SessionImplementor session) throws SQLException { + Object[] values = new Object[propertySpan]; + + int currentIndex = startIndex; + boolean notNull = false; + for ( int i = 0; i < propertySpan; i++ ) { + // we know this cast is safe from canDoExtraction + final ProcedureParameterExtractionAware propertyType = (ProcedureParameterExtractionAware) propertyTypes[i]; + final Object value = propertyType.extract( statement, currentIndex, session ); + if ( value == null ) { + if ( isKey ) { + return null; //different nullability rules for pk/fk + } + } + else { + notNull = true; + } + values[i] = value; + currentIndex += propertyType.getColumnSpan( session.getFactory() ); + } + + if ( ! notNull ) { + values = null; + } + + return resolve( values, session, null ); + } + + @Override + public Object extract(CallableStatement statement, String[] paramNames, SessionImplementor session) throws SQLException { + // for this form to work all sub-property spans must be one (1)... + + Object[] values = new Object[propertySpan]; + + int indx = 0; + boolean notNull = false; + for ( String paramName : paramNames ) { + // we know this cast is safe from canDoExtraction + final ProcedureParameterExtractionAware propertyType = (ProcedureParameterExtractionAware) propertyTypes[indx]; + final Object value = propertyType.extract( statement, new String[] { paramName }, session ); + if ( value == null ) { + if ( isKey ) { + return null; //different nullability rules for pk/fk + } + } + else { + notNull = true; + } + values[indx] = value; + } + + if ( ! notNull ) { + values = null; + } + + return resolve( values, session, null ); + } + + public boolean hasNotNullProperty() { + return hasNotNullProperty; + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/CompositeCustomType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/CompositeCustomType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/CompositeCustomType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/CompositeCustomType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; @@ -30,59 +29,55 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map; -import java.util.Properties; -import org.dom4j.Element; -import org.dom4j.Node; import org.hibernate.EntityMode; import org.hibernate.FetchMode; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.engine.CascadeStyle; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.CascadeStyle; +import org.hibernate.engine.spi.CascadeStyles; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.metamodel.relational.Size; import org.hibernate.usertype.CompositeUserType; +import org.hibernate.usertype.LoggableUserType; +import org.dom4j.Element; +import org.dom4j.Node; + /** - * Adapts CompositeUserType to Type interface + * Adapts {@link CompositeUserType} to the {@link Type} interface + * * @author Gavin King + * @author Steve Ebersole */ -public class CompositeCustomType extends AbstractType - implements AbstractComponentType { - +public class CompositeCustomType extends AbstractType implements CompositeType, BasicType { private final CompositeUserType userType; + private final String[] registrationKeys; private final String name; + private final boolean customLogging; - public CompositeCustomType(Class userTypeClass, Properties parameters) - throws MappingException { - name = userTypeClass.getName(); + public CompositeCustomType(CompositeUserType userType) { + this( userType, ArrayHelper.EMPTY_STRING_ARRAY ); + } - if ( !CompositeUserType.class.isAssignableFrom(userTypeClass) ) { - throw new MappingException( - "Custom type does not implement CompositeUserType: " + - userTypeClass.getName() - ); - } - - try { - userType = (CompositeUserType) userTypeClass.newInstance(); - } - catch (InstantiationException ie) { - throw new MappingException( - "Cannot instantiate custom type: " + - userTypeClass.getName() - ); - } - catch (IllegalAccessException iae) { - throw new MappingException( - "IllegalAccessException trying to instantiate custom type: " + - userTypeClass.getName() - ); - } - TypeFactory.injectParameters(userType, parameters); + public CompositeCustomType(CompositeUserType userType, String[] registrationKeys) { + this.userType = userType; + this.name = userType.getClass().getName(); + this.customLogging = LoggableUserType.class.isInstance( userType ); + this.registrationKeys = registrationKeys; } - + + public String[] getRegistrationKeys() { + return registrationKeys; + } + + public CompositeUserType getUserType() { + return userType; + } + public boolean isMethodOf(Method method) { return false; } @@ -95,13 +90,11 @@ return userType.getPropertyNames(); } - public Object[] getPropertyValues(Object component, SessionImplementor session) - throws HibernateException { - return getPropertyValues( component, session.getEntityMode() ); + public Object[] getPropertyValues(Object component, SessionImplementor session) throws HibernateException { + return getPropertyValues( component, EntityMode.POJO ); } - public Object[] getPropertyValues(Object component, EntityMode entityMode) - throws HibernateException { + public Object[] getPropertyValues(Object component, EntityMode entityMode) throws HibernateException { int len = getSubtypes().length; Object[] result = new Object[len]; @@ -124,13 +117,12 @@ return getPropertyValue(component, i); } - public Object getPropertyValue(Object component, int i) - throws HibernateException { - return userType.getPropertyValue(component, i); + public Object getPropertyValue(Object component, int i) throws HibernateException { + return userType.getPropertyValue( component, i ); } public CascadeStyle getCascadeStyle(int i) { - return CascadeStyle.NONE; + return CascadeStyles.NONE; } public FetchMode getFetchMode(int i) { @@ -141,9 +133,9 @@ return true; } - public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) + public Object deepCopy(Object value, SessionFactoryImplementor factory) throws HibernateException { - return userType.deepCopy(value); + return userType.deepCopy( value ); } public Object assemble( @@ -152,14 +144,14 @@ Object owner) throws HibernateException { - return userType.assemble(cached, session, owner); + return userType.assemble( cached, session, owner ); } public Serializable disassemble(Object value, SessionImplementor session, Object owner) throws HibernateException { return userType.disassemble(value, session); } - + public Object replace( Object original, Object target, @@ -170,20 +162,20 @@ return userType.replace(original, target, session, owner); } - public boolean isEqual(Object x, Object y, EntityMode entityMode) + public boolean isEqual(Object x, Object y) throws HibernateException { return userType.equals(x, y); } - public int getHashCode(Object x, EntityMode entityMode) { + public int getHashCode(Object x) { return userType.hashCode(x); } public int getColumnSpan(Mapping mapping) throws MappingException { Type[] types = userType.getPropertyTypes(); int n=0; - for (int i=0; icurrency: A type that maps an SQL VARCHAR to a - * java.util.Currency - * @see java.util.Currency + * A type that maps between {@link java.sql.Types#VARCHAR VARCHAR} and {@link Currency} + * * @author Gavin King + * @author Steve Ebersole */ -public class CurrencyType extends ImmutableType implements LiteralType { +public class CurrencyType + extends AbstractSingleColumnStandardBasicType + implements LiteralType { - public static final Class CURRENCY_CLASS; - private static final Method CURRENCY_GET_INSTANCE; - private static final Method CURRENCY_GET_CODE; + public static final CurrencyType INSTANCE = new CurrencyType(); - static { - Class clazz; - try { - clazz = Class.forName("java.util.Currency"); - } - catch (ClassNotFoundException cnfe) { - clazz = null; - } - if (clazz==null) { - CURRENCY_CLASS = null; - CURRENCY_GET_INSTANCE = null; - CURRENCY_GET_CODE = null; - } - else { - CURRENCY_CLASS = clazz; - try { - CURRENCY_GET_INSTANCE = clazz.getMethod("getInstance", new Class[] { String.class } ); - CURRENCY_GET_CODE = clazz.getMethod("getCurrencyCode", new Class[0] ); - } - catch (Exception e) { - throw new AssertionFailure("Exception in static initializer of CurrencyType", e); - } - } + public CurrencyType() { + super( VarcharTypeDescriptor.INSTANCE, CurrencyTypeDescriptor.INSTANCE ); } - /** - * @see org.hibernate.type.NullableType#get(ResultSet, String) - */ - public Object get(ResultSet rs, String name) - throws HibernateException, SQLException { - String code = (String) Hibernate.STRING.nullSafeGet(rs, name); - try { - return code==null ? null : - CURRENCY_GET_INSTANCE.invoke(null, new Object[] { code } ); - } - catch (Exception e) { - throw new HibernateException("Could not resolve currency code: " + code); - } - } - - /** - * @see org.hibernate.type.NullableType#set(PreparedStatement, Object, int) - */ - public void set(PreparedStatement st, Object value, int index) - throws HibernateException, SQLException { - Object code; - try { - code = CURRENCY_GET_CODE.invoke(value, null); - } - catch (Exception e) { - throw new HibernateException("Could not get Currency code", e); - } - Hibernate.STRING.set(st, code, index); - } - - /** - * @see org.hibernate.type.NullableType#sqlType() - */ - public int sqlType() { - return Hibernate.STRING.sqlType(); - } - - /** - */ - public String toString(Object value) throws HibernateException { - try { - return (String) CURRENCY_GET_CODE.invoke(value, null); - } - catch (Exception e) { - throw new HibernateException("Could not get Currency code", e); - } - } - - /** - * @see org.hibernate.type.Type#getReturnedClass() - */ - public Class getReturnedClass() { - return CURRENCY_CLASS; - } - - /** - * @see org.hibernate.type.Type#getName() - */ public String getName() { return "currency"; } - /** - * @see org.hibernate.type.LiteralType#objectToSQLString(Object, Dialect) - */ - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - String code; - try { - code = (String) CURRENCY_GET_CODE.invoke(value, null); - } - catch (Exception e) { - throw new HibernateException("Could not get Currency code", e); - } - return ( (LiteralType) Hibernate.STRING ).objectToSQLString(code, dialect); + @Override + protected boolean registerUnderJavaType() { + return true; } - public Object fromStringValue(String xml) throws HibernateException { - try { - return CURRENCY_GET_INSTANCE.invoke( null, new Object[] {xml} ); - } - catch (Exception e) { - throw new HibernateException("Could not resolve currency code: " + xml); - } + public String objectToSQLString(Currency value, Dialect dialect) throws Exception { + return "\'" + toString( value ) + "\'"; } - } - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/CustomCollectionType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/CustomCollectionType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/CustomCollectionType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/CustomCollectionType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; @@ -30,17 +29,17 @@ import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.collection.PersistentCollection; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.engine.SessionFactoryImplementor; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; -import org.hibernate.usertype.UserCollectionType; import org.hibernate.usertype.LoggableUserType; +import org.hibernate.usertype.UserCollectionType; /** * A custom type for mapping user-written classes that implement PersistentCollection * - * @see org.hibernate.collection.PersistentCollection + * @see org.hibernate.collection.spi.PersistentCollection * @see org.hibernate.usertype.UserCollectionType * @author Gavin King */ @@ -49,24 +48,46 @@ private final UserCollectionType userType; private final boolean customLogging; - public CustomCollectionType(Class userTypeClass, String role, String foreignKeyPropertyName, boolean isEmbeddedInXML) { - super(role, foreignKeyPropertyName, isEmbeddedInXML); + /** + * @deprecated Use {@link #CustomCollectionType(TypeFactory.TypeScope, Class, String, String )} instead. + * See Jira issue: HHH-7771 + */ + @Deprecated + public CustomCollectionType( + TypeFactory.TypeScope typeScope, + Class userTypeClass, + String role, + String foreignKeyPropertyName, + boolean isEmbeddedInXML) { + super( typeScope, role, foreignKeyPropertyName, isEmbeddedInXML ); + userType = createUserCollectionType( userTypeClass ); + customLogging = LoggableUserType.class.isAssignableFrom( userTypeClass ); + } + public CustomCollectionType( + TypeFactory.TypeScope typeScope, + Class userTypeClass, + String role, + String foreignKeyPropertyName) { + super( typeScope, role, foreignKeyPropertyName ); + userType = createUserCollectionType( userTypeClass ); + customLogging = LoggableUserType.class.isAssignableFrom( userTypeClass ); + } + + private static UserCollectionType createUserCollectionType(Class userTypeClass) { if ( !UserCollectionType.class.isAssignableFrom( userTypeClass ) ) { throw new MappingException( "Custom type does not implement UserCollectionType: " + userTypeClass.getName() ); } try { - userType = ( UserCollectionType ) userTypeClass.newInstance(); + return ( UserCollectionType ) userTypeClass.newInstance(); } catch ( InstantiationException ie ) { throw new MappingException( "Cannot instantiate custom type: " + userTypeClass.getName() ); } catch ( IllegalAccessException iae ) { throw new MappingException( "IllegalAccessException trying to instantiate custom type: " + userTypeClass.getName() ); } - - customLogging = LoggableUserType.class.isAssignableFrom( userTypeClass ); } public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) Index: 3rdParty_sources/hibernate-core/org/hibernate/type/CustomType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/CustomType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/CustomType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/CustomType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; @@ -31,72 +30,82 @@ import java.util.Arrays; import java.util.Comparator; import java.util.Map; -import java.util.Properties; -import org.dom4j.Node; -import org.hibernate.EntityMode; import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.metamodel.relational.Size; import org.hibernate.usertype.EnhancedUserType; +import org.hibernate.usertype.LoggableUserType; +import org.hibernate.usertype.Sized; import org.hibernate.usertype.UserType; import org.hibernate.usertype.UserVersionType; -import org.hibernate.usertype.LoggableUserType; +import org.dom4j.Node; + /** * Adapts {@link UserType} to the generic {@link Type} interface, in order * to isolate user code from changes in the internal Type contracts. * - * @see org.hibernate.usertype.UserType * @author Gavin King + * @author Steve Ebersole */ -public class CustomType extends AbstractType implements IdentifierType, DiscriminatorType, VersionType { +public class CustomType + extends AbstractType + implements IdentifierType, DiscriminatorType, VersionType, BasicType, StringRepresentableType { private final UserType userType; private final String name; private final int[] types; + private final Size[] dictatedSizes; + private final Size[] defaultSizes; private final boolean customLogging; + private final String[] registrationKeys; - public CustomType(Class userTypeClass, Properties parameters) throws MappingException { + public CustomType(UserType userType) throws MappingException { + this( userType, ArrayHelper.EMPTY_STRING_ARRAY ); + } - if ( !UserType.class.isAssignableFrom( userTypeClass ) ) { - throw new MappingException( - "Custom type does not implement UserType: " + - userTypeClass.getName() - ); - } + public CustomType(UserType userType, String[] registrationKeys) throws MappingException { + this.userType = userType; + this.name = userType.getClass().getName(); + this.types = userType.sqlTypes(); + this.dictatedSizes = Sized.class.isInstance( userType ) + ? ( (Sized) userType ).dictatedSizes() + : new Size[ types.length ]; + this.defaultSizes = Sized.class.isInstance( userType ) + ? ( (Sized) userType ).defaultSizes() + : new Size[ types.length ]; + this.customLogging = LoggableUserType.class.isInstance( userType ); + this.registrationKeys = registrationKeys; + } - name = userTypeClass.getName(); + public UserType getUserType() { + return userType; + } - try { - userType = ( UserType ) userTypeClass.newInstance(); - } - catch ( InstantiationException ie ) { - throw new MappingException( - "Cannot instantiate custom type: " + - userTypeClass.getName() - ); - } - catch ( IllegalAccessException iae ) { - throw new MappingException( - "IllegalAccessException trying to instantiate custom type: " + - userTypeClass.getName() - ); - } - - TypeFactory.injectParameters( userType, parameters ); - types = userType.sqlTypes(); - - customLogging = LoggableUserType.class.isAssignableFrom( userTypeClass ); + public String[] getRegistrationKeys() { + return registrationKeys; } public int[] sqlTypes(Mapping pi) { return types; } + @Override + public Size[] dictatedSizes(Mapping mapping) throws MappingException { + return dictatedSizes; + } + + @Override + public Size[] defaultSizes(Mapping mapping) throws MappingException { + return defaultSizes; + } + public int getColumnSpan(Mapping session) { return types.length; } @@ -106,45 +115,31 @@ } public boolean isEqual(Object x, Object y) throws HibernateException { - return userType.equals(x, y); + return userType.equals( x, y ); } - public boolean isEqual(Object x, Object y, EntityMode entityMode) - throws HibernateException { - return isEqual(x, y); - } - - public int getHashCode(Object x, EntityMode entityMode) { + public int getHashCode(Object x) { return userType.hashCode(x); } - public Object nullSafeGet( - ResultSet rs, - String[] names, - SessionImplementor session, - Object owner - ) throws HibernateException, SQLException { - - return userType.nullSafeGet(rs, names, owner); + public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) + throws HibernateException, SQLException { + return userType.nullSafeGet(rs, names, session, owner); } - public Object nullSafeGet( - ResultSet rs, - String columnName, - SessionImplementor session, - Object owner - ) throws HibernateException, SQLException { + public Object nullSafeGet(ResultSet rs, String columnName, SessionImplementor session, Object owner) + throws HibernateException, SQLException { return nullSafeGet(rs, new String[] { columnName }, session, owner); } public Object assemble(Serializable cached, SessionImplementor session, Object owner) - throws HibernateException { + throws HibernateException { return userType.assemble(cached, owner); } public Serializable disassemble(Object value, SessionImplementor session, Object owner) - throws HibernateException { + throws HibernateException { return userType.disassemble(value); } @@ -153,52 +148,38 @@ Object target, SessionImplementor session, Object owner, - Map copyCache) - throws HibernateException { - return userType.replace(original, target, owner); + Map copyCache) throws HibernateException { + return userType.replace( original, target, owner ); } - public void nullSafeSet( - PreparedStatement st, - Object value, - int index, - boolean[] settable, - SessionImplementor session - ) throws HibernateException, SQLException { - - if ( settable[0] ) userType.nullSafeSet(st, value, index); + public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session) + throws HibernateException, SQLException { + if ( settable[0] ) { + userType.nullSafeSet( st, value, index, session ); + } } - public void nullSafeSet( - PreparedStatement st, - Object value, - int index, - SessionImplementor session - ) throws HibernateException, SQLException { - - userType.nullSafeSet(st, value, index); + public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) + throws HibernateException, SQLException { + userType.nullSafeSet( st, value, index, session ); } + @SuppressWarnings({ "UnusedDeclaration" }) public String toXMLString(Object value, SessionFactoryImplementor factory) { - if (value==null) return null; - if (userType instanceof EnhancedUserType) { - return ( (EnhancedUserType) userType ).toXMLString(value); - } - else { - return value.toString(); - } + return toString( value ); } + @SuppressWarnings({ "UnusedDeclaration" }) public Object fromXMLString(String xml, Mapping factory) { - return ( (EnhancedUserType) userType ).fromXMLString(xml); + return fromStringValue( xml ); } public String getName() { return name; } - public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) - throws HibernateException { + public Object deepCopy(Object value, SessionFactoryImplementor factory) + throws HibernateException { return userType.deepCopy(value); } @@ -207,7 +188,7 @@ } public Object stringToObject(String xml) { - return ( (EnhancedUserType) userType ).fromXMLString(xml); + return fromStringValue( xml ); } public String objectToSQLString(Object value, Dialect dialect) throws Exception { @@ -231,12 +212,12 @@ } public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) - throws HibernateException { + throws HibernateException { node.setText( toXMLString(value, factory) ); } public String toLoggableString(Object value, SessionFactoryImplementor factory) - throws HibernateException { + throws HibernateException { if ( value == null ) { return "null"; } @@ -250,12 +231,49 @@ public boolean[] toColumnNullness(Object value, Mapping mapping) { boolean[] result = new boolean[ getColumnSpan(mapping) ]; - if (value!=null) Arrays.fill(result, true); + if ( value != null ) { + Arrays.fill(result, true); + } return result; } - public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException { + public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) + throws HibernateException { return checkable[0] && isDirty(old, current, session); } + @Override + @SuppressWarnings("unchecked") + public String toString(Object value) throws HibernateException { + if ( StringRepresentableType.class.isInstance( userType ) ) { + return ( (StringRepresentableType) userType ).toString( value ); + } + if ( value == null ) { + return null; + } + if ( EnhancedUserType.class.isInstance( userType ) ) { + //noinspection deprecation + return ( (EnhancedUserType) userType ).toXMLString( value ); + } + return value.toString(); + } + + @Override + public Object fromStringValue(String string) throws HibernateException { + if ( StringRepresentableType.class.isInstance( userType ) ) { + return ( (StringRepresentableType) userType ).fromStringValue( string ); + } + if ( EnhancedUserType.class.isInstance( userType ) ) { + //noinspection deprecation + return ( (EnhancedUserType) userType ).fromXMLString( string ); + } + throw new HibernateException( + String.format( + "Could not process #fromStringValue, UserType class [%s] did not implement %s or %s", + name, + StringRepresentableType.class.getName(), + EnhancedUserType.class.getName() + ) + ); + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/DateType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/DateType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/DateType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/DateType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,111 +20,56 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; -import java.sql.Date; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; +import java.util.Date; -import org.hibernate.EntityMode; -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; import org.hibernate.dialect.Dialect; +import org.hibernate.type.descriptor.java.JdbcDateTypeDescriptor; /** - * date: A type that maps an SQL DATE to a Java Date. + * A type that maps between {@link java.sql.Types#DATE DATE} and {@link java.sql.Date} + * * @author Gavin King + * @author Steve Ebersole */ -public class DateType extends MutableType implements IdentifierType, LiteralType { +public class DateType + extends AbstractSingleColumnStandardBasicType + implements IdentifierType, LiteralType { - private static final String DATE_FORMAT = "dd MMMM yyyy"; + public static final DateType INSTANCE = new DateType(); - public Object get(ResultSet rs, String name) throws SQLException { - return rs.getDate(name); + public DateType() { + super( org.hibernate.type.descriptor.sql.DateTypeDescriptor.INSTANCE, JdbcDateTypeDescriptor.INSTANCE ); } - public Class getReturnedClass() { - return java.util.Date.class; + public String getName() { + return "date"; } - public void set(PreparedStatement st, Object value, int index) throws SQLException { - - Date sqlDate; - if ( value instanceof Date) { - sqlDate = (Date) value; - } - else { - sqlDate = new Date( ( (java.util.Date) value ).getTime() ); - } - st.setDate(index, sqlDate); + @Override + public String[] getRegistrationKeys() { + return new String[] { + getName(), + java.sql.Date.class.getName() + }; } - public int sqlType() { - return Types.DATE; - } +// @Override +// protected boolean registerUnderJavaType() { +// return true; +// } - public boolean isEqual(Object x, Object y) { - - if (x==y) return true; - if (x==null || y==null) return false; - - java.util.Date xdate = (java.util.Date) x; - java.util.Date ydate = (java.util.Date) y; - - if ( xdate.getTime()==ydate.getTime() ) return true; - - Calendar calendar1 = java.util.Calendar.getInstance(); - Calendar calendar2 = java.util.Calendar.getInstance(); - calendar1.setTime( xdate ); - calendar2.setTime( ydate ); - - return Hibernate.CALENDAR_DATE.isEqual(calendar1, calendar2); + public String objectToSQLString(Date value, Dialect dialect) throws Exception { + final java.sql.Date jdbcDate = java.sql.Date.class.isInstance( value ) + ? ( java.sql.Date ) value + : new java.sql.Date( value.getTime() ); + // TODO : use JDBC date literal escape syntax? -> {d 'date-string'} in yyyy-mm-dd format + return StringType.INSTANCE.objectToSQLString( jdbcDate.toString(), dialect ); } - public int getHashCode(Object x, EntityMode entityMode) { - Calendar calendar = java.util.Calendar.getInstance(); - calendar.setTime( (java.util.Date) x ); - return Hibernate.CALENDAR_DATE.getHashCode(calendar, entityMode); + public Date stringToObject(String xml) { + return fromString( xml ); } - - public String getName() { return "date"; } - - public String toString(Object val) { - return new SimpleDateFormat(DATE_FORMAT).format( (java.util.Date) val ); - } - - public Object deepCopyNotNull(Object value) { - return new Date( ( (java.util.Date) value ).getTime() ); - } - - public Object stringToObject(String xml) throws Exception { - return DateFormat.getDateInstance().parse(xml); - } - - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return '\'' + new Date( ( (java.util.Date) value ).getTime() ).toString() + '\''; - } - - public Object fromStringValue(String xml) throws HibernateException { - try { - return new SimpleDateFormat(DATE_FORMAT).parse(xml); - } - catch (ParseException pe) { - throw new HibernateException("could not parse XML", pe); - } - } - } - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/DbTimestampType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/DbTimestampType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/DbTimestampType.java 17 Aug 2012 14:36:27 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/DbTimestampType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,22 +20,21 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; -import java.sql.Timestamp; +import java.sql.CallableStatement; import java.sql.PreparedStatement; -import java.sql.SQLException; import java.sql.ResultSet; -import java.sql.CallableStatement; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.Date; -import org.hibernate.engine.SessionImplementor; import org.hibernate.dialect.Dialect; -import org.hibernate.exception.JDBCExceptionHelper; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.CoreMessageLogger; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.jboss.logging.Logger; /** * dbtimestamp: An extension of {@link TimestampType} which @@ -48,105 +47,97 @@ * * @author Steve Ebersole */ -public class DbTimestampType extends TimestampType implements VersionType { +public class DbTimestampType extends TimestampType { + public static final DbTimestampType INSTANCE = new DbTimestampType(); - private static final Logger log = LoggerFactory.getLogger( DbTimestampType.class ); - - public String getName() { return "dbtimestamp"; } + private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, DbTimestampType.class.getName() ); - public Object seed(SessionImplementor session) { + @Override + public String getName() { + return "dbtimestamp"; + } + + @Override + public String[] getRegistrationKeys() { + return new String[] { getName() }; + } + + @Override + public Date seed(SessionImplementor session) { if ( session == null ) { - log.trace( "incoming session was null; using current jvm time" ); + LOG.trace( "Incoming session was null; using current jvm time" ); return super.seed( session ); } else if ( !session.getFactory().getDialect().supportsCurrentTimestampSelection() ) { - log.debug( "falling back to vm-based timestamp, as dialect does not support current timestamp selection" ); + LOG.debug( "Falling back to vm-based timestamp, as dialect does not support current timestamp selection" ); return super.seed( session ); } else { return getCurrentTimestamp( session ); } } - private Timestamp getCurrentTimestamp(SessionImplementor session) { + private Date getCurrentTimestamp(SessionImplementor session) { Dialect dialect = session.getFactory().getDialect(); String timestampSelectString = dialect.getCurrentTimestampSelectString(); - if ( dialect.isCurrentTimestampSelectStringCallable() ) { - return useCallableStatement( timestampSelectString, session ); - } - else { - return usePreparedStatement( timestampSelectString, session ); - } + if (dialect.isCurrentTimestampSelectStringCallable()) return useCallableStatement(timestampSelectString, session); + return usePreparedStatement(timestampSelectString, session); } private Timestamp usePreparedStatement(String timestampSelectString, SessionImplementor session) { PreparedStatement ps = null; try { - ps = session.getBatcher().prepareStatement( timestampSelectString ); - ResultSet rs = session.getBatcher().getResultSet( ps ); + ps = session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( timestampSelectString, false ); + ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( ps ); rs.next(); Timestamp ts = rs.getTimestamp( 1 ); - if ( log.isTraceEnabled() ) { - log.trace( - "current timestamp retreived from db : " + ts + - " (nanos=" + ts.getNanos() + - ", time=" + ts.getTime() + ")" - ); + if ( LOG.isTraceEnabled() ) { + LOG.tracev( "Current timestamp retreived from db : {0} (nanos={1}, time={2})", ts, ts.getNanos(), ts.getTime() ); } return ts; } - catch( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - session.getFactory().getSQLExceptionConverter(), - sqle, + catch( SQLException e ) { + throw session.getFactory().getSQLExceptionHelper().convert( + e, "could not select current db timestamp", timestampSelectString - ); + ); } finally { if ( ps != null ) { - try { - session.getBatcher().closeStatement( ps ); - } - catch( SQLException sqle ) { - log.warn( "unable to clean up prepared statement", sqle ); - } + session.getTransactionCoordinator().getJdbcCoordinator().release( ps ); } } } private Timestamp useCallableStatement(String callString, SessionImplementor session) { CallableStatement cs = null; try { - cs = session.getBatcher().prepareCallableStatement( callString ); + cs = (CallableStatement) session.getTransactionCoordinator() + .getJdbcCoordinator() + .getStatementPreparer() + .prepareStatement( callString, true ); cs.registerOutParameter( 1, java.sql.Types.TIMESTAMP ); - cs.execute(); + session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().execute( cs ); Timestamp ts = cs.getTimestamp( 1 ); - if ( log.isTraceEnabled() ) { - log.trace( - "current timestamp retreived from db : " + ts + - " (nanos=" + ts.getNanos() + - ", time=" + ts.getTime() + ")" - ); + if ( LOG.isTraceEnabled() ) { + LOG.tracev( "Current timestamp retreived from db : {0} (nanos={1}, time={2})", ts, ts.getNanos(), ts.getTime() ); } return ts; } - catch( SQLException sqle ) { - throw JDBCExceptionHelper.convert( - session.getFactory().getSQLExceptionConverter(), - sqle, + catch( SQLException e ) { + throw session.getFactory().getSQLExceptionHelper().convert( + e, "could not call current db timestamp function", callString - ); + ); } finally { if ( cs != null ) { - try { - session.getBatcher().closeStatement( cs ); - } - catch( SQLException sqle ) { - log.warn( "unable to clean up callable statement", sqle ); - } + session.getTransactionCoordinator().getJdbcCoordinator().release( cs ); } } } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/DiscriminatorType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/DiscriminatorType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/DiscriminatorType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/DiscriminatorType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,19 +20,15 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; + /** - * A Type that may be used for a discriminator column. + * Additional contract for a {@link Type} may be used for a discriminator. + * * @author Gavin King + * @author Steve Ebersole */ -public interface DiscriminatorType extends IdentifierType, LiteralType { +public interface DiscriminatorType extends IdentifierType, LiteralType { } - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/DoubleType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/DoubleType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/DoubleType.java 17 Aug 2012 14:36:30 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/DoubleType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,62 +20,47 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; import org.hibernate.dialect.Dialect; +import org.hibernate.type.descriptor.java.DoubleTypeDescriptor; /** - * double: A type that maps an SQL DOUBLE to a Java Double. + * A type that maps between {@link java.sql.Types#DOUBLE DOUBLE} and {@link Double} + * * @author Gavin King + * @author Steve Ebersole */ -public class DoubleType extends PrimitiveType { +public class DoubleType extends AbstractSingleColumnStandardBasicType implements PrimitiveType { + public static final DoubleType INSTANCE = new DoubleType(); - public Serializable getDefaultValue() { - return new Double(0.0); - } - - public Object get(ResultSet rs, String name) throws SQLException { - return new Double( rs.getDouble(name) ); - } + public static final Double ZERO = 0.0; - public Class getPrimitiveClass() { - return double.class; + public DoubleType() { + super( org.hibernate.type.descriptor.sql.DoubleTypeDescriptor.INSTANCE, DoubleTypeDescriptor.INSTANCE ); } - - public Class getReturnedClass() { - return Double.class; + @Override + public String getName() { + return "double"; } - public void set(PreparedStatement st, Object value, int index) - throws SQLException { - - st.setDouble( index, ( (Double) value ).doubleValue() ); + @Override + public String[] getRegistrationKeys() { + return new String[] { getName(), double.class.getName(), Double.class.getName() }; } - - public int sqlType() { - return Types.DOUBLE; + @Override + public Serializable getDefaultValue() { + return ZERO; } - public String getName() { return "double"; } - - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return value.toString(); + @Override + public Class getPrimitiveClass() { + return double.class; } - - public Object fromStringValue(String xml) { - return new Double(xml); + @Override + public String objectToSQLString(Double value, Dialect dialect) throws Exception { + return toString( value ); } - } - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/EmbeddedComponentType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/EmbeddedComponentType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/EmbeddedComponentType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/EmbeddedComponentType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,37 +20,32 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.lang.reflect.Method; -import org.hibernate.EntityMode; import org.hibernate.HibernateException; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.tuple.component.ComponentTuplizer; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.tuple.component.ComponentMetamodel; /** * @author Gavin King */ public class EmbeddedComponentType extends ComponentType { + public EmbeddedComponentType(TypeFactory.TypeScope typeScope, ComponentMetamodel metamodel) { + super( typeScope, metamodel ); + } public boolean isEmbedded() { return true; } - public EmbeddedComponentType(ComponentMetamodel metamodel) { - super( metamodel ); - } - public boolean isMethodOf(Method method) { - return ( ( ComponentTuplizer ) tuplizerMapping.getTuplizer(EntityMode.POJO) ).isMethodOf(method); + return componentTuplizer.isMethodOf( method ); } - public Object instantiate(Object parent, SessionImplementor session) - throws HibernateException { + public Object instantiate(Object parent, SessionImplementor session) throws HibernateException { final boolean useParent = parent!=null && //TODO: Yuck! This is not quite good enough, it's a quick //hack around the problem of having a to-one association Index: 3rdParty_sources/hibernate-core/org/hibernate/type/EntityType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/EntityType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/EntityType.java 17 Aug 2012 14:36:30 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/EntityType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,53 +20,69 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map; +import java.util.Set; -import org.dom4j.Element; -import org.dom4j.Node; import org.hibernate.AssertionFailure; import org.hibernate.EntityMode; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.engine.EntityUniqueKey; -import org.hibernate.engine.ForeignKeys; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.PersistenceContext; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.internal.ForeignKeys; +import org.hibernate.engine.spi.EntityUniqueKey; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.PersistenceContext; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.util.ReflectHelper; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.Joinable; import org.hibernate.persister.entity.UniqueKeyLoadable; import org.hibernate.proxy.HibernateProxy; -import org.hibernate.proxy.LazyInitializer; import org.hibernate.tuple.ElementWrapper; -import org.hibernate.util.ReflectHelper; +import org.dom4j.Element; +import org.dom4j.Node; + /** * Base for types which map associations to persistent entities. * * @author Gavin King */ public abstract class EntityType extends AbstractType implements AssociationType { + private final TypeFactory.TypeScope scope; private final String associatedEntityName; protected final String uniqueKeyPropertyName; protected final boolean isEmbeddedInXML; private final boolean eager; private final boolean unwrapProxy; + private final boolean referenceToPrimaryKey; + /** + * Cached because of performance + * @see #getIdentifierType(SessionImplementor) + * @see #getIdentifierType(Mapping) + */ + private transient volatile Type associatedIdentifierType; + + /** + * Cached because of performance + * @see #getAssociatedEntityPersister + */ + private transient volatile EntityPersister associatedEntityPersister; + private transient Class returnedClass; /** * Constructs the requested entity type mapping. * + * @param scope The type scope * @param entityName The name of the associated entity. * @param uniqueKeyPropertyName The property-ref name, or null if we * reference the PK of the associated entity. @@ -75,25 +91,84 @@ * @param unwrapProxy Is unwrapping of proxies allowed for this association; unwrapping * says to return the "implementation target" of lazy prooxies; typically only possible * with lazy="no-proxy". + * + * @deprecated Use {@link #EntityType(org.hibernate.type.TypeFactory.TypeScope, String, boolean, String, boolean, boolean)} instead. + * See Jira issue: HHH-7771 */ + @Deprecated protected EntityType( + TypeFactory.TypeScope scope, String entityName, String uniqueKeyPropertyName, boolean eager, boolean isEmbeddedInXML, boolean unwrapProxy) { + this( scope, entityName, uniqueKeyPropertyName == null, uniqueKeyPropertyName, eager, unwrapProxy ); + } + + /** + * Constructs the requested entity type mapping. + * + * @param scope The type scope + * @param entityName The name of the associated entity. + * @param uniqueKeyPropertyName The property-ref name, or null if we + * reference the PK of the associated entity. + * @param eager Is eager fetching enabled. + * @param unwrapProxy Is unwrapping of proxies allowed for this association; unwrapping + * says to return the "implementation target" of lazy prooxies; typically only possible + * with lazy="no-proxy". + * + * @deprecated Use {@link #EntityType(org.hibernate.type.TypeFactory.TypeScope, String, boolean, String, boolean, boolean)} instead. + */ + @Deprecated + protected EntityType( + TypeFactory.TypeScope scope, + String entityName, + String uniqueKeyPropertyName, + boolean eager, + boolean unwrapProxy) { + this( scope, entityName, uniqueKeyPropertyName == null, uniqueKeyPropertyName, eager, unwrapProxy ); + } + + /** + * Constructs the requested entity type mapping. + * + * @param scope The type scope + * @param entityName The name of the associated entity. + * @param referenceToPrimaryKey True if association references a primary key. + * @param uniqueKeyPropertyName The property-ref name, or null if we + * reference the PK of the associated entity. + * @param eager Is eager fetching enabled. + * @param unwrapProxy Is unwrapping of proxies allowed for this association; unwrapping + * says to return the "implementation target" of lazy prooxies; typically only possible + * with lazy="no-proxy". + */ + protected EntityType( + TypeFactory.TypeScope scope, + String entityName, + boolean referenceToPrimaryKey, + String uniqueKeyPropertyName, + boolean eager, + boolean unwrapProxy) { + this.scope = scope; this.associatedEntityName = entityName; this.uniqueKeyPropertyName = uniqueKeyPropertyName; - this.isEmbeddedInXML = isEmbeddedInXML; + this.isEmbeddedInXML = true; this.eager = eager; this.unwrapProxy = unwrapProxy; + this.referenceToPrimaryKey = referenceToPrimaryKey; } + protected TypeFactory.TypeScope scope() { + return scope; + } + /** * An entity type is a type of association type * * @return True. */ + @Override public boolean isAssociationType() { return true; } @@ -103,13 +178,12 @@ * * @return True. */ + @Override public final boolean isEntityType() { return true; } - /** - * {@inheritDoc} - */ + @Override public boolean isMutable() { return false; } @@ -119,13 +193,15 @@ * * @return string rep */ + @Override public String toString() { return getClass().getName() + '(' + getAssociatedEntityName() + ')'; } /** * For entity types, the name correlates to the associated entity name. */ + @Override public String getName() { return associatedEntityName; } @@ -137,13 +213,17 @@ * @return True if this association reference the PK of the associated entity. */ public boolean isReferenceToPrimaryKey() { - return uniqueKeyPropertyName==null; + return referenceToPrimaryKey; } + @Override public String getRHSUniqueKeyPropertyName() { - return uniqueKeyPropertyName; + // Return null if this type references a PK. This is important for + // associations' use of mappedBy referring to a derived ID. + return referenceToPrimaryKey ? null : uniqueKeyPropertyName; } + @Override public String getLHSPropertyName() { return null; } @@ -167,6 +247,7 @@ * @param factory The session factory, for resolution. * @return The associated entity name. */ + @Override public String getAssociatedEntityName(SessionFactoryImplementor factory) { return getAssociatedEntityName(); } @@ -178,8 +259,9 @@ * @return The associated joinable * @throws MappingException Generally indicates an invalid entity name. */ + @Override public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) throws MappingException { - return ( Joinable ) factory.getEntityPersister( associatedEntityName ); + return ( Joinable ) getAssociatedEntityPersister( factory ); } /** @@ -192,33 +274,32 @@ * * @return The entiyt class. */ + @Override public final Class getReturnedClass() { if ( returnedClass == null ) { returnedClass = determineAssociatedEntityClass(); } return returnedClass; } - private Class determineAssociatedEntityClass() { - try { - return ReflectHelper.classForName( getAssociatedEntityName() ); - } - catch ( ClassNotFoundException cnfe ) { - return java.util.Map.class; - } - } + private Class determineAssociatedEntityClass() { + final String entityName = getAssociatedEntityName(); + try { + return ReflectHelper.classForName(entityName); + } + catch ( ClassNotFoundException cnfe ) { + return this.scope.resolveFactory().getEntityPersister(entityName). + getEntityTuplizer().getMappedClass(); + } + } - /** - * {@inheritDoc} - */ + @Override public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) - throws HibernateException, SQLException { + throws HibernateException, SQLException { return nullSafeGet( rs, new String[] {name}, session, owner ); } - /** - * {@inheritDoc} - */ + @Override public final Object nullSafeGet( ResultSet rs, String[] names, @@ -230,32 +311,27 @@ /** * Two entities are considered the same when their instances are the same. * + * * @param x One entity instance * @param y Another entity instance - * @param entityMode The entity mode. * @return True if x == y; false otherwise. */ - public final boolean isSame(Object x, Object y, EntityMode entityMode) { + @Override + public final boolean isSame(Object x, Object y) { return x == y; } - /** - * {@inheritDoc} - */ - public int compare(Object x, Object y, EntityMode entityMode) { + @Override + public int compare(Object x, Object y) { return 0; //TODO: entities CAN be compared, by PK, fix this! -> only if/when we can extract the id values.... } - /** - * {@inheritDoc} - */ - public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) { + @Override + public Object deepCopy(Object value, SessionFactoryImplementor factory) { return value; //special case ... this is the leaf of the containment graph, even though not immutable } - /** - * {@inheritDoc} - */ + @Override public Object replace( Object original, Object target, @@ -275,16 +351,15 @@ } if ( session.getContextEntityIdentifier( original ) == null && ForeignKeys.isTransient( associatedEntityName, original, Boolean.FALSE, session ) ) { - final Object copy = session.getFactory().getEntityPersister( associatedEntityName ) - .instantiate( null, session.getEntityMode() ); - //TODO: should this be Session.instantiate(Persister, ...)? + final Object copy = session.getEntityPersister( associatedEntityName, original ) + .instantiate( null, session ); copyCache.put( original, copy ); return copy; } else { Object id = getIdentifier( original, session ); if ( id == null ) { - throw new AssertionFailure("non-transient entity has a null id"); + throw new AssertionFailure("non-transient entity has a null id: " + original.getClass().getName()); } id = getIdentifierOrUniqueKeyType( session.getFactory() ) .replace(id, null, session, owner, copyCache); @@ -293,41 +368,55 @@ } } - /** - * {@inheritDoc} - */ - public int getHashCode(Object x, EntityMode entityMode, SessionFactoryImplementor factory) { - EntityPersister persister = factory.getEntityPersister(associatedEntityName); + @Override + public int getHashCode(Object x, SessionFactoryImplementor factory) { + EntityPersister persister = getAssociatedEntityPersister( factory ); if ( !persister.canExtractIdOutOfEntity() ) { - return super.getHashCode(x, entityMode); + return super.getHashCode( x ); } final Serializable id; if (x instanceof HibernateProxy) { id = ( (HibernateProxy) x ).getHibernateLazyInitializer().getIdentifier(); } else { - id = persister.getIdentifier(x, entityMode); + final Class mappedClass = persister.getMappedClass(); + if ( mappedClass.isAssignableFrom( x.getClass() ) ) { + id = persister.getIdentifier( x ); + } + else { + id = (Serializable) x; + } } - return persister.getIdentifierType().getHashCode(id, entityMode, factory); + return persister.getIdentifierType().getHashCode( id, factory ); } - /** - * {@inheritDoc} - */ - public boolean isEqual(Object x, Object y, EntityMode entityMode, SessionFactoryImplementor factory) { - EntityPersister persister = factory.getEntityPersister(associatedEntityName); + @Override + public boolean isEqual(Object x, Object y, SessionFactoryImplementor factory) { + // associations (many-to-one and one-to-one) can be null... + if ( x == null || y == null ) { + return x == y; + } + + EntityPersister persister = getAssociatedEntityPersister( factory ); if ( !persister.canExtractIdOutOfEntity() ) { - return super.isEqual(x, y, entityMode); + return super.isEqual(x, y ); } + final Class mappedClass = persister.getMappedClass(); Serializable xid; if (x instanceof HibernateProxy) { xid = ( (HibernateProxy) x ).getHibernateLazyInitializer() .getIdentifier(); } else { - xid = persister.getIdentifier(x, entityMode); + if ( mappedClass.isAssignableFrom( x.getClass() ) ) { + xid = persister.getIdentifier( x ); + } + else { + //JPA 2 case where @IdClass contains the id and not the associated entity + xid = (Serializable) x; + } } Serializable yid; @@ -336,30 +425,30 @@ .getIdentifier(); } else { - yid = persister.getIdentifier(y, entityMode); + if ( mappedClass.isAssignableFrom( y.getClass() ) ) { + yid = persister.getIdentifier( y ); + } + else { + //JPA 2 case where @IdClass contains the id and not the associated entity + yid = (Serializable) y; + } } return persister.getIdentifierType() - .isEqual(xid, yid, entityMode, factory); + .isEqual(xid, yid, factory); } - /** - * {@inheritDoc} - */ + @Override public boolean isEmbeddedInXML() { return isEmbeddedInXML; } - /** - * {@inheritDoc} - */ + @Override public boolean isXMLElement() { return isEmbeddedInXML; } - /** - * {@inheritDoc} - */ + @Override public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException { if ( !isEmbeddedInXML ) { return getIdentifierType(factory).fromXMLNode(xml, factory); @@ -369,9 +458,7 @@ } } - /** - * {@inheritDoc} - */ + @Override public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) throws HibernateException { if ( !isEmbeddedInXML ) { getIdentifierType(factory).setToXMLNode(node, value, factory); @@ -382,59 +469,79 @@ } } - public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters) - throws MappingException { - if ( isReferenceToPrimaryKey() ) { //TODO: this is a bit arbitrary, expose a switch to the user? + @Override + public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters) { + return getOnCondition( alias, factory, enabledFilters, null ); + } + + @Override + public String getOnCondition( + String alias, + SessionFactoryImplementor factory, + Map enabledFilters, + Set treatAsDeclarations) { + if ( isReferenceToPrimaryKey() && ( treatAsDeclarations == null || treatAsDeclarations.isEmpty() ) ) { return ""; } else { - return getAssociatedJoinable( factory ).filterFragment( alias, enabledFilters ); + return getAssociatedJoinable( factory ).filterFragment( alias, enabledFilters, treatAsDeclarations ); } } /** * Resolve an identifier or unique key value */ + @Override public Object resolve(Object value, SessionImplementor session, Object owner) throws HibernateException { if ( isNotEmbedded( session ) ) { return value; } - if ( value == null ) { - return null; - } - else { - if ( isNull( owner, session ) ) { - return null; //EARLY EXIT! - } - + if ( value != null && !isNull( owner, session ) ) { if ( isReferenceToPrimaryKey() ) { return resolveIdentifier( (Serializable) value, session ); } - else { + else if ( uniqueKeyPropertyName != null ) { return loadByUniqueKey( getAssociatedEntityName(), uniqueKeyPropertyName, value, session ); } } + + return null; } + @Override public Type getSemiResolvedType(SessionFactoryImplementor factory) { - return factory.getEntityPersister( associatedEntityName ).getIdentifierType(); + return getAssociatedEntityPersister( factory ).getIdentifierType(); } + protected EntityPersister getAssociatedEntityPersister(final SessionFactoryImplementor factory) { + final EntityPersister persister = associatedEntityPersister; + //The following branch implements a simple lazy-initialization, but rather than the canonical + //form it returns the local variable to avoid a second volatile read: associatedEntityPersister + //needs to be volatile as the initialization might happen by a different thread than the readers. + if ( persister == null ) { + associatedEntityPersister = factory.getEntityPersister( getAssociatedEntityName() ); + return associatedEntityPersister; + } + else { + return persister; + } + } + protected final Object getIdentifier(Object value, SessionImplementor session) throws HibernateException { if ( isNotEmbedded(session) ) { return value; } - if ( isReferenceToPrimaryKey() ) { + if ( isReferenceToPrimaryKey() || uniqueKeyPropertyName == null ) { return ForeignKeys.getEntityIdentifierIfNotUnsaved( getAssociatedEntityName(), value, session ); //tolerates nulls } else if ( value == null ) { return null; } else { - EntityPersister entityPersister = session.getFactory().getEntityPersister( getAssociatedEntityName() ); - Object propertyValue = entityPersister.getPropertyValue( value, uniqueKeyPropertyName, session.getEntityMode() ); + EntityPersister entityPersister = getAssociatedEntityPersister( session.getFactory() ); + Object propertyValue = entityPersister.getPropertyValue( value, uniqueKeyPropertyName ); // We now have the value of the property-ref we reference. However, // we need to dig a little deeper, as that property might also be // an entity type, in which case we need to resolve its identitifier @@ -447,29 +554,14 @@ } } - protected boolean isNotEmbedded(SessionImplementor session) { - return !isEmbeddedInXML && session.getEntityMode()==EntityMode.DOM4J; - } - /** - * Get the identifier value of an instance or proxy. - *

        - * Intended only for loggin purposes!!! - * - * @param object The object from which to extract the identifier. - * @param persister The entity persister - * @param entityMode The entity mode - * @return The extracted identifier. + * @deprecated To be removed in 5. Removed as part of removing the notion of DOM entity-mode. + * See Jira issue: HHH-7771 */ - private static Serializable getIdentifier(Object object, EntityPersister persister, EntityMode entityMode) { - if (object instanceof HibernateProxy) { - HibernateProxy proxy = (HibernateProxy) object; - LazyInitializer li = proxy.getHibernateLazyInitializer(); - return li.getIdentifier(); - } - else { - return persister.getIdentifier( object, entityMode ); - } + @Deprecated + protected boolean isNotEmbedded(SessionImplementor session) { +// return !isEmbeddedInXML; + return false; } /** @@ -480,25 +572,29 @@ * @return The loggable string. * @throws HibernateException Generally some form of resolution problem. */ + @Override public String toLoggableString(Object value, SessionFactoryImplementor factory) { if ( value == null ) { return "null"; } - EntityPersister persister = factory.getEntityPersister( associatedEntityName ); - StringBuffer result = new StringBuffer().append( associatedEntityName ); + EntityPersister persister = getAssociatedEntityPersister( factory ); + StringBuilder result = new StringBuilder().append( associatedEntityName ); if ( persister.hasIdentifierProperty() ) { - final EntityMode entityMode = persister.guessEntityMode( value ); + final EntityMode entityMode = persister.getEntityMode(); final Serializable id; if ( entityMode == null ) { if ( isEmbeddedInXML ) { throw new ClassCastException( value.getClass().getName() ); } id = ( Serializable ) value; + } else if ( value instanceof HibernateProxy ) { + HibernateProxy proxy = ( HibernateProxy ) value; + id = proxy.getHibernateLazyInitializer().getIdentifier(); } else { - id = getIdentifier( value, persister, entityMode ); + id = persister.getIdentifier( value ); } result.append( '#' ) @@ -508,16 +604,40 @@ return result.toString(); } + /** + * Is the association modeled here defined as a 1-1 in the database (physical model)? + * + * @return True if a 1-1 in the database; false otherwise. + */ public abstract boolean isOneToOne(); /** + * Is the association modeled here a 1-1 according to the logical moidel? + * + * @return True if a 1-1 in the logical model; false otherwise. + */ + public boolean isLogicalOneToOne() { + return isOneToOne(); + } + + /** * Convenience method to locate the identifier type of the associated entity. * * @param factory The mappings... * @return The identifier type */ - Type getIdentifierType(Mapping factory) { - return factory.getIdentifierType( getAssociatedEntityName() ); + Type getIdentifierType(final Mapping factory) { + final Type type = associatedIdentifierType; + //The following branch implements a simple lazy-initialization, but rather than the canonical + //form it returns the local variable to avoid a second volatile read: associatedIdentifierType + //needs to be volatile as the initialization might happen by a different thread than the readers. + if ( type == null ) { + associatedIdentifierType = factory.getIdentifierType( getAssociatedEntityName() ); + return associatedIdentifierType; + } + else { + return type; + } } /** @@ -526,8 +646,15 @@ * @param session The originating session * @return The identifier type */ - Type getIdentifierType(SessionImplementor session) { - return getIdentifierType( session.getFactory() ); + Type getIdentifierType(final SessionImplementor session) { + final Type type = associatedIdentifierType; + if ( type == null ) { + associatedIdentifierType = getIdentifierType( session.getFactory() ); + return associatedIdentifierType; + } + else { + return type; + } } /** @@ -541,7 +668,7 @@ * or unique key property name. */ public final Type getIdentifierOrUniqueKeyType(Mapping factory) throws MappingException { - if ( isReferenceToPrimaryKey() ) { + if ( isReferenceToPrimaryKey() || uniqueKeyPropertyName == null ) { return getIdentifierType(factory); } else { @@ -563,7 +690,7 @@ */ public final String getIdentifierOrUniqueKeyPropertyName(Mapping factory) throws MappingException { - if ( isReferenceToPrimaryKey() ) { + if ( isReferenceToPrimaryKey() || uniqueKeyPropertyName == null ) { return factory.getIdentifierPropertyName( getAssociatedEntityName() ); } else { @@ -583,9 +710,8 @@ */ protected final Object resolveIdentifier(Serializable id, SessionImplementor session) throws HibernateException { boolean isProxyUnwrapEnabled = unwrapProxy && - session.getFactory() - .getEntityPersister( getAssociatedEntityName() ) - .isInstrumented( session.getEntityMode() ); + getAssociatedEntityPersister( session.getFactory() ) + .isInstrumented(); Object proxyOrEntity = session.internalLoad( getAssociatedEntityName(), @@ -631,7 +757,7 @@ uniqueKeyPropertyName, key, getIdentifierOrUniqueKeyType( factory ), - session.getEntityMode(), + persister.getEntityMode(), session.getFactory() ); Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/EnumType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/FloatType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/FloatType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/FloatType.java 17 Aug 2012 14:36:30 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/FloatType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,60 +20,49 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; import org.hibernate.dialect.Dialect; +import org.hibernate.type.descriptor.java.FloatTypeDescriptor; /** - * float: A type that maps an SQL FLOAT to a Java Float. + * A type that maps between {@link java.sql.Types#FLOAT FLOAT} and {@link Float} + * * @author Gavin King + * @author Steve Ebersole */ -public class FloatType extends PrimitiveType { +public class FloatType extends AbstractSingleColumnStandardBasicType implements PrimitiveType { + public static final FloatType INSTANCE = new FloatType(); - public Serializable getDefaultValue() { - return new Float(0.0); - } - - public Object get(ResultSet rs, String name) throws SQLException { - return new Float( rs.getFloat(name) ); - } + public static final Float ZERO = 0.0f; - public Class getPrimitiveClass() { - return float.class; + public FloatType() { + super( org.hibernate.type.descriptor.sql.FloatTypeDescriptor.INSTANCE, FloatTypeDescriptor.INSTANCE ); } - - public Class getReturnedClass() { - return Float.class; + @Override + public String getName() { + return "float"; } - public void set(PreparedStatement st, Object value, int index) - throws SQLException { - - st.setFloat( index, ( (Float) value ).floatValue() ); + @Override + public String[] getRegistrationKeys() { + return new String[] { getName(), float.class.getName(), Float.class.getName() }; } - - public int sqlType() { - return Types.FLOAT; + @Override + public Serializable getDefaultValue() { + return ZERO; } - - public String getName() { return "float"; } - - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return value.toString(); + @Override + public Class getPrimitiveClass() { + return float.class; } - - public Object fromStringValue(String xml) { - return new Float(xml); + @Override + public String objectToSQLString(Float value, Dialect dialect) throws Exception { + return toString( value ); } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/ForeignKeyDirection.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/ForeignKeyDirection.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/ForeignKeyDirection.java 17 Aug 2012 14:36:30 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/ForeignKeyDirection.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,13 +20,12 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; -import org.hibernate.engine.Cascade; +import org.hibernate.engine.internal.CascadePoint; /** * Represents directionality of the foreign key constraint @@ -36,18 +35,25 @@ protected ForeignKeyDirection() {} /** * Should we cascade at this cascade point? - * @see org.hibernate.engine.Cascade + * + * @param cascadePoint The point at which the cascade is being initiated. + * + * @return {@code true} if cascading should be performed now. + * + * @see org.hibernate.engine.internal.Cascade */ - public abstract boolean cascadeNow(int cascadePoint); + public abstract boolean cascadeNow(CascadePoint cascadePoint); /** * A foreign key from child to parent */ public static final ForeignKeyDirection FOREIGN_KEY_TO_PARENT = new ForeignKeyDirection() { - public boolean cascadeNow(int cascadePoint) { - return cascadePoint!=Cascade.BEFORE_INSERT_AFTER_DELETE; + @Override + public boolean cascadeNow(CascadePoint cascadePoint) { + return cascadePoint != CascadePoint.BEFORE_INSERT_AFTER_DELETE; } + @Override public String toString() { return "toParent"; } @@ -60,10 +66,12 @@ * A foreign key from parent to child */ public static final ForeignKeyDirection FOREIGN_KEY_FROM_PARENT = new ForeignKeyDirection() { - public boolean cascadeNow(int cascadePoint) { - return cascadePoint!=Cascade.AFTER_INSERT_BEFORE_DELETE; + @Override + public boolean cascadeNow(CascadePoint cascadePoint) { + return cascadePoint != CascadePoint.AFTER_INSERT_BEFORE_DELETE; } + @Override public String toString() { return "fromParent"; } @@ -72,4 +80,4 @@ return FOREIGN_KEY_FROM_PARENT; } }; -} \ No newline at end of file +} Index: 3rdParty_sources/hibernate-core/org/hibernate/type/IdentifierBagType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/IdentifierBagType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/IdentifierBagType.java 17 Aug 2012 14:36:27 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/IdentifierBagType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,25 +20,33 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; import java.util.ArrayList; import org.hibernate.HibernateException; -import org.hibernate.collection.PersistentIdentifierBag; -import org.hibernate.collection.PersistentCollection; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.collection.internal.PersistentIdentifierBag; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; public class IdentifierBagType extends CollectionType { - public IdentifierBagType(String role, String propertyRef, boolean isEmbeddedInXML) { - super(role, propertyRef, isEmbeddedInXML); + /** + * @deprecated Use {@link #IdentifierBagType(org.hibernate.type.TypeFactory.TypeScope, String, String)} + * See Jira issue: HHH-7771 + */ + @Deprecated + public IdentifierBagType(TypeFactory.TypeScope typeScope, String role, String propertyRef, boolean isEmbeddedInXML) { + super( typeScope, role, propertyRef, isEmbeddedInXML ); } + public IdentifierBagType(TypeFactory.TypeScope typeScope, String role, String propertyRef) { + super( typeScope, role, propertyRef ); + } + public PersistentCollection instantiate( SessionImplementor session, CollectionPersister persister, Serializable key) Index: 3rdParty_sources/hibernate-core/org/hibernate/type/IdentifierType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/IdentifierType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/IdentifierType.java 17 Aug 2012 14:36:27 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/IdentifierType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,28 +20,26 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; + /** - * A Type that may be used as an identifier. + * Additional contract for a {@link Type} may be used for a discriminator. THis contract is used to process + * the string representation as presented in metadata, especially in XML files. + * * @author Gavin King */ -public interface IdentifierType extends Type { +public interface IdentifierType extends Type { /** * Convert the value from the mapping file to a Java object. + * * @param xml the value of discriminator-value or unsaved-value attribute - * @return Object - * @throws Exception + * @return The converted value of the string representation. + * + * @throws Exception Indicates a problem converting from the string */ - public Object stringToObject(String xml) throws Exception; + public T stringToObject(String xml) throws Exception; } - - - - - - Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/ImageType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/ImmutableType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/ImmutableType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/ImmutableType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/ImmutableType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,24 +20,23 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; - import java.util.Map; -import org.hibernate.EntityMode; import org.hibernate.HibernateException; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; /** * Superclass of nullable immutable types. * @author Gavin King + * + * @deprecated Use the {@link AbstractStandardBasicType} approach instead */ public abstract class ImmutableType extends NullableType { - public final Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) { + public final Object deepCopy(Object value, SessionFactoryImplementor factory) { return value; } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/IntegerType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/IntegerType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/IntegerType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/IntegerType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,78 +20,67 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; import java.util.Comparator; -import org.hibernate.util.ComparableComparator; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.type.descriptor.java.IntegerTypeDescriptor; /** - * integer: A type that maps an SQL INT to a Java Integer. + * A type that maps between {@link java.sql.Types#INTEGER INTEGER} and @link Integer} + * * @author Gavin King + * @author Steve Ebersole */ -public class IntegerType extends PrimitiveType implements DiscriminatorType, VersionType { +public class IntegerType extends AbstractSingleColumnStandardBasicType + implements PrimitiveType, DiscriminatorType, VersionType { - private static final Integer ZERO = new Integer(0); + public static final IntegerType INSTANCE = new IntegerType(); - public Serializable getDefaultValue() { - return ZERO; - } - - public Object get(ResultSet rs, String name) throws SQLException { - return new Integer( rs.getInt(name) ); - } + public static final Integer ZERO = 0; - public Class getPrimitiveClass() { - return int.class; + public IntegerType() { + super( org.hibernate.type.descriptor.sql.IntegerTypeDescriptor.INSTANCE, IntegerTypeDescriptor.INSTANCE ); } - - public Class getReturnedClass() { - return Integer.class; + @Override + public String getName() { + return "integer"; } - public void set(PreparedStatement st, Object value, int index) - throws SQLException { - st.setInt( index, ( (Integer) value ).intValue() ); + @Override + public String[] getRegistrationKeys() { + return new String[] { getName(), int.class.getName(), Integer.class.getName() }; } - - public int sqlType() { - return Types.INTEGER; + @Override + public Serializable getDefaultValue() { + return ZERO; } - - public String getName() { return "integer"; } - - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return value.toString(); + @Override + public Class getPrimitiveClass() { + return int.class; } - - public Object stringToObject(String xml) throws Exception { - return new Integer(xml); + @Override + public String objectToSQLString(Integer value, Dialect dialect) throws Exception { + return toString( value ); } - - public Object next(Object current, SessionImplementor session) { - return new Integer( ( (Integer) current ).intValue() + 1 ); + @Override + public Integer stringToObject(String xml) { + return fromString( xml ); } - - public Object seed(SessionImplementor session) { + @Override + public Integer seed(SessionImplementor session) { return ZERO; } - - public Comparator getComparator() { - return ComparableComparator.INSTANCE; + @Override + public Integer next(Integer current, SessionImplementor session) { + return current+1; } - - public Object fromStringValue(String xml) { - return new Integer(xml); + @Override + public Comparator getComparator() { + return getJavaTypeDescriptor().getComparator(); } - } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/ListType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/ListType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/ListType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/ListType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,48 +20,43 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; import java.util.ArrayList; import java.util.List; -import org.dom4j.Element; -import org.hibernate.EntityMode; -import org.hibernate.collection.PersistentCollection; -import org.hibernate.collection.PersistentList; -import org.hibernate.collection.PersistentListElementHolder; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.collection.internal.PersistentList; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; public class ListType extends CollectionType { - public ListType(String role, String propertyRef, boolean isEmbeddedInXML) { - super(role, propertyRef, isEmbeddedInXML); + /** + * @deprecated Use {@link #ListType(org.hibernate.type.TypeFactory.TypeScope, String, String)} + * See Jira issue: HHH-7771 + */ + @Deprecated + public ListType(TypeFactory.TypeScope typeScope, String role, String propertyRef, boolean isEmbeddedInXML) { + super( typeScope, role, propertyRef, isEmbeddedInXML ); } + public ListType(TypeFactory.TypeScope typeScope, String role, String propertyRef) { + super( typeScope, role, propertyRef ); + } + public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) { - if ( session.getEntityMode()==EntityMode.DOM4J ) { - return new PersistentListElementHolder(session, persister, key); - } - else { - return new PersistentList(session); - } + return new PersistentList(session); } public Class getReturnedClass() { return List.class; } public PersistentCollection wrap(SessionImplementor session, Object collection) { - if ( session.getEntityMode()==EntityMode.DOM4J ) { - return new PersistentListElementHolder( session, (Element) collection ); - } - else { - return new PersistentList( session, (List) collection ); - } + return new PersistentList( session, (List) collection ); } public Object instantiate(int anticipatedSize) { @@ -72,7 +67,7 @@ List list = (List) collection; for ( int i=0; i { /** - * String representation of the value, suitable for embedding in - * an SQL statement. - * @param value - * @param dialect - * @return String the value, as it appears in a SQL query - * @throws Exception + * Convert the value into a string representation, suitable for embedding in an SQL statement as a + * literal. + * + * @param value The value to convert + * @param dialect The SQL dialect + * + * @return The value's string representation + * + * @throws Exception Indicates an issue converting the value to literal string. */ - public String objectToSQLString(Object value, Dialect dialect) throws Exception; + public String objectToSQLString(T value, Dialect dialect) throws Exception; } - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/LocaleType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/LocaleType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/LocaleType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/LocaleType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,82 +20,40 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; import java.util.Locale; -import java.util.StringTokenizer; -import org.hibernate.EntityMode; -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; import org.hibernate.dialect.Dialect; +import org.hibernate.type.descriptor.java.LocaleTypeDescriptor; +import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor; /** - * locale: A type that maps an SQL VARCHAR to a Java Locale. + * A type that maps between {@link java.sql.Types#VARCHAR VARCHAR} and @link Locale} + * * @author Gavin King + * @author Steve Ebersole */ -public class LocaleType extends ImmutableType implements LiteralType { +public class LocaleType extends AbstractSingleColumnStandardBasicType + implements LiteralType { - public Object get(ResultSet rs, String name) throws HibernateException, SQLException { - return fromStringValue( (String) Hibernate.STRING.get(rs, name) ); - } + public static final LocaleType INSTANCE = new LocaleType(); - public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { - Hibernate.STRING.set(st, value.toString(), index); + public LocaleType() { + super( VarcharTypeDescriptor.INSTANCE, LocaleTypeDescriptor.INSTANCE ); } - public Object fromStringValue(String string) { - if (string == null) { - return null; - } - else { - StringTokenizer tokens = new StringTokenizer(string, "_"); - String language = tokens.hasMoreTokens() ? tokens.nextToken() : ""; - String country = tokens.hasMoreTokens() ? tokens.nextToken() : ""; - // Need to account for allowable '_' within the variant - String variant = ""; - String sep = ""; - while ( tokens.hasMoreTokens() ) { - variant += sep + tokens.nextToken(); - sep = "_"; - } - return new Locale(language, country, variant); - } - } - - public int compare(Object x, Object y, EntityMode entityMode) { - return x.toString().compareTo( y.toString() ); - } - - public int sqlType() { - return Hibernate.STRING.sqlType(); - } - - public String toString(Object value) throws HibernateException { - return value.toString(); - } - - public Class getReturnedClass() { - return Locale.class; - } - public String getName() { return "locale"; } - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return ( (LiteralType) Hibernate.STRING ).objectToSQLString( value.toString(), dialect ); + @Override + protected boolean registerUnderJavaType() { + return true; } + public String objectToSQLString(Locale value, Dialect dialect) throws Exception { + return StringType.INSTANCE.objectToSQLString( toString( value ), dialect ); + } } - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/LongType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/LongType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/LongType.java 17 Aug 2012 14:36:27 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/LongType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,80 +20,77 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; import java.util.Comparator; -import org.hibernate.util.ComparableComparator; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.type.descriptor.java.LongTypeDescriptor; +import org.hibernate.type.descriptor.sql.BigIntTypeDescriptor; /** - * long: A type that maps an SQL BIGINT to a Java Long. + * A type that maps between {@link java.sql.Types#BIGINT BIGINT} and {@link Long} + * * @author Gavin King + * @author Steve Ebersole */ -public class LongType extends PrimitiveType implements DiscriminatorType, VersionType { +public class LongType + extends AbstractSingleColumnStandardBasicType + implements PrimitiveType, DiscriminatorType, VersionType { - private static final Long ZERO = new Long(0); + public static final LongType INSTANCE = new LongType(); - public Serializable getDefaultValue() { - return ZERO; + private static final Long ZERO = (long) 0; + + public LongType() { + super( BigIntTypeDescriptor.INSTANCE, LongTypeDescriptor.INSTANCE ); } - - public Object get(ResultSet rs, String name) throws SQLException { - return new Long( rs.getLong(name) ); - } - public Class getPrimitiveClass() { - return long.class; + @Override + public String getName() { + return "long"; } - public Class getReturnedClass() { - return Long.class; + @Override + public String[] getRegistrationKeys() { + return new String[] { getName(), long.class.getName(), Long.class.getName() }; } - public void set(PreparedStatement st, Object value, int index) - throws SQLException { - - st.setLong( index, ( (Long) value ).longValue() ); + @Override + public Serializable getDefaultValue() { + return ZERO; } - public int sqlType() { - return Types.BIGINT; + @Override + public Class getPrimitiveClass() { + return long.class; } - public String getName() { return "long"; } - - public Object stringToObject(String xml) throws Exception { - return new Long(xml); + @Override + public Long stringToObject(String xml) throws Exception { + return Long.valueOf( xml ); } - public Object next(Object current, SessionImplementor session) { - return new Long( ( (Long) current ).longValue() + 1 ); + @Override + public Long next(Long current, SessionImplementor session) { + return current + 1L; } - public Object seed(SessionImplementor session) { + @Override + public Long seed(SessionImplementor session) { return ZERO; } - public Comparator getComparator() { - return ComparableComparator.INSTANCE; + @Override + public Comparator getComparator() { + return getJavaTypeDescriptor().getComparator(); } - - public String objectToSQLString(Object value, Dialect dialect) throws Exception { + + @Override + public String objectToSQLString(Long value, Dialect dialect) throws Exception { return value.toString(); } - - public Object fromStringValue(String xml) { - return new Long(xml); - } - - } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/ManyToOneType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/ManyToOneType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/ManyToOneType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/ManyToOneType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; @@ -33,10 +32,11 @@ import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.engine.EntityKey; -import org.hibernate.engine.ForeignKeys; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.internal.ForeignKeys; +import org.hibernate.engine.spi.EntityKey; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.metamodel.relational.Size; import org.hibernate.persister.entity.EntityPersister; /** @@ -45,44 +45,98 @@ * @author Gavin King */ public class ManyToOneType extends EntityType { - private final boolean ignoreNotFound; + private boolean isLogicalOneToOne; - public ManyToOneType(String className) { - this( className, false ); + /** + * Creates a many-to-one association type with the given referenced entity. + * + * @param scope The scope for this instance. + * @param referencedEntityName The name iof the referenced entity + */ + public ManyToOneType(TypeFactory.TypeScope scope, String referencedEntityName) { + this( scope, referencedEntityName, false ); } - public ManyToOneType(String className, boolean lazy) { - super( className, null, !lazy, true, false ); - this.ignoreNotFound = false; + /** + * Creates a many-to-one association type with the given referenced entity and the + * given laziness characteristic + * + * @param scope The scope for this instance. + * @param referencedEntityName The name iof the referenced entity + * @param lazy Should the association be handled lazily + */ + public ManyToOneType(TypeFactory.TypeScope scope, String referencedEntityName, boolean lazy) { + this( scope, referencedEntityName, true, null, lazy, true, false, false ); } + + /** + * @deprecated Use {@link #ManyToOneType(TypeFactory.TypeScope, String, boolean, String, boolean, boolean, boolean, boolean ) } instead. + */ + @Deprecated public ManyToOneType( - String entityName, + TypeFactory.TypeScope scope, + String referencedEntityName, String uniqueKeyPropertyName, boolean lazy, boolean unwrapProxy, boolean isEmbeddedInXML, - boolean ignoreNotFound) { - super( entityName, uniqueKeyPropertyName, !lazy, isEmbeddedInXML, unwrapProxy ); + boolean ignoreNotFound, + boolean isLogicalOneToOne) { + this( scope, referencedEntityName, uniqueKeyPropertyName == null, uniqueKeyPropertyName, lazy, unwrapProxy, ignoreNotFound, isLogicalOneToOne ); + } + + /** + * @deprecated Use {@link #ManyToOneType(TypeFactory.TypeScope, String, boolean, String, boolean, boolean, boolean, boolean ) } instead. + * See Jira issue: HHH-7771 + */ + @Deprecated + public ManyToOneType( + TypeFactory.TypeScope scope, + String referencedEntityName, + String uniqueKeyPropertyName, + boolean lazy, + boolean unwrapProxy, + boolean ignoreNotFound, + boolean isLogicalOneToOne) { + this( scope, referencedEntityName, uniqueKeyPropertyName == null, uniqueKeyPropertyName, lazy, unwrapProxy, ignoreNotFound, isLogicalOneToOne ); + } + + public ManyToOneType( + TypeFactory.TypeScope scope, + String referencedEntityName, + boolean referenceToPrimaryKey, + String uniqueKeyPropertyName, + boolean lazy, + boolean unwrapProxy, + boolean ignoreNotFound, + boolean isLogicalOneToOne) { + super( scope, referencedEntityName, referenceToPrimaryKey, uniqueKeyPropertyName, !lazy, unwrapProxy ); this.ignoreNotFound = ignoreNotFound; + this.isLogicalOneToOne = isLogicalOneToOne; } protected boolean isNullable() { return ignoreNotFound; } public boolean isAlwaysDirtyChecked() { - // If we have not-found="ignore" association mapped to a - // formula, we always need to dirty check it, so we can update the - // second-level cache - return ignoreNotFound; + // always need to dirty-check, even when non-updateable; + // this ensures that when the association is updated, + // the entity containing this association will be updated + // in the cache + return true; } public boolean isOneToOne() { return false; } - + + public boolean isLogicalOneToOne() { + return isLogicalOneToOne; + } + public int getColumnSpan(Mapping mapping) throws MappingException { // our column span is the number of columns in the PK return getIdentifierOrUniqueKeyType( mapping ).getColumnSpan( mapping ); @@ -92,6 +146,16 @@ return getIdentifierOrUniqueKeyType( mapping ).sqlTypes( mapping ); } + @Override + public Size[] dictatedSizes(Mapping mapping) throws MappingException { + return getIdentifierOrUniqueKeyType( mapping ).dictatedSizes( mapping ); + } + + @Override + public Size[] defaultSizes(Mapping mapping) throws MappingException { + return getIdentifierOrUniqueKeyType( mapping ).defaultSizes( mapping ); + } + public void nullSafeSet( PreparedStatement st, Object value, @@ -123,7 +187,7 @@ // return the (fully resolved) identifier value, but do not resolve // to the actual referenced entity instance // NOTE: the owner of the association is not really the owner of the id! - Serializable id = (Serializable) getIdentifierOrUniqueKeyType( session.getFactory() ) + final Serializable id = (Serializable) getIdentifierOrUniqueKeyType( session.getFactory() ) .nullSafeGet( rs, names, session, null ); scheduleBatchLoadIfNeeded( id, session ); return id; @@ -132,21 +196,20 @@ /** * Register the entity as batch loadable, if enabled */ - private void scheduleBatchLoadIfNeeded( - Serializable id, - SessionImplementor session) throws MappingException { + @SuppressWarnings({ "JavaDoc" }) + private void scheduleBatchLoadIfNeeded(Serializable id, SessionImplementor session) throws MappingException { //cannot batch fetch by unique key (property-ref associations) if ( uniqueKeyPropertyName == null && id != null ) { - EntityPersister persister = session.getFactory().getEntityPersister( getAssociatedEntityName() ); - EntityKey entityKey = new EntityKey( id, persister, session.getEntityMode() ); - if ( !session.getPersistenceContext().containsEntity( entityKey ) ) { - session.getPersistenceContext() - .getBatchFetchQueue() - .addBatchLoadableEntityKey( entityKey ); + final EntityPersister persister = getAssociatedEntityPersister( session.getFactory() ); + if ( persister.isBatchLoadable() ) { + final EntityKey entityKey = session.generateEntityKey( id, persister ); + if ( !session.getPersistenceContext().containsEntity( entityKey ) ) { + session.getPersistenceContext().getBatchFetchQueue().addBatchLoadableEntityKey( entityKey ); + } } } } - + public boolean useLHSPrimaryKey() { return false; } @@ -183,9 +246,9 @@ else { // cache the actual id of the object, not the value of the // property-ref, which might not be initialized - Object id = ForeignKeys.getEntityIdentifierIfNotUnsaved( - getAssociatedEntityName(), - value, + Object id = ForeignKeys.getEntityIdentifierIfNotUnsaved( + getAssociatedEntityName(), + value, session ); if ( id == null ) { @@ -241,7 +304,7 @@ Object old, Object current, SessionImplementor session) throws HibernateException { - if ( isSame( old, current, session.getEntityMode() ) ) { + if ( isSame( old, current ) ) { return false; } Object oldid = getIdentifier( old, session ); @@ -258,7 +321,7 @@ return isDirty( old, current, session ); } else { - if ( isSame( old, current, session.getEntityMode() ) ) { + if ( isSame( old, current ) ) { return false; } Object oldid = getIdentifier( old, session ); Index: 3rdParty_sources/hibernate-core/org/hibernate/type/MapType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/MapType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/MapType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/MapType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; @@ -29,29 +28,30 @@ import java.util.Iterator; import java.util.Map; -import org.dom4j.Element; -import org.hibernate.EntityMode; import org.hibernate.HibernateException; -import org.hibernate.collection.PersistentCollection; -import org.hibernate.collection.PersistentMap; -import org.hibernate.collection.PersistentMapElementHolder; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.collection.internal.PersistentMap; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; public class MapType extends CollectionType { - public MapType(String role, String propertyRef, boolean isEmbeddedInXML) { - super(role, propertyRef, isEmbeddedInXML); + /** + * @deprecated Use {@link #MapType(TypeFactory.TypeScope, String, String ) } instead. + * See Jira issue: HHH-7771 + */ + @Deprecated + public MapType(TypeFactory.TypeScope typeScope, String role, String propertyRef, boolean isEmbeddedInXML) { + super( typeScope, role, propertyRef, isEmbeddedInXML ); } + public MapType(TypeFactory.TypeScope typeScope, String role, String propertyRef) { + super( typeScope, role, propertyRef ); + } + public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) { - if ( session.getEntityMode()==EntityMode.DOM4J ) { - return new PersistentMapElementHolder(session, persister, key); - } - else { - return new PersistentMap(session); - } + return new PersistentMap(session); } public Class getReturnedClass() { @@ -63,12 +63,7 @@ } public PersistentCollection wrap(SessionImplementor session, Object collection) { - if ( session.getEntityMode()==EntityMode.DOM4J ) { - return new PersistentMapElementHolder( session, (Element) collection ); - } - else { - return new PersistentMap( session, (java.util.Map) collection ); - } + return new PersistentMap( session, (java.util.Map) collection ); } public Object instantiate(int anticipatedSize) { Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/MaterializedBlobType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/MaterializedClobType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/MaterializedNClobType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/MetaType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/MetaType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/MetaType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/MetaType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,49 +20,65 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import org.dom4j.Node; -import org.hibernate.EntityMode; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.metamodel.relational.Size; +import org.dom4j.Node; + /** * @author Gavin King */ public class MetaType extends AbstractType { + public static final String[] REGISTRATION_KEYS = new String[0]; - private final Map values; - private final Map keys; private final Type baseType; + private final Map discriminatorValuesToEntityNameMap; + private final Map entityNameToDiscriminatorValueMap; - public MetaType(Map values, Type baseType) { + public MetaType(Map discriminatorValuesToEntityNameMap, Type baseType) { this.baseType = baseType; - this.values = values; - keys = new HashMap(); - Iterator iter = values.entrySet().iterator(); - while ( iter.hasNext() ) { - Map.Entry me = (Map.Entry) iter.next(); - keys.put( me.getValue(), me.getKey() ); + this.discriminatorValuesToEntityNameMap = discriminatorValuesToEntityNameMap; + this.entityNameToDiscriminatorValueMap = new HashMap(); + for ( Map.Entry entry : discriminatorValuesToEntityNameMap.entrySet() ) { + entityNameToDiscriminatorValueMap.put( entry.getValue(), entry.getKey() ); } } + public String[] getRegistrationKeys() { + return REGISTRATION_KEYS; + } + + public Map getDiscriminatorValuesToEntityNameMap() { + return discriminatorValuesToEntityNameMap; + } + public int[] sqlTypes(Mapping mapping) throws MappingException { return baseType.sqlTypes(mapping); } + @Override + public Size[] dictatedSizes(Mapping mapping) throws MappingException { + return baseType.dictatedSizes( mapping ); + } + + @Override + public Size[] defaultSizes(Mapping mapping) throws MappingException { + return baseType.defaultSizes( mapping ); + } + public int getColumnSpan(Mapping mapping) throws MappingException { return baseType.getColumnSpan(mapping); } @@ -78,7 +94,7 @@ Object owner) throws HibernateException, SQLException { Object key = baseType.nullSafeGet(rs, names, session, owner); - return key==null ? null : values.get(key); + return key==null ? null : discriminatorValuesToEntityNameMap.get(key); } public Object nullSafeGet( @@ -88,12 +104,12 @@ Object owner) throws HibernateException, SQLException { Object key = baseType.nullSafeGet(rs, name, session, owner); - return key==null ? null : values.get(key); + return key==null ? null : discriminatorValuesToEntityNameMap.get(key); } public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException { - baseType.nullSafeSet(st, value==null ? null : keys.get(value), index, session); + baseType.nullSafeSet(st, value==null ? null : entityNameToDiscriminatorValueMap.get(value), index, session); } public void nullSafeSet( @@ -124,7 +140,7 @@ return baseType.getName(); //TODO! } - public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) + public Object deepCopy(Object value, SessionFactoryImplementor factory) throws HibernateException { return value; } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/MutableType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/MutableType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/MutableType.java 17 Aug 2012 14:36:27 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/MutableType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,20 +20,19 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; - import java.util.Map; -import org.hibernate.EntityMode; import org.hibernate.HibernateException; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; /** * Superclass for mutable nullable types * @author Gavin King + * + * @deprecated Use the {@link AbstractStandardBasicType} approach instead */ public abstract class MutableType extends NullableType { @@ -43,20 +42,20 @@ protected abstract Object deepCopyNotNull(Object value) throws HibernateException; - public final Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) - throws HibernateException { + public final Object deepCopy(Object value, SessionFactoryImplementor factory) throws HibernateException { return (value==null) ? null : deepCopyNotNull(value); } public Object replace( - Object original, - Object target, - SessionImplementor session, - Object owner, - Map copyCache) - throws HibernateException { - if ( isEqual( original, target, session.getEntityMode() ) ) return original; - return deepCopy( original, session.getEntityMode(), session.getFactory() ); + Object original, + Object target, + SessionImplementor session, + Object owner, + Map copyCache) throws HibernateException { + if ( isEqual( original, target ) ) { + return original; + } + return deepCopy( original, session.getFactory() ); } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/NClobType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/NTextType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/NullableType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/NullableType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/NullableType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/NullableType.java 30 Jul 2014 16:15:59 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,53 +20,70 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import org.slf4j.LoggerFactory; -import org.slf4j.Logger; -import org.dom4j.Node; - -import org.hibernate.EntityMode; import org.hibernate.HibernateException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.util.ArrayHelper; -import org.hibernate.util.EqualsHelper; -import org.hibernate.util.StringHelper; +import org.hibernate.MappingException; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.internal.util.compare.EqualsHelper; +import org.hibernate.metamodel.relational.Size; +import org.jboss.logging.Logger; + +import org.dom4j.Node; + /** * Superclass of single-column nullable types. - * + * * @author Gavin King + * + * @deprecated Use the {@link AbstractStandardBasicType} approach instead */ -public abstract class NullableType extends AbstractType { +@Deprecated +public abstract class NullableType extends AbstractType implements StringRepresentableType, XmlRepresentableType { + private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, NullableType.class.getName()); + private final Size dictatedSize = new Size(); + /** - * This is the old scheme where logging of parameter bindings and value extractions - * was controlled by the trace level enablement on the 'org.hibernate.type' package... - *

        - * Originally was cached such because of performance of looking up the logger each time - * in order to check the trace-enablement. Driving this via a central Log-specific class - * would alleviate that performance hit, and yet still allow more "normal" logging usage/config. + * A convenience form of {@link #sqlTypes(org.hibernate.engine.spi.Mapping)}, returning + * just a single type value since these are explicitly dealing with single column + * mappings. + * + * @return The {@link java.sql.Types} mapping value. */ - private static final boolean IS_VALUE_TRACING_ENABLED = LoggerFactory.getLogger( StringHelper.qualifier( Type.class.getName() ) ).isTraceEnabled(); - private transient Logger log; + public abstract int sqlType(); - private Logger log() { - if ( log == null ) { - log = LoggerFactory.getLogger( getClass() ); - } - return log; + /** + * A convenience form of {@link #dictatedSizes}, returning just a single size since we are explicitly dealing with + * single column mappings here. + * + * @return The {@link java.sql.Types} mapping value. + */ + public Size dictatedSize() { + return dictatedSize; } /** + * A convenience form of {@link #defaultSizes}, returning just a single size since we are explicitly dealing with + * single column mappings here. + * + * @return The {@link java.sql.Types} mapping value. + */ + public Size defaultSize() { + return LEGACY_DEFAULT_SIZE; + } + + /** * Get a column value from a result set, without worrying about the * possibility of null values. Called from {@link #nullSafeGet} after * nullness checks have been performed. @@ -96,15 +113,6 @@ public abstract void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException; /** - * A convenience form of {@link #sqlTypes(org.hibernate.engine.Mapping)}, returning - * just a single type value since these are explicitly dealing with single column - * mappings. - * - * @return The {@link java.sql.Types} mapping value. - */ - public abstract int sqlType(); - - /** * A null-safe version of {@link #toString(Object)}. Specifically we are * worried about null safeness in regards to the incoming value parameter, * not the return. @@ -140,26 +148,22 @@ throws HibernateException, SQLException { try { if ( value == null ) { - if ( IS_VALUE_TRACING_ENABLED ) { - log().trace( "binding null to parameter: " + index ); - } + LOG.tracev("Binding null to parameter: {0}", index); st.setNull( index, sqlType() ); } else { - if ( IS_VALUE_TRACING_ENABLED ) { - log().trace( "binding '" + toString( value ) + "' to parameter: " + index ); - } + if (LOG.isTraceEnabled()) LOG.tracev("Binding '{0}' to parameter: {1}", toString(value), index); set( st, value, index ); } } catch ( RuntimeException re ) { - log().info( "could not bind value '" + nullSafeToString( value ) + "' to parameter: " + index + "; " + re.getMessage() ); + LOG.unableToBindValueToParameter( nullSafeToString( value ), index, re.getMessage() ); throw re; } catch ( SQLException se ) { - log().info( "could not bind value '" + nullSafeToString( value ) + "' to parameter: " + index + "; " + se.getMessage() ); + LOG.unableToBindValueToParameter( nullSafeToString( value ), index, se.getMessage() ); throw se; } } @@ -183,31 +187,25 @@ try { Object value = get(rs, name); if ( value == null || rs.wasNull() ) { - if ( IS_VALUE_TRACING_ENABLED ) { - log().trace( "returning null as column: " + name ); - } + LOG.tracev( "Returning null as column {0}", name ); return null; } - else { - if ( IS_VALUE_TRACING_ENABLED ) { - log().trace( "returning '" + toString( value ) + "' as column: " + name ); - } - return value; - } + if ( LOG.isTraceEnabled() ) LOG.trace( "Returning '" + toString( value ) + "' as column " + name ); + return value; } catch ( RuntimeException re ) { - log().info( "could not read column value from result set: " + name + "; " + re.getMessage() ); + LOG.unableToReadColumnValueFromResultSet( name, re.getMessage() ); throw re; } catch ( SQLException se ) { - log().info( "could not read column value from result set: " + name + "; " + se.getMessage() ); + LOG.unableToReadColumnValueFromResultSet( name, se.getMessage() ); throw se; } } public final Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) throws HibernateException, SQLException { - return nullSafeGet(rs, name); + return nullSafeGet( rs, name ); } public final String toXMLString(Object value, SessionFactoryImplementor pc) @@ -227,10 +225,17 @@ return new int[] { sqlType() }; } - public final boolean isEqual(Object x, Object y, EntityMode entityMode) { - return isEqual(x, y); + @Override + public Size[] dictatedSizes(Mapping mapping) throws MappingException { + return new Size[] { dictatedSize() }; } + @Override + public Size[] defaultSizes(Mapping mapping) throws MappingException { + return new Size[] { defaultSize() }; + } + + @Override public boolean isEqual(Object x, Object y) { return EqualsHelper.equals(x, y); } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/NumericBooleanType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/NumericBooleanType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/NumericBooleanType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/NumericBooleanType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,75 +20,47 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.PreparedStatement; -import java.sql.Types; +import java.io.Serializable; import org.hibernate.dialect.Dialect; +import org.hibernate.type.descriptor.java.BooleanTypeDescriptor; +import org.hibernate.type.descriptor.sql.IntegerTypeDescriptor; /** - * Maps {@link Types#INTEGER interger} database values to boolean java values. Zero is considered false; - * NULL maps to {@link #getDefaultValue()}; any other value is considered true. + * A type that maps between {@link java.sql.Types#INTEGER INTEGER} and {@link Boolean} (using 1 and 0) * * @author Steve Ebersole - * @see #getName() */ -public class NumericBooleanType extends BooleanType { +public class NumericBooleanType + extends AbstractSingleColumnStandardBasicType + implements PrimitiveType, DiscriminatorType { - /** - * {@inheritDoc} - *

        - * This type's name is numeric_boolean - */ + public static final NumericBooleanType INSTANCE = new NumericBooleanType(); + + public NumericBooleanType() { + super( IntegerTypeDescriptor.INSTANCE, BooleanTypeDescriptor.INSTANCE ); + } + @Override public String getName() { return "numeric_boolean"; } - - /** - * {@inheritDoc} - */ - public Object get(ResultSet rs, String name) throws SQLException { - int value = rs.getInt( name ); - if ( rs.wasNull() ) { - return getDefaultValue(); - } - else if ( value == 0 ) { - return Boolean.FALSE; - } - else { - return Boolean.TRUE; - } + @Override + public Class getPrimitiveClass() { + return boolean.class; } - - /** - * {@inheritDoc} - */ - public void set(PreparedStatement st, Object value, int index) throws SQLException { - if ( value == null ) { - st.setNull( index, Types.INTEGER ); - } - else { - boolean bool = ( ( Boolean ) value ).booleanValue(); - st.setInt( index, bool ? 1 : 0 ); - } + @Override + public Serializable getDefaultValue() { + return Boolean.FALSE; } - - /** - * {@inheritDoc} - */ - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return ( ( Boolean ) value ).booleanValue() ? "1" : "0"; + @Override + public Boolean stringToObject(String string) { + return fromString( string ); } - - /** - * {@inheritDoc} - */ - public int sqlType() { - return Types.INTEGER; + @Override + public String objectToSQLString(Boolean value, Dialect dialect) { + return value ? "1" : "0"; } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/ObjectType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/OneToOneType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/OneToOneType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/OneToOneType.java 17 Aug 2012 14:36:27 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/OneToOneType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; @@ -31,11 +30,12 @@ import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.engine.EntityKey; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.EntityKey; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.util.collections.ArrayHelper; +import org.hibernate.metamodel.relational.Size; import org.hibernate.persister.entity.EntityPersister; -import org.hibernate.util.ArrayHelper; /** * A one-to-one association to an entity @@ -46,29 +46,73 @@ private final ForeignKeyDirection foreignKeyType; private final String propertyName; private final String entityName; - + + /** + * @deprecated Use {@link #OneToOneType(TypeFactory.TypeScope, String, ForeignKeyDirection, boolean, String, boolean, boolean, String, String)} + * instead. + * See Jira issue: HHH-7771 + */ + @Deprecated + public OneToOneType( + TypeFactory.TypeScope scope, + String referencedEntityName, + ForeignKeyDirection foreignKeyType, + String uniqueKeyPropertyName, + boolean lazy, + boolean unwrapProxy, + boolean isEmbeddedInXML, + String entityName, + String propertyName) { + this( scope, referencedEntityName, foreignKeyType, uniqueKeyPropertyName == null, uniqueKeyPropertyName, lazy, unwrapProxy, entityName, propertyName ); + } + + /** + * @deprecated Use {@link #OneToOneType(TypeFactory.TypeScope, String, ForeignKeyDirection, boolean, String, boolean, boolean, String, String)} + * instead. + */ + @Deprecated + public OneToOneType( + TypeFactory.TypeScope scope, + String referencedEntityName, + ForeignKeyDirection foreignKeyType, + String uniqueKeyPropertyName, + boolean lazy, + boolean unwrapProxy, + String entityName, + String propertyName) { + this( scope, referencedEntityName, foreignKeyType, uniqueKeyPropertyName == null, uniqueKeyPropertyName, lazy, unwrapProxy, entityName, propertyName ); + } + + public OneToOneType( + TypeFactory.TypeScope scope, + String referencedEntityName, + ForeignKeyDirection foreignKeyType, + boolean referenceToPrimaryKey, + String uniqueKeyPropertyName, + boolean lazy, + boolean unwrapProxy, + String entityName, + String propertyName) { + super( scope, referencedEntityName, referenceToPrimaryKey, uniqueKeyPropertyName, !lazy, unwrapProxy ); + this.foreignKeyType = foreignKeyType; + this.propertyName = propertyName; + this.entityName = entityName; + } + public String getPropertyName() { return propertyName; } public boolean isNull(Object owner, SessionImplementor session) { - if ( propertyName != null ) { - - EntityPersister ownerPersister = session.getFactory() - .getEntityPersister(entityName); - Serializable id = session.getContextEntityIdentifier(owner); - - EntityKey entityKey = new EntityKey( id, ownerPersister, session.getEntityMode() ); - - return session.getPersistenceContext() - .isPropertyNull( entityKey, getPropertyName() ); - + final EntityPersister ownerPersister = session.getFactory().getEntityPersister( entityName ); + final Serializable id = session.getContextEntityIdentifier( owner ); + final EntityKey entityKey = session.generateEntityKey( id, ownerPersister ); + return session.getPersistenceContext().isPropertyNull( entityKey, getPropertyName() ); } else { return false; } - } public int getColumnSpan(Mapping session) throws MappingException { @@ -79,32 +123,22 @@ return ArrayHelper.EMPTY_INT_ARRAY; } - public boolean[] toColumnNullness(Object value, Mapping mapping) { - return ArrayHelper.EMPTY_BOOLEAN_ARRAY; + private static final Size[] SIZES = new Size[0]; + + @Override + public Size[] dictatedSizes(Mapping mapping) throws MappingException { + return SIZES; } - public OneToOneType( - String referencedEntityName, - ForeignKeyDirection foreignKeyType, - String uniqueKeyPropertyName, - boolean lazy, - boolean unwrapProxy, - boolean isEmbeddedInXML, - String entityName, - String propertyName - ) { - super( - referencedEntityName, - uniqueKeyPropertyName, - !lazy, - isEmbeddedInXML, - unwrapProxy - ); - this.foreignKeyType = foreignKeyType; - this.propertyName = propertyName; - this.entityName = entityName; + @Override + public Size[] defaultSizes(Mapping mapping) throws MappingException { + return SIZES; } + public boolean[] toColumnNullness(Object value, Mapping mapping) { + return ArrayHelper.EMPTY_BOOLEAN_ARRAY; + } + public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session) { //nothing to do } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/OrderedMapType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/OrderedMapType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/OrderedMapType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/OrderedMapType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,10 +20,8 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; - import java.util.LinkedHashMap; /** @@ -38,14 +36,21 @@ * @param role The collection role name. * @param propertyRef The property ref name. * @param isEmbeddedInXML Is this collection to embed itself in xml + * + * @deprecated Use {@link #OrderedMapType(TypeFactory.TypeScope, String, String)} instead. + * instead. + * See Jira issue: HHH-7771 */ - public OrderedMapType(String role, String propertyRef, boolean isEmbeddedInXML) { - super( role, propertyRef, isEmbeddedInXML ); + @Deprecated + public OrderedMapType(TypeFactory.TypeScope typeScope, String role, String propertyRef, boolean isEmbeddedInXML) { + super( typeScope, role, propertyRef, isEmbeddedInXML ); } - /** - * {@inheritDoc} - */ + public OrderedMapType(TypeFactory.TypeScope typeScope, String role, String propertyRef) { + super( typeScope, role, propertyRef ); + } + + @Override public Object instantiate(int anticipatedSize) { return anticipatedSize > 0 ? new LinkedHashMap( anticipatedSize ) Index: 3rdParty_sources/hibernate-core/org/hibernate/type/OrderedSetType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/OrderedSetType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/OrderedSetType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/OrderedSetType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,10 +20,8 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; - import java.util.LinkedHashSet; /** @@ -35,17 +33,25 @@ * Constructs a set type capable of creating ordered sets of the given * role. * + * @param typeScope The scope for this type instance. * @param role The collection role name. * @param propertyRef The property ref name. * @param isEmbeddedInXML Is this collection to embed itself in xml + * + * @deprecated Use {@link #OrderedSetType(org.hibernate.type.TypeFactory.TypeScope, String, String)} + * instead. + * See Jira issue: HHH-7771 */ - public OrderedSetType(String role, String propertyRef, boolean isEmbeddedInXML) { - super( role, propertyRef, isEmbeddedInXML ); + @Deprecated + public OrderedSetType(TypeFactory.TypeScope typeScope, String role, String propertyRef, boolean isEmbeddedInXML) { + super( typeScope, role, propertyRef, isEmbeddedInXML ); } - /** - * {@inheritDoc} - */ + public OrderedSetType(TypeFactory.TypeScope typeScope, String role, String propertyRef) { + super( typeScope, role, propertyRef ); + } + + @Override public Object instantiate(int anticipatedSize) { return anticipatedSize > 0 ? new LinkedHashSet( anticipatedSize ) Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/PostgresUUIDType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/PrimitiveByteArrayBlobType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/PrimitiveCharacterArrayClobType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/PrimitiveCharacterArrayNClobType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/PrimitiveType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/PrimitiveType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/PrimitiveType.java 17 Aug 2012 14:36:27 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/PrimitiveType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,29 +20,38 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; - import java.io.Serializable; /** - * Superclass of primitive / primitive wrapper types. + * Additional contract for primitive / primitive wrapper types. + * * @author Gavin King + * @author Steve Ebersole */ -public abstract class PrimitiveType extends ImmutableType implements LiteralType { - +public interface PrimitiveType extends LiteralType { + /** + * Retrieve the primitive counterpart to the wrapper type identified by + * {@link org.hibernate.type.Type#getReturnedClass()}. + * + * @return The primitive Java type. + */ public abstract Class getPrimitiveClass(); - public String toString(Object value) { - return value.toString(); - } - - public abstract Serializable getDefaultValue(); + /** + * Retrieve the string representation of the given value. + * + * @param value The value to be stringified. + * + * @return The string representation + */ + public String toString(T value); + /** + * Get this type's default value. + * + * @return The default value. + */ + public abstract Serializable getDefaultValue(); } - - - - - Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/ProcedureParameterExtractionAware.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/SerializableToBlobType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/SerializableType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/SerializableType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/SerializableType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/SerializableType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,110 +20,39 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import org.hibernate.EntityMode; -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.util.SerializationHelper; +import org.hibernate.type.descriptor.java.SerializableTypeDescriptor; +import org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor; /** - * serializable: A type that maps an SQL VARBINARY to a - * serializable Java object. + * A type that maps between a {@link java.sql.Types#VARBINARY VARBINARY} and {@link Serializable} classes. + *

        + * Notice specifically the 2 forms:

          + *
        • {@link #INSTANCE} indicates a mapping using the {@link Serializable} interface itself.
        • + *
        • {@link #SerializableType(Class)} indicates a mapping using the specific class
        • + *
        + * The important distinction has to do with locating the appropriate {@link ClassLoader} to use during deserialization. + * In the fist form we are always using the {@link ClassLoader} of the JVM (Hibernate will always fallback to trying + * its classloader as well). The second form is better at targeting the needed {@link ClassLoader} actually needed. + * * @author Gavin King + * @author Steve Ebersole */ -public class SerializableType extends MutableType { +public class SerializableType extends AbstractSingleColumnStandardBasicType { + public static final SerializableType INSTANCE = new SerializableType( Serializable.class ); - private final Class serializableClass; + private final Class serializableClass; - public SerializableType(Class serializableClass) { + public SerializableType(Class serializableClass) { + super( VarbinaryTypeDescriptor.INSTANCE, new SerializableTypeDescriptor( serializableClass ) ); this.serializableClass = serializableClass; } - public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { - Hibernate.BINARY.set(st, toBytes(value), index); - } - - public Object get(ResultSet rs, String name) throws HibernateException, SQLException { - byte[] bytes = (byte[]) Hibernate.BINARY.get(rs, name); - // Some JDBC drivers erroneously return an empty array here for a null DB value :/ - if ( bytes == null || bytes.length == 0 ) { - return null; - } - else { - return fromBytes(bytes); - } - } - - public Class getReturnedClass() { - return serializableClass; - } - - public boolean isEqual(Object x, Object y) throws HibernateException { - if ( x == y ) { - return true; - } - if ( x == null || y == null ) { - return false; - } - return x.equals( y ) || Hibernate.BINARY.isEqual( toBytes( x ), toBytes( y ) ); - } - - public int getHashCode(Object x, EntityMode entityMode) { - return Hibernate.BINARY.getHashCode( toBytes(x), entityMode ); - } - - public String toString(Object value) throws HibernateException { - return Hibernate.BINARY.toString( toBytes(value) ); - } - - public Object fromStringValue(String xml) throws HibernateException { - return fromBytes( (byte[]) Hibernate.BINARY.fromStringValue(xml) ); - } - public String getName() { return (serializableClass==Serializable.class) ? "serializable" : serializableClass.getName(); } - - public Object deepCopyNotNull(Object value) throws HibernateException { - return fromBytes( toBytes(value) ); - } - - private static byte[] toBytes(Object object) throws SerializationException { - return SerializationHelper.serialize( (Serializable) object ); - } - - private static Object fromBytes( byte[] bytes ) throws SerializationException { - return SerializationHelper.deserialize(bytes); - } - - public int sqlType() { - return Hibernate.BINARY.sqlType(); - } - - public Object assemble(Serializable cached, SessionImplementor session, Object owner) - throws HibernateException { - return (cached==null) ? null : fromBytes( (byte[]) cached ); - } - - public Serializable disassemble(Object value, SessionImplementor session, Object owner) - throws HibernateException { - return (value==null) ? null : toBytes(value); - } - } - - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/SerializationException.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/SerializationException.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/SerializationException.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/SerializationException.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,10 +20,8 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; - import org.hibernate.HibernateException; /** Index: 3rdParty_sources/hibernate-core/org/hibernate/type/SetType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/SetType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/SetType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/SetType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,47 +20,42 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; import java.util.HashSet; -import org.dom4j.Element; -import org.hibernate.EntityMode; -import org.hibernate.collection.PersistentCollection; -import org.hibernate.collection.PersistentElementHolder; -import org.hibernate.collection.PersistentSet; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.collection.internal.PersistentSet; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; public class SetType extends CollectionType { - public SetType(String role, String propertyRef, boolean isEmbeddedInXML) { - super(role, propertyRef, isEmbeddedInXML); + /** + * @deprecated Use {@link #SetType(org.hibernate.type.TypeFactory.TypeScope, String, String)} instead. + * See Jira issue: HHH-7771 + */ + @Deprecated + public SetType(TypeFactory.TypeScope typeScope, String role, String propertyRef, boolean isEmbeddedInXML) { + super( typeScope, role, propertyRef, isEmbeddedInXML ); } + public SetType(TypeFactory.TypeScope typeScope, String role, String propertyRef) { + super( typeScope, role, propertyRef ); + } + public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) { - if ( session.getEntityMode()==EntityMode.DOM4J ) { - return new PersistentElementHolder(session, persister, key); - } - else { - return new PersistentSet(session); - } + return new PersistentSet(session); } public Class getReturnedClass() { return java.util.Set.class; } public PersistentCollection wrap(SessionImplementor session, Object collection) { - if ( session.getEntityMode()==EntityMode.DOM4J ) { - return new PersistentElementHolder( session, (Element) collection ); - } - else { - return new PersistentSet( session, (java.util.Set) collection ); - } + return new PersistentSet( session, (java.util.Set) collection ); } public Object instantiate(int anticipatedSize) { Index: 3rdParty_sources/hibernate-core/org/hibernate/type/ShortType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/ShortType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/ShortType.java 17 Aug 2012 14:36:30 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/ShortType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,82 +20,70 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; import java.util.Comparator; -import org.hibernate.util.ComparableComparator; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.type.descriptor.java.ShortTypeDescriptor; +import org.hibernate.type.descriptor.sql.SmallIntTypeDescriptor; /** - * short: A type that maps an SQL SMALLINT to a Java Short. + * A type that maps between {@link java.sql.Types#SMALLINT SMALLINT} and {@link Short} + * * @author Gavin King + * @author Steve Ebersole */ -public class ShortType extends PrimitiveType implements DiscriminatorType, VersionType { +public class ShortType + extends AbstractSingleColumnStandardBasicType + implements PrimitiveType, DiscriminatorType, VersionType { - private static final Short ZERO = new Short( (short) 0 ); + public static final ShortType INSTANCE = new ShortType(); - public Serializable getDefaultValue() { - return ZERO; - } - - public Object get(ResultSet rs, String name) throws SQLException { - return new Short( rs.getShort(name) ); - } + private static final Short ZERO = (short) 0; - public Class getPrimitiveClass() { - return short.class; + public ShortType() { + super( SmallIntTypeDescriptor.INSTANCE, ShortTypeDescriptor.INSTANCE ); } - - public Class getReturnedClass() { - return Short.class; + @Override + public String getName() { + return "short"; } - public void set(PreparedStatement st, Object value, int index) throws SQLException { - st.setShort( index, ( (Short) value ).shortValue() ); + @Override + public String[] getRegistrationKeys() { + return new String[] { getName(), short.class.getName(), Short.class.getName() }; } - - public int sqlType() { - return Types.SMALLINT; + @Override + public Serializable getDefaultValue() { + return ZERO; } - - public String getName() { return "short"; } - - public String objectToSQLString(Object value, Dialect dialect) throws Exception { + @Override + public Class getPrimitiveClass() { + return short.class; + } + @Override + public String objectToSQLString(Short value, Dialect dialect) throws Exception { return value.toString(); } - - public Object stringToObject(String xml) throws Exception { - return new Short(xml); + @Override + public Short stringToObject(String xml) throws Exception { + return Short.valueOf( xml ); } - - public Object next(Object current, SessionImplementor session) { - return new Short( (short) ( ( (Short) current ).shortValue() + 1 ) ); + @Override + public Short next(Short current, SessionImplementor session) { + return (short) ( current + 1 ); } - - public Object seed(SessionImplementor session) { + @Override + public Short seed(SessionImplementor session) { return ZERO; } - - public Comparator getComparator() { - return ComparableComparator.INSTANCE; + @Override + public Comparator getComparator() { + return getJavaTypeDescriptor().getComparator(); } - - public Object fromStringValue(String xml) { - return new Short(xml); - } } - - - - - Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/SingleColumnType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/SortedMapType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/SortedMapType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/SortedMapType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/SortedMapType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,59 +20,56 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; import java.util.Comparator; import java.util.TreeMap; -import org.dom4j.Element; -import org.hibernate.EntityMode; -import org.hibernate.collection.PersistentCollection; -import org.hibernate.collection.PersistentElementHolder; -import org.hibernate.collection.PersistentMapElementHolder; -import org.hibernate.collection.PersistentSortedMap; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.collection.internal.PersistentSortedMap; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; public class SortedMapType extends MapType { private final Comparator comparator; - public SortedMapType(String role, String propertyRef, Comparator comparator, boolean isEmbeddedInXML) { - super(role, propertyRef, isEmbeddedInXML); + /** + * @deprecated Use {@link #SortedMapType(org.hibernate.type.TypeFactory.TypeScope, String, String, java.util.Comparator)} + * instead. + * See Jira issue: HHH-7771 + */ + @Deprecated + public SortedMapType(TypeFactory.TypeScope typeScope, String role, String propertyRef, Comparator comparator, boolean isEmbeddedInXML) { + super( typeScope, role, propertyRef, isEmbeddedInXML ); this.comparator = comparator; } + public SortedMapType(TypeFactory.TypeScope typeScope, String role, String propertyRef, Comparator comparator) { + super( typeScope, role, propertyRef ); + this.comparator = comparator; + } + public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) { - if ( session.getEntityMode()==EntityMode.DOM4J ) { - return new PersistentMapElementHolder(session, persister, key); - } - else { - PersistentSortedMap map = new PersistentSortedMap(session); - map.setComparator(comparator); - return map; - } + PersistentSortedMap map = new PersistentSortedMap(session); + map.setComparator(comparator); + return map; } public Class getReturnedClass() { return java.util.SortedMap.class; } + @SuppressWarnings( {"unchecked"}) public Object instantiate(int anticipatedSize) { return new TreeMap(comparator); } public PersistentCollection wrap(SessionImplementor session, Object collection) { - if ( session.getEntityMode()==EntityMode.DOM4J ) { - return new PersistentElementHolder( session, (Element) collection ); - } - else { - return new PersistentSortedMap( session, (java.util.SortedMap) collection ); - } + return new PersistentSortedMap( session, (java.util.SortedMap) collection ); } } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/SortedSetType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/SortedSetType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/SortedSetType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/SortedSetType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,62 +20,53 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; import java.util.Comparator; import java.util.TreeSet; -import org.dom4j.Element; -import org.hibernate.EntityMode; -import org.hibernate.collection.PersistentCollection; -import org.hibernate.collection.PersistentElementHolder; -import org.hibernate.collection.PersistentSortedSet; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.collection.internal.PersistentSortedSet; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; public class SortedSetType extends SetType { - private final Comparator comparator; - public SortedSetType(String role, String propertyRef, Comparator comparator, boolean isEmbeddedInXML) { - super(role, propertyRef, isEmbeddedInXML); + /** + * @deprecated Use {@link #SortedSetType(org.hibernate.type.TypeFactory.TypeScope, String, String, java.util.Comparator)} + * instead. + * See Jira issue: HHH-7771 + */ + @Deprecated + public SortedSetType(TypeFactory.TypeScope typeScope, String role, String propertyRef, Comparator comparator, boolean isEmbeddedInXML) { + super( typeScope, role, propertyRef, isEmbeddedInXML ); this.comparator = comparator; } + public SortedSetType(TypeFactory.TypeScope typeScope, String role, String propertyRef, Comparator comparator) { + super( typeScope, role, propertyRef ); + this.comparator = comparator; + } + public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) { - if ( session.getEntityMode()==EntityMode.DOM4J ) { - return new PersistentElementHolder(session, persister, key); - } - else { - PersistentSortedSet set = new PersistentSortedSet(session); - set.setComparator(comparator); - return set; - } + PersistentSortedSet set = new PersistentSortedSet(session); + set.setComparator(comparator); + return set; } public Class getReturnedClass() { return java.util.SortedSet.class; } + @SuppressWarnings( {"unchecked"}) public Object instantiate(int anticipatedSize) { return new TreeSet(comparator); } public PersistentCollection wrap(SessionImplementor session, Object collection) { - if ( session.getEntityMode()==EntityMode.DOM4J ) { - return new PersistentElementHolder( session, (Element) collection ); - } - else { - return new PersistentSortedSet( session, (java.util.SortedSet) collection ); - } + return new PersistentSortedSet( session, (java.util.SortedSet) collection ); } } - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/SpecialOneToOneType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/SpecialOneToOneType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/SpecialOneToOneType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/SpecialOneToOneType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; @@ -31,9 +30,10 @@ import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.engine.ForeignKeys; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.internal.ForeignKeys; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.metamodel.relational.Size; /** * A one-to-one association that maps to specific formula(s) @@ -43,35 +43,63 @@ */ public class SpecialOneToOneType extends OneToOneType { + /** + * @deprecated Use {@link #SpecialOneToOneType(org.hibernate.type.TypeFactory.TypeScope, String, ForeignKeyDirection, boolean, String, boolean, boolean, String, String)} instead. + */ + @Deprecated public SpecialOneToOneType( + TypeFactory.TypeScope scope, String referencedEntityName, ForeignKeyDirection foreignKeyType, String uniqueKeyPropertyName, boolean lazy, boolean unwrapProxy, String entityName, - String propertyName - ) { + String propertyName) { + this( scope, referencedEntityName, foreignKeyType, uniqueKeyPropertyName == null, uniqueKeyPropertyName, lazy, unwrapProxy, entityName, propertyName ); + } + + public SpecialOneToOneType( + TypeFactory.TypeScope scope, + String referencedEntityName, + ForeignKeyDirection foreignKeyType, + boolean referenceToPrimaryKey, + String uniqueKeyPropertyName, + boolean lazy, + boolean unwrapProxy, + String entityName, + String propertyName) { super( + scope, referencedEntityName, - foreignKeyType, + foreignKeyType, + referenceToPrimaryKey, uniqueKeyPropertyName, lazy, unwrapProxy, - true, entityName, propertyName ); } public int getColumnSpan(Mapping mapping) throws MappingException { - return super.getIdentifierOrUniqueKeyType(mapping).getColumnSpan(mapping); + return super.getIdentifierOrUniqueKeyType( mapping ).getColumnSpan( mapping ); } public int[] sqlTypes(Mapping mapping) throws MappingException { - return super.getIdentifierOrUniqueKeyType(mapping).sqlTypes(mapping); + return super.getIdentifierOrUniqueKeyType( mapping ).sqlTypes( mapping ); } + @Override + public Size[] dictatedSizes(Mapping mapping) throws MappingException { + return super.getIdentifierOrUniqueKeyType( mapping ).dictatedSizes( mapping ); + } + + @Override + public Size[] defaultSizes(Mapping mapping) throws MappingException { + return super.getIdentifierOrUniqueKeyType( mapping ).defaultSizes( mapping ); + } + public boolean useLHSPrimaryKey() { return false; } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/StandardBasicTypes.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/StringClobType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/StringNVarcharType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/StringRepresentableType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/StringType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/StringType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/StringType.java 17 Aug 2012 14:36:27 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/StringType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,60 +20,46 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; - import org.hibernate.dialect.Dialect; +import org.hibernate.type.descriptor.java.StringTypeDescriptor; +import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor; /** - * string: A type that maps an SQL VARCHAR to a Java String. + * A type that maps between {@link java.sql.Types#VARCHAR VARCHAR} and {@link String} + * * @author Gavin King + * @author Steve Ebersole */ -public class StringType extends ImmutableType implements DiscriminatorType { +public class StringType + extends AbstractSingleColumnStandardBasicType + implements DiscriminatorType { - public Object get(ResultSet rs, String name) throws SQLException { - return rs.getString(name); - } + public static final StringType INSTANCE = new StringType(); - public Class getReturnedClass() { - return String.class; + public StringType() { + super( VarcharTypeDescriptor.INSTANCE, StringTypeDescriptor.INSTANCE ); } - public void set(PreparedStatement st, Object value, int index) throws SQLException { - st.setString(index, (String) value); + public String getName() { + return "string"; } - public int sqlType() { - return Types.VARCHAR; + @Override + protected boolean registerUnderJavaType() { + return true; } - public String getName() { return "string"; } - - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return '\'' + (String) value + '\''; + public String objectToSQLString(String value, Dialect dialect) throws Exception { + return '\'' + value + '\''; } - public Object stringToObject(String xml) throws Exception { + public String stringToObject(String xml) throws Exception { return xml; } - public String toString(Object value) { - return (String) value; + public String toString(String value) { + return value; } - - public Object fromStringValue(String xml) { - return xml; - } - } - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/TextType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/TextType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/TextType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/TextType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,88 +20,27 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; +import org.hibernate.type.descriptor.java.StringTypeDescriptor; +import org.hibernate.type.descriptor.sql.LongVarcharTypeDescriptor; -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; - -import org.hibernate.HibernateException; - /** - * text: A type that maps an SQL CLOB to a Java String. - * @author Gavin King, Bertrand Renuart + * A type that maps between {@link java.sql.Types#LONGVARCHAR LONGVARCHAR} and {@link String} + * + * @author Gavin King, + * @author Bertrand Renuart + * @author Steve Ebersole */ -public class TextType extends ImmutableType { +public class TextType extends AbstractSingleColumnStandardBasicType { + public static final TextType INSTANCE = new TextType(); - public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { - String str = (String) value; - st.setCharacterStream( index, new StringReader(str), str.length() ); + public TextType() { + super( LongVarcharTypeDescriptor.INSTANCE, StringTypeDescriptor.INSTANCE ); } - public Object get(ResultSet rs, String name) throws HibernateException, SQLException { - - // Retrieve the value of the designated column in the current row of this - // ResultSet object as a java.io.Reader object - Reader charReader = rs.getCharacterStream(name); - - // if the corresponding SQL value is NULL, the reader we got is NULL as well - if (charReader==null) return null; - - // Fetch Reader content up to the end - and put characters in a StringBuffer - StringBuffer sb = new StringBuffer(); - try { - char[] buffer = new char[2048]; - while (true) { - int amountRead = charReader.read(buffer, 0, buffer.length); - if ( amountRead == -1 ) break; - sb.append(buffer, 0, amountRead); - } - } - catch (IOException ioe) { - throw new HibernateException( "IOException occurred reading text", ioe ); - } - finally { - try { - charReader.close(); - } - catch (IOException e) { - throw new HibernateException( "IOException occurred closing stream", e ); - } - } - - // Return StringBuffer content as a large String - return sb.toString(); + public String getName() { + return "text"; } - public int sqlType() { - return Types.CLOB; //or Types.LONGVARCHAR? - } - - public Class getReturnedClass() { - return String.class; - } - - public String getName() { return "text"; } - - public String toString(Object val) { - return (String) val; - } - public Object fromStringValue(String xml) { - return xml; - } - } - - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/TimeType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/TimeType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/TimeType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/TimeType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,111 +20,53 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; import java.sql.Time; -import java.sql.Types; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; import java.util.Date; -import org.hibernate.EntityMode; -import org.hibernate.HibernateException; import org.hibernate.dialect.Dialect; +import org.hibernate.type.descriptor.java.JdbcTimeTypeDescriptor; /** - * time: A type that maps an SQL TIME to a Java - * java.util.Date or java.sql.Time. + * A type that maps between {@link java.sql.Types#TIME TIME} and {@link Time} + * * @author Gavin King + * @author Steve Ebersole */ -public class TimeType extends MutableType implements LiteralType { +public class TimeType + extends AbstractSingleColumnStandardBasicType + implements LiteralType { - private static final String TIME_FORMAT = "HH:mm:ss"; + public static final TimeType INSTANCE = new TimeType(); - public Object get(ResultSet rs, String name) throws SQLException { - return rs.getTime(name); + public TimeType() { + super( org.hibernate.type.descriptor.sql.TimeTypeDescriptor.INSTANCE, JdbcTimeTypeDescriptor.INSTANCE ); } - public Class getReturnedClass() { - return java.util.Date.class; - } - public void set(PreparedStatement st, Object value, int index) throws SQLException { - Time time; - if (value instanceof Time) { - time = (Time) value; - } - else { - time = new Time( ( (java.util.Date) value ).getTime() ); - } - st.setTime(index, time); + public String getName() { + return "time"; } - public int sqlType() { - return Types.TIME; + @Override + public String[] getRegistrationKeys() { + return new String[] { + getName(), + java.sql.Time.class.getName() + }; } - public String getName() { return "time"; } - public String toString(Object val) { - return new SimpleDateFormat(TIME_FORMAT).format( (java.util.Date) val ); - } - public boolean isEqual(Object x, Object y) { + // @Override +// protected boolean registerUnderJavaType() { +// return true; +// } - if (x==y) return true; - if (x==null || y==null) return false; - - Date xdate = (Date) x; - Date ydate = (Date) y; - - if ( xdate.getTime()==ydate.getTime() ) return true; - - Calendar calendar1 = java.util.Calendar.getInstance(); - Calendar calendar2 = java.util.Calendar.getInstance(); - calendar1.setTime( xdate ); - calendar2.setTime( ydate ); - - return calendar1.get(Calendar.HOUR_OF_DAY) == calendar2.get(Calendar.HOUR_OF_DAY) - && calendar1.get(Calendar.MINUTE) == calendar2.get(Calendar.MINUTE) - && calendar1.get(Calendar.SECOND) == calendar2.get(Calendar.SECOND) - && calendar1.get(Calendar.MILLISECOND) == calendar2.get(Calendar.MILLISECOND); + public String objectToSQLString(Date value, Dialect dialect) throws Exception { + Time jdbcTime = Time.class.isInstance( value ) + ? ( Time ) value + : new Time( value.getTime() ); + // TODO : use JDBC time literal escape syntax? -> {t 'time-string'} in hh:mm:ss format + return StringType.INSTANCE.objectToSQLString( jdbcTime.toString(), dialect ); } - - public int getHashCode(Object x, EntityMode entityMode) { - Calendar calendar = java.util.Calendar.getInstance(); - calendar.setTime( (java.util.Date) x ); - int hashCode = 1; - hashCode = 31 * hashCode + calendar.get(Calendar.HOUR_OF_DAY); - hashCode = 31 * hashCode + calendar.get(Calendar.MINUTE); - hashCode = 31 * hashCode + calendar.get(Calendar.SECOND); - hashCode = 31 * hashCode + calendar.get(Calendar.MILLISECOND); - return hashCode; - } - - public Object deepCopyNotNull(Object value) { - return new Time( ( (java.util.Date) value ).getTime() ); - } - - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return '\'' + new Time( ( (java.util.Date) value ).getTime() ).toString() + '\''; - } - - public Object fromStringValue(String xml) throws HibernateException { - try { - return new SimpleDateFormat(TIME_FORMAT).parse(xml); - } - catch (ParseException pe) { - throw new HibernateException("could not parse XML", pe); - } - } - } - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/TimeZoneType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/TimeZoneType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/TimeZoneType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/TimeZoneType.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,73 +20,42 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; import java.util.TimeZone; -import org.hibernate.EntityMode; -import org.hibernate.Hibernate; -import org.hibernate.HibernateException; import org.hibernate.dialect.Dialect; +import org.hibernate.type.descriptor.java.TimeZoneTypeDescriptor; +import org.hibernate.type.descriptor.sql.VarcharTypeDescriptor; /** - * timezone: A type that maps an SQL VARCHAR to a - * java.util.TimeZone - * @see java.util.TimeZone + * A type mapping {@link java.sql.Types#VARCHAR VARCHAR} and {@link TimeZone} + * * @author Gavin King + * @author Steve Ebersole */ -public class TimeZoneType extends ImmutableType implements LiteralType { +public class TimeZoneType + extends AbstractSingleColumnStandardBasicType + implements LiteralType { - public Object get(ResultSet rs, String name) - throws HibernateException, SQLException { - String id = (String) Hibernate.STRING.nullSafeGet(rs, name); - return (id==null) ? null : TimeZone.getTimeZone(id); - } + public static final TimeZoneType INSTANCE = new TimeZoneType(); - - public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { - Hibernate.STRING.set(st, ( (TimeZone) value ).getID(), index); + public TimeZoneType() { + super( VarcharTypeDescriptor.INSTANCE, TimeZoneTypeDescriptor.INSTANCE ); } - public int sqlType() { - return Hibernate.STRING.sqlType(); - } - - public String toString(Object value) throws HibernateException { - return ( (TimeZone) value ).getID(); - } - - public int compare(Object x, Object y, EntityMode entityMode) { - return ( (TimeZone) x ).getID().compareTo( ( (TimeZone) y ).getID() ); - } - - public Object fromStringValue(String xml) throws HibernateException { - return TimeZone.getTimeZone(xml); - } - - public Class getReturnedClass() { - return TimeZone.class; - } - public String getName() { return "timezone"; } - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return ( (LiteralType) Hibernate.STRING ).objectToSQLString( - ( (TimeZone) value ).getID(), dialect - ); + @Override + protected boolean registerUnderJavaType() { + return true; } -} + public String objectToSQLString(TimeZone value, Dialect dialect) throws Exception { + return StringType.INSTANCE.objectToSQLString( value.getID(), dialect ); + } - - - - - +} Index: 3rdParty_sources/hibernate-core/org/hibernate/type/TimestampType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/TimestampType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/TimestampType.java 17 Aug 2012 14:36:27 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/TimestampType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,139 +20,65 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; import java.sql.Timestamp; -import java.sql.Types; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.Comparator; +import java.util.Date; -import org.hibernate.EntityMode; import org.hibernate.HibernateException; -import org.hibernate.cfg.Environment; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.util.ComparableComparator; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.type.descriptor.java.JdbcTimestampTypeDescriptor; +import org.hibernate.type.descriptor.sql.TimestampTypeDescriptor; /** - * timestamp: A type that maps an SQL TIMESTAMP to a Java - * java.util.Date or java.sql.Timestamp. + * A type that maps between {@link java.sql.Types#TIMESTAMP TIMESTAMP} and {@link java.sql.Timestamp} + * * @author Gavin King + * @author Steve Ebersole */ -public class TimestampType extends MutableType implements VersionType, LiteralType { +public class TimestampType + extends AbstractSingleColumnStandardBasicType + implements VersionType, LiteralType { - private static final String TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss"; + public static final TimestampType INSTANCE = new TimestampType(); - public Object get(ResultSet rs, String name) throws SQLException { - return rs.getTimestamp(name); + public TimestampType() { + super( TimestampTypeDescriptor.INSTANCE, JdbcTimestampTypeDescriptor.INSTANCE ); } - - public Class getReturnedClass() { - return java.util.Date.class; - } - - public void set(PreparedStatement st, Object value, int index) throws SQLException { - Timestamp ts; - if (value instanceof Timestamp) { - ts = (Timestamp) value; - } - else { - ts = new Timestamp( ( (java.util.Date) value ).getTime() ); - } - st.setTimestamp(index, ts); - } - public int sqlType() { - return Types.TIMESTAMP; + public String getName() { + return "timestamp"; } - - public String getName() { return "timestamp"; } - public String toString(Object val) { - return new SimpleDateFormat(TIMESTAMP_FORMAT).format( (java.util.Date) val ); + @Override + public String[] getRegistrationKeys() { + return new String[] { getName(), Timestamp.class.getName(), java.util.Date.class.getName() }; } - public Object deepCopyNotNull(Object value) { - if ( value instanceof Timestamp ) { - Timestamp orig = (Timestamp) value; - Timestamp ts = new Timestamp( orig.getTime() ); - ts.setNanos( orig.getNanos() ); - return ts; - } - else { - java.util.Date orig = (java.util.Date) value; - return new java.util.Date( orig.getTime() ); - } - } - - public boolean isEqual(Object x, Object y) { - - if (x==y) return true; - if (x==null || y==null) return false; - - long xTime = ( (java.util.Date) x ).getTime(); - long yTime = ( (java.util.Date) y ).getTime(); - boolean xts = x instanceof Timestamp; - boolean yts = y instanceof Timestamp; - int xNanos = xts ? ( (Timestamp) x ).getNanos() : 0; - int yNanos = yts ? ( (Timestamp) y ).getNanos() : 0; - if ( !Environment.jvmHasJDK14Timestamp() ) { - xTime += xNanos / 1000000; - yTime += yNanos / 1000000; - } - if ( xTime!=yTime ) return false; - if (xts && yts) { - // both are Timestamps - int xn = xNanos % 1000000; - int yn = yNanos % 1000000; - return xn==yn; - } - else { - // at least one is a plain old Date - return true; - } - - } - - public int getHashCode(Object x, EntityMode entityMode) { - java.util.Date ts = (java.util.Date) x; - return new Long( ts.getTime() / 1000 ).hashCode(); - } - - public Object next(Object current, SessionImplementor session) { + public Date next(Date current, SessionImplementor session) { return seed( session ); } - public Object seed(SessionImplementor session) { + public Date seed(SessionImplementor session) { return new Timestamp( System.currentTimeMillis() ); } - public Comparator getComparator() { - return ComparableComparator.INSTANCE; + public Comparator getComparator() { + return getJavaTypeDescriptor().getComparator(); } - public String objectToSQLString(Object value, Dialect dialect) throws Exception { - return '\'' + new Timestamp( ( (java.util.Date) value ).getTime() ).toString() + '\''; + public String objectToSQLString(Date value, Dialect dialect) throws Exception { + final Timestamp ts = Timestamp.class.isInstance( value ) + ? ( Timestamp ) value + : new Timestamp( value.getTime() ); + // TODO : use JDBC date literal escape syntax? -> {d 'date-string'} in yyyy-mm-dd hh:mm:ss[.f...] format + return StringType.INSTANCE.objectToSQLString( ts.toString(), dialect ); } - public Object fromStringValue(String xml) throws HibernateException { - try { - return new Timestamp( new SimpleDateFormat(TIMESTAMP_FORMAT).parse(xml).getTime() ); - } - catch (ParseException pe) { - throw new HibernateException("could not parse XML", pe); - } + public Date fromStringValue(String xml) throws HibernateException { + return fromString( xml ); } - } - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/TrueFalseType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/TrueFalseType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/TrueFalseType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/TrueFalseType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,22 +20,49 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; +import java.io.Serializable; + +import org.hibernate.dialect.Dialect; +import org.hibernate.type.descriptor.java.BooleanTypeDescriptor; +import org.hibernate.type.descriptor.sql.CharTypeDescriptor; + /** - * true_false: A type that maps an SQL CHAR(1) to a Java Boolean. + * A type that maps between {@link java.sql.Types#CHAR CHAR(1)} and {@link Boolean} (using 'T' and 'F') + * * @author Gavin King + * @author Steve Ebersole */ -public class TrueFalseType extends CharBooleanType { +public class TrueFalseType + extends AbstractSingleColumnStandardBasicType + implements PrimitiveType, DiscriminatorType { - protected final String getTrueString() { - return "T"; + public static final TrueFalseType INSTANCE = new TrueFalseType(); + + public TrueFalseType() { + super( CharTypeDescriptor.INSTANCE, new BooleanTypeDescriptor( 'T', 'F' ) ); } - protected final String getFalseString() { - return "F"; + @Override + public String getName() { + return "true_false"; } - public String getName() { return "true_false"; } + @Override + public Class getPrimitiveClass() { + return boolean.class; + } + @Override + public Boolean stringToObject(String xml) throws Exception { + return fromString( xml ); + } + @Override + public Serializable getDefaultValue() { + return Boolean.FALSE; + } + @Override + public String objectToSQLString(Boolean value, Dialect dialect) throws Exception { + return StringType.INSTANCE.objectToSQLString( value ? "T" : "F", dialect ); + } } Index: 3rdParty_sources/hibernate-core/org/hibernate/type/Type.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/Type.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/Type.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/Type.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; @@ -30,273 +29,396 @@ import java.sql.SQLException; import java.util.Map; -import org.dom4j.Node; -import org.hibernate.EntityMode; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.engine.Mapping; -import org.hibernate.engine.SessionFactoryImplementor; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.Mapping; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.metamodel.relational.Size; +import org.dom4j.Node; + /** - * Defines a mapping from a Java type to an JDBC datatype. This interface is intended to - * be implemented by applications that need custom types.
        - *
        - * Implementors should usually be immutable and must certainly be threadsafe. + * Defines a mapping between a Java type and one or more JDBC {@linkplain java.sql.Types types}, as well + * as describing the in-memory semantics of the given java type (how do we check it for 'dirtiness', how do + * we copy values, etc). + *

        + * Application developers needing custom types can implement this interface (either directly or via subclassing an + * existing impl) or by the (slightly more stable, though more limited) {@link org.hibernate.usertype.UserType} + * interface. + *

        + * Implementations of this interface must certainly be thread-safe. It is recommended that they be immutable as + * well, though that is difficult to achieve completely given the no-arg constructor requirement for custom types. * * @author Gavin King + * @author Steve Ebersole */ public interface Type extends Serializable { - /** - * Return true if the implementation is castable to - * AssociationType. This does not necessarily imply that - * the type actually represents an association. - * @see AssociationType - * @return boolean + * Return true if the implementation is castable to {@link AssociationType}. This does not necessarily imply that + * the type actually represents an association. Essentially a polymorphic version of + * {@code (type instanceof AssociationType.class)} + * + * @return True if this type is also an {@link AssociationType} implementor; false otherwise. */ public boolean isAssociationType(); + /** - * Is this type a collection type. + * Return true if the implementation is castable to {@link CollectionType}. Essentially a polymorphic version of + * {@code (type instanceof CollectionType.class)} + *

        + * A {@link CollectionType} is additionally an {@link AssociationType}; so if this method returns true, + * {@link #isAssociationType()} should also return true. + * + * @return True if this type is also an {@link CollectionType} implementor; false otherwise. */ public boolean isCollectionType(); /** - * Is this type a component type. If so, the implementation - * must be castable to AbstractComponentType. A component - * type may own collections or associations and hence must provide - * certain extra functionality. - * @see AbstractComponentType - * @return boolean + * Return true if the implementation is castable to {@link EntityType}. Essentially a polymorphic + * version of {@code (type instanceof EntityType.class)}. + *

        + * An {@link EntityType} is additionally an {@link AssociationType}; so if this method returns true, + * {@link #isAssociationType()} should also return true. + * + * @return True if this type is also an {@link EntityType} implementor; false otherwise. */ - public boolean isComponentType(); + public boolean isEntityType(); /** - * Is this type an entity type? - * @return boolean + * Return true if the implementation is castable to {@link AnyType}. Essentially a polymorphic + * version of {@code (type instanceof AnyType.class)}. + *

        + * An {@link AnyType} is additionally an {@link AssociationType}; so if this method returns true, + * {@link #isAssociationType()} should also return true. + * + * @return True if this type is also an {@link AnyType} implementor; false otherwise. */ - public boolean isEntityType(); + public boolean isAnyType(); /** - * Is this an "any" type. + * Return true if the implementation is castable to {@link CompositeType}. Essentially a polymorphic + * version of {@code (type instanceof CompositeType.class)}. A component type may own collections or + * associations and hence must provide certain extra functionality. * - * i.e. a reference to a persistent entity - * that is not modelled as a (foreign key) association. + * @return True if this type is also an {@link CompositeType} implementor; false otherwise. */ - public boolean isAnyType(); - - public boolean isXMLElement(); + public boolean isComponentType(); /** - * Return the SQL type codes for the columns mapped by this type. The codes - * are defined on java.sql.Types. - * @see java.sql.Types - * @return the typecodes - * @throws MappingException + * How many columns are used to persist this type. Always the same as {@code sqlTypes(mapping).length} + * + * @param mapping The mapping object :/ + * + * @return The number of columns + * + * @throws MappingException Generally indicates an issue accessing the passed mapping object. */ + public int getColumnSpan(Mapping mapping) throws MappingException; + + /** + * Return the JDBC types codes (per {@link java.sql.Types}) for the columns mapped by this type. + *

        + * NOTE: The number of elements in this array matches the return from {@link #getColumnSpan}. + * + * @param mapping The mapping object :/ + * + * @return The JDBC type codes. + * + * @throws MappingException Generally indicates an issue accessing the passed mapping object. + */ public int[] sqlTypes(Mapping mapping) throws MappingException; /** - * How many columns are used to persist this type. + * Return the column sizes dictated by this type. For example, the mapping for a {@code char}/{@link Character} would + * have a dictated length limit of 1; for a string-based {@link java.util.UUID} would have a size limit of 36; etc. + *

        + * NOTE: The number of elements in this array matches the return from {@link #getColumnSpan}. + * + * @param mapping The mapping object :/ + * @todo Would be much much better to have this aware of Dialect once the service/metamodel split is done + * + * @return The dictated sizes. + * + * @throws MappingException Generally indicates an issue accessing the passed mapping object. */ - public int getColumnSpan(Mapping mapping) throws MappingException; + public Size[] dictatedSizes(Mapping mapping) throws MappingException; /** - * The class returned by nullSafeGet() methods. This is used to - * establish the class of an array of this type. + * Defines the column sizes to use according to this type if the user did not explicitly say (and if no + * {@link #dictatedSizes} were given). + *

        + * NOTE: The number of elements in this array matches the return from {@link #getColumnSpan}. * - * @return Class + * @param mapping The mapping object :/ + * @todo Would be much much better to have this aware of Dialect once the service/metamodel split is done + * + * @return The default sizes. + * + * @throws MappingException Generally indicates an issue accessing the passed mapping object. */ + public Size[] defaultSizes(Mapping mapping) throws MappingException; + + /** + * The class returned by {@link #nullSafeGet} methods. This is used to establish the class of an array of + * this type. + * + * @return The java type class handled by this type. + */ public Class getReturnedClass(); /** - * Compare two instances of the class mapped by this type for persistence - * "equality" - equality of persistent state - taking a shortcut for - * entity references. - * @param x - * @param y - * @param entityMode + * @deprecated To be removed in 5. Removed as part of removing the notion of DOM entity-mode. + * See Jira issue: HHH-7771 + */ + @SuppressWarnings( {"UnusedDeclaration"}) + @Deprecated + public boolean isXMLElement(); + + /** + * Compare two instances of the class mapped by this type for persistence "equality" (equality of persistent + * state) taking a shortcut for entity references. + *

        + * For most types this should equate to an {@link Object#equals equals} check on the values. For associations + * the implication is a bit different. For most types it is conceivable to simply delegate to {@link #isEqual} * - * @return boolean - * @throws HibernateException + * @param x The first value + * @param y The second value + * + * @return True if there are considered the same (see discussion above). + * + * @throws HibernateException A problem occurred performing the comparison */ - public boolean isSame(Object x, Object y, EntityMode entityMode) throws HibernateException; + public boolean isSame(Object x, Object y) throws HibernateException; /** - * Compare two instances of the class mapped by this type for persistence - * "equality" - equality of persistent state. - * @param x - * @param y - * @param entityMode + * Compare two instances of the class mapped by this type for persistence "equality" (equality of persistent + * state). + *

        + * This should always equate to some form of comparison of the value's internal state. As an example, for + * something like a date the comparison should be based on its internal "time" state based on the specific portion + * it is meant to represent (timestamp, date, time). * - * @return boolean - * @throws HibernateException + * @param x The first value + * @param y The second value + * + * @return True if there are considered equal (see discussion above). + * + * @throws HibernateException A problem occurred performing the comparison */ - public boolean isEqual(Object x, Object y, EntityMode entityMode) throws HibernateException; + public boolean isEqual(Object x, Object y) throws HibernateException; /** - * Compare two instances of the class mapped by this type for persistence - * "equality" - equality of persistent state. - * @param x - * @param y - * @param entityMode + * Compare two instances of the class mapped by this type for persistence "equality" (equality of persistent + * state). + *

        + * This should always equate to some form of comparison of the value's internal state. As an example, for + * something like a date the comparison should be based on its internal "time" state based on the specific portion + * it is meant to represent (timestamp, date, time). * - * @return boolean - * @throws HibernateException + * @param x The first value + * @param y The second value + * @param factory The session factory + * + * @return True if there are considered equal (see discussion above). + * + * @throws HibernateException A problem occurred performing the comparison */ - public boolean isEqual(Object x, Object y, EntityMode entityMode, SessionFactoryImplementor factory) - throws HibernateException; + public boolean isEqual(Object x, Object y, SessionFactoryImplementor factory) throws HibernateException; /** - * Get a hashcode, consistent with persistence "equality" - * @param x - * @param entityMode + * Get a hash code, consistent with persistence "equality". Again for most types the normal usage is to + * delegate to the value's {@link Object#hashCode hashCode}. + * + * @param x The value for which to retrieve a hash code + * @return The hash code + * + * @throws HibernateException A problem occurred calculating the hash code */ - public int getHashCode(Object x, EntityMode entityMode) throws HibernateException; + public int getHashCode(Object x) throws HibernateException; /** - * Get a hashcode, consistent with persistence "equality" - * @param x - * @param entityMode - * @param factory + * Get a hash code, consistent with persistence "equality". Again for most types the normal usage is to + * delegate to the value's {@link Object#hashCode hashCode}. + * + * @param x The value for which to retrieve a hash code + * @param factory The session factory + * + * @return The hash code + * + * @throws HibernateException A problem occurred calculating the hash code */ - public int getHashCode(Object x, EntityMode entityMode, SessionFactoryImplementor factory) - throws HibernateException; + public int getHashCode(Object x, SessionFactoryImplementor factory) throws HibernateException; /** - * compare two instances of the type - * @param entityMode + * Perform a {@link java.util.Comparator} style comparison between values + * + * @param x The first value + * @param y The second value + * + * @return The comparison result. See {@link java.util.Comparator#compare} for a discussion. */ - public int compare(Object x, Object y, EntityMode entityMode); + public int compare(Object x, Object y); /** - * Should the parent be considered dirty, given both the old and current field or - * element value? + * Should the parent be considered dirty, given both the old and current value? * * @param old the old value * @param current the current value - * @param session + * @param session The session from which the request originated. + * * @return true if the field is dirty + * + * @throws HibernateException A problem occurred performing the checking */ - public boolean isDirty(Object old, Object current, SessionImplementor session) - throws HibernateException; + public boolean isDirty(Object old, Object current, SessionImplementor session) throws HibernateException; + /** - * Should the parent be considered dirty, given both the old and current field or - * element value? - * - * @param old the old value - * @param current the current value - * @param checkable which columns are actually updatable - * @param session + * Should the parent be considered dirty, given both the old and current value? + * + * @param oldState the old value + * @param currentState the current value + * @param checkable An array of booleans indicating which columns making up the value are actually checkable + * @param session The session from which the request originated. + * * @return true if the field is dirty + * + * @throws HibernateException A problem occurred performing the checking */ - public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) - throws HibernateException; + public boolean isDirty(Object oldState, Object currentState, boolean[] checkable, SessionImplementor session) + throws HibernateException; /** - * Has the parent object been modified, compared to the current database state? - * @param oldHydratedState the database state, in a "hydrated" form, with identifiers unresolved + * Has the value been modified compared to the current database state? The difference between this + * and the {@link #isDirty} methods is that here we need to account for "partially" built values. This is really + * only an issue with association types. For most type implementations it is enough to simply delegate to + * {@link #isDirty} here/ + * + * @param dbState the database state, in a "hydrated" form, with identifiers unresolved * @param currentState the current state of the object * @param checkable which columns are actually updatable - * @param session + * @param session The session from which the request originated. + * * @return true if the field has been modified + * + * @throws HibernateException A problem occurred performing the checking */ - public boolean isModified(Object oldHydratedState, Object currentState, boolean[] checkable, SessionImplementor session) - throws HibernateException; + public boolean isModified(Object dbState, Object currentState, boolean[] checkable, SessionImplementor session) + throws HibernateException; /** - * Retrieve an instance of the mapped class from a JDBC resultset. Implementors + * Extract a value of the {@link #getReturnedClass() mapped class} from the JDBC result set. Implementors * should handle possibility of null values. * - * @see Type#hydrate(ResultSet, String[], SessionImplementor, Object) alternative, 2-phase property initialization - * @param rs - * @param names the column names - * @param session + * @param rs The result set from which to extract value. + * @param names the column names making up this type value (use to read from result set) + * @param session The originating session * @param owner the parent entity - * @return Object - * @throws HibernateException - * @throws SQLException + * + * @return The extracted value + * + * @throws HibernateException An error from Hibernate + * @throws SQLException An error from the JDBC driver + * + * @see Type#hydrate(ResultSet, String[], SessionImplementor, Object) alternative, 2-phase property initialization */ public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException; /** - * Retrieve an instance of the mapped class from a JDBC resultset. Implementations - * should handle possibility of null values. This method might be called if the - * type is known to be a single-column type. + * Extract a value of the {@link #getReturnedClass() mapped class} from the JDBC result set. Implementors + * should handle possibility of null values. This form might be called if the type is known to be a + * single-column type. * - * @param rs - * @param name the column name - * @param session + * @param rs The result set from which to extract value. + * @param name the column name making up this type value (use to read from result set) + * @param session The originating session * @param owner the parent entity - * @return Object - * @throws HibernateException - * @throws SQLException + * + * @return The extracted value + * + * @throws HibernateException An error from Hibernate + * @throws SQLException An error from the JDBC driver */ public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) throws HibernateException, SQLException; /** - * Write an instance of the mapped class to a prepared statement, ignoring some columns. - * Implementors should handle possibility of null values. A multi-column type should be - * written to parameters starting from index. - * @param st + * Bind a value represented by an instance of the {@link #getReturnedClass() mapped class} to the JDBC prepared + * statement, ignoring some columns as dictated by the 'settable' parameter. Implementors should handle the + * possibility of null values. A multi-column type should bind parameters starting from index. + * + * @param st The JDBC prepared statement to which to bind * @param value the object to write - * @param index statement parameter index - * @param settable an array indicating which columns to ignore - * @param session + * @param index starting parameter bind index + * @param settable an array indicating which columns to bind/ignore + * @param session The originating session * - * @throws HibernateException - * @throws SQLException + * @throws HibernateException An error from Hibernate + * @throws SQLException An error from the JDBC driver */ public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session) throws HibernateException, SQLException; /** - * Write an instance of the mapped class to a prepared statement. Implementors - * should handle possibility of null values. A multi-column type should be written - * to parameters starting from index. - * @param st + * Bind a value represented by an instance of the {@link #getReturnedClass() mapped class} to the JDBC prepared + * statement. Implementors should handle possibility of null values. A multi-column type should bind parameters + * starting from index. + * + * @param st The JDBC prepared statement to which to bind * @param value the object to write - * @param index statement parameter index - * @param session + * @param index starting parameter bind index + * @param session The originating session * - * @throws HibernateException - * @throws SQLException + * @throws HibernateException An error from Hibernate + * @throws SQLException An error from the JDBC driver */ public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException; /** - * A representation of the value to be embedded in an XML element. + * Generate a representation of the value for logging purposes. * - * @param value - * @param factory - * @return String - * @throws HibernateException + * @param value The value to be logged + * @param factory The session factory + * + * @return The loggable representation + * + * @throws HibernateException An error from Hibernate */ - public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) + public String toLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException; /** - * A representation of the value to be embedded in a log file. + * A representation of the value to be embedded in an XML element. * - * @param value - * @param factory - * @return String - * @throws HibernateException + * @param node The XML node to which to write the value + * @param value The value to write + * @param factory The session factory + * + * @throws HibernateException An error from Hibernate + * + * @deprecated To be removed in 5. Removed as part of removing the notion of DOM entity-mode. + * See Jira issue: HHH-7771 */ - public String toLoggableString(Object value, SessionFactoryImplementor factory) + @Deprecated + public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) throws HibernateException; /** * Parse the XML representation of an instance. - * @param xml - * @param factory * - * @return an instance of the type - * @throws HibernateException + * @param xml The XML node from which to read the value + * @param factory The session factory + * + * @return an instance of the {@link #getReturnedClass() mapped class} + * + * @throws HibernateException An error from Hibernate + * + * @deprecated To be removed in 5. Removed as part of removing the notion of DOM entity-mode. + * See Jira issue: HHH-7771 */ + @Deprecated public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException; /** @@ -307,14 +429,16 @@ public String getName(); /** - * Return a deep copy of the persistent state, stopping at entities and at - * collections. - * @param value generally a collection element or entity field - * @param entityMode - * @param factory - * @return Object a copy + * Return a deep copy of the persistent state, stopping at entities and at collections. + * + * @param value The value to be copied + * @param factory The session factory + * + * @return The deep copy + * + * @throws HibernateException An error from Hibernate */ - public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) + public Object deepCopy(Object value, SessionFactoryImplementor factory) throws HibernateException; /** @@ -327,70 +451,106 @@ public boolean isMutable(); /** - * Return a cacheable "disassembled" representation of the object. + * Return a disassembled representation of the object. This is the value Hibernate will use in second level + * caching, so care should be taken to break values down to their simplest forms; for entities especially, this + * means breaking them down into their constituent parts. + * * @param value the value to cache - * @param session the session + * @param session the originating session * @param owner optional parent entity object (needed for collections) + * * @return the disassembled, deep cloned state + * + * @throws HibernateException An error from Hibernate */ public Serializable disassemble(Object value, SessionImplementor session, Object owner) throws HibernateException; /** - * Reconstruct the object from its cached "disassembled" state. + * Reconstruct the object from its disassembled state. This method is the reciprocal of {@link #disassemble} + * * @param cached the disassembled state from the cache - * @param session the session + * @param session the originating session * @param owner the parent entity object - * @return the the object + * + * @return the (re)assembled object + * + * @throws HibernateException An error from Hibernate */ public Object assemble(Serializable cached, SessionImplementor session, Object owner) throws HibernateException; /** * Called before assembling a query result set from the query cache, to allow batch fetching * of entities missing from the second-level cache. + * + * @param cached The key + * @param session The originating session */ public void beforeAssemble(Serializable cached, SessionImplementor session); /** - * Retrieve an instance of the mapped class, or the identifier of an entity or collection, - * from a JDBC resultset. This is useful for 2-phase property initialization - the second - * phase is a call to resolveIdentifier(). + * Extract a value from the JDBC result set. This is useful for 2-phase property initialization - the second + * phase is a call to {@link #resolve} + * This hydrated value will be either:

          + *
        • in the case of an entity or collection type, the key
        • + *
        • otherwise, the value itself
        • + *
        * - * @see Type#resolve(Object, SessionImplementor, Object) - * @param rs - * @param names the column names - * @param session the session + * @param rs The JDBC result set + * @param names the column names making up this type value (use to read from result set) + * @param session The originating session * @param owner the parent entity - * @return Object an identifier or actual value - * @throws HibernateException - * @throws SQLException + * + * @return An entity or collection key, or an actual value. + * + * @throws HibernateException An error from Hibernate + * @throws SQLException An error from the JDBC driver + * + * @see #resolve */ public Object hydrate(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException; /** - * Map identifiers to entities or collections. This is the second phase of 2-phase property - * initialization. + * The second phase of 2-phase loading. Only really pertinent for entities and collections. Here we resolve the + * identifier to an entity or collection instance * - * @see Type#hydrate(ResultSet, String[], SessionImplementor, Object) * @param value an identifier or value returned by hydrate() * @param owner the parent entity * @param session the session + * * @return the given value, or the value associated with the identifier - * @throws HibernateException + * + * @throws HibernateException An error from Hibernate + * + * @see #hydrate */ public Object resolve(Object value, SessionImplementor session, Object owner) throws HibernateException; /** - * Given a hydrated, but unresolved value, return a value that may be used to - * reconstruct property-ref associations. + * Given a hydrated, but unresolved value, return a value that may be used to reconstruct property-ref + * associations. + * + * @param value The unresolved, hydrated value + * @param session THe originating session + * @param owner The value owner + * + * @return The semi-resolved value + * + * @throws HibernateException An error from Hibernate */ public Object semiResolve(Object value, SessionImplementor session, Object owner) throws HibernateException; /** - * Get the type of a semi-resolved value. + * As part of 2-phase loading, when we perform resolving what is the resolved type for this type? Generally + * speaking the type and its semi-resolved type will be the same. The main deviation from this is in the + * case of an entity where the type would be the entity type and semi-resolved type would be its identifier type + * + * @param factory The session factory + * + * @return The semi-resolved type */ public Type getSemiResolvedType(SessionFactoryImplementor factory); @@ -403,15 +563,20 @@ * * @param original the value from the detached entity being merged * @param target the value in the managed entity + * @param session The originating session + * @param owner The owner of the value + * @param copyCache The cache of already copied/replaced values + * * @return the value to be merged + * + * @throws HibernateException An error from Hibernate */ public Object replace( Object original, Object target, SessionImplementor session, Object owner, - Map copyCache) - throws HibernateException; + Map copyCache) throws HibernateException; /** * During merge, replace the existing (target) value in the entity we are merging to @@ -422,29 +587,32 @@ * * @param original the value from the detached entity being merged * @param target the value in the managed entity + * @param session The originating session + * @param owner The owner of the value + * @param copyCache The cache of already copied/replaced values + * @param foreignKeyDirection For associations, which direction does the foreign key point? + * * @return the value to be merged + * + * @throws HibernateException An error from Hibernate */ public Object replace( Object original, Object target, SessionImplementor session, Object owner, Map copyCache, - ForeignKeyDirection foreignKeyDirection) - throws HibernateException; + ForeignKeyDirection foreignKeyDirection) throws HibernateException; /** * Given an instance of the type, return an array of boolean, indicating * which mapped columns would be null. * * @param value an instance of the type + * @param mapping The mapping abstraction + * + * @return array indicating column nullness for a value instance */ public boolean[] toColumnNullness(Object value, Mapping mapping); } - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/TypeFactory.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/TypeFactory.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/TypeFactory.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/TypeFactory.java 30 Jul 2014 16:15:57 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,669 +20,505 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.io.Serializable; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.sql.Blob; -import java.sql.Clob; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.Calendar; -import java.util.Collections; import java.util.Comparator; -import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; import java.util.Properties; -import java.util.TimeZone; -import org.hibernate.Hibernate; +import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.classic.Lifecycle; -import org.hibernate.engine.SessionImplementor; -import org.hibernate.intercept.LazyPropertyInitializer; -import org.hibernate.property.BackrefPropertyAccessor; -import org.hibernate.tuple.StandardProperty; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.util.ReflectHelper; +import org.hibernate.tuple.component.ComponentMetamodel; import org.hibernate.usertype.CompositeUserType; -import org.hibernate.usertype.UserType; import org.hibernate.usertype.ParameterizedType; -import org.hibernate.util.ReflectHelper; +import org.hibernate.usertype.UserType; +import org.jboss.logging.Logger; + /** + * Used internally to build instances of {@link Type}, specifically it builds instances of + * + * * Used internally to obtain instances of Type. Applications should use static methods * and constants on org.hibernate.Hibernate. * - * @see org.hibernate.Hibernate * @author Gavin King + * @author Steve Ebersole */ -public final class TypeFactory { +@SuppressWarnings({ "unchecked" }) +public final class TypeFactory implements Serializable { - private static final Map BASIC_TYPES; + private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, TypeFactory.class.getName()); - static { - HashMap basics = new HashMap(); - basics.put( boolean.class.getName(), Hibernate.BOOLEAN ); - basics.put( long.class.getName(), Hibernate.LONG ); - basics.put( short.class.getName(), Hibernate.SHORT ); - basics.put( int.class.getName(), Hibernate.INTEGER ); - basics.put( byte.class.getName(), Hibernate.BYTE ); - basics.put( float.class.getName(), Hibernate.FLOAT ); - basics.put( double.class.getName(), Hibernate.DOUBLE ); - basics.put( char.class.getName(), Hibernate.CHARACTER ); - basics.put( Hibernate.CHARACTER.getName(), Hibernate.CHARACTER ); - basics.put( Hibernate.INTEGER.getName(), Hibernate.INTEGER ); - basics.put( Hibernate.STRING.getName(), Hibernate.STRING ); - basics.put( Hibernate.DATE.getName(), Hibernate.DATE ); - basics.put( Hibernate.TIME.getName(), Hibernate.TIME ); - basics.put( Hibernate.TIMESTAMP.getName(), Hibernate.TIMESTAMP ); - basics.put( "dbtimestamp", new DbTimestampType() ); - basics.put( Hibernate.LOCALE.getName(), Hibernate.LOCALE ); - basics.put( Hibernate.CALENDAR.getName(), Hibernate.CALENDAR ); - basics.put( Hibernate.CALENDAR_DATE.getName(), Hibernate.CALENDAR_DATE ); - basics.put( Hibernate.CURRENCY.getName(), Hibernate.CURRENCY ); - basics.put( Hibernate.TIMEZONE.getName(), Hibernate.TIMEZONE ); - basics.put( Hibernate.CLASS.getName(), Hibernate.CLASS ); - basics.put( Hibernate.TRUE_FALSE.getName(), Hibernate.TRUE_FALSE ); - basics.put( Hibernate.YES_NO.getName(), Hibernate.YES_NO ); - basics.put( Hibernate.BINARY.getName(), Hibernate.BINARY ); - basics.put( Hibernate.TEXT.getName(), Hibernate.TEXT ); - basics.put( Hibernate.BLOB.getName(), Hibernate.BLOB ); - basics.put( Hibernate.CLOB.getName(), Hibernate.CLOB ); - basics.put( Hibernate.BIG_DECIMAL.getName(), Hibernate.BIG_DECIMAL ); - basics.put( Hibernate.BIG_INTEGER.getName(), Hibernate.BIG_INTEGER ); - basics.put( Hibernate.SERIALIZABLE.getName(), Hibernate.SERIALIZABLE ); - basics.put( Hibernate.OBJECT.getName(), Hibernate.OBJECT ); - basics.put( Boolean.class.getName(), Hibernate.BOOLEAN ); - basics.put( Long.class.getName(), Hibernate.LONG ); - basics.put( Short.class.getName(), Hibernate.SHORT ); - basics.put( Integer.class.getName(), Hibernate.INTEGER ); - basics.put( Byte.class.getName(), Hibernate.BYTE ); - basics.put( Float.class.getName(), Hibernate.FLOAT ); - basics.put( Double.class.getName(), Hibernate.DOUBLE ); - basics.put( Character.class.getName(), Hibernate.CHARACTER ); - basics.put( String.class.getName(), Hibernate.STRING ); - basics.put( java.util.Date.class.getName(), Hibernate.TIMESTAMP ); - basics.put( Time.class.getName(), Hibernate.TIME ); - basics.put( Timestamp.class.getName(), Hibernate.TIMESTAMP ); - basics.put( java.sql.Date.class.getName(), Hibernate.DATE ); - basics.put( BigDecimal.class.getName(), Hibernate.BIG_DECIMAL ); - basics.put( BigInteger.class.getName(), Hibernate.BIG_INTEGER ); - basics.put( Locale.class.getName(), Hibernate.LOCALE ); - basics.put( Calendar.class.getName(), Hibernate.CALENDAR ); - basics.put( GregorianCalendar.class.getName(), Hibernate.CALENDAR ); - if ( CurrencyType.CURRENCY_CLASS != null ) { - basics.put( CurrencyType.CURRENCY_CLASS.getName(), Hibernate.CURRENCY ); - } - basics.put( TimeZone.class.getName(), Hibernate.TIMEZONE ); - basics.put( Object.class.getName(), Hibernate.OBJECT ); - basics.put( Class.class.getName(), Hibernate.CLASS ); - basics.put( byte[].class.getName(), Hibernate.BINARY ); - basics.put( "byte[]", Hibernate.BINARY ); - basics.put( Byte[].class.getName(), Hibernate.WRAPPER_BINARY ); - basics.put( "Byte[]", Hibernate.WRAPPER_BINARY ); - basics.put( char[].class.getName(), Hibernate.CHAR_ARRAY ); - basics.put( "char[]", Hibernate.CHAR_ARRAY ); - basics.put( Character[].class.getName(), Hibernate.CHARACTER_ARRAY ); - basics.put( "Character[]", Hibernate.CHARACTER_ARRAY ); - basics.put( Blob.class.getName(), Hibernate.BLOB ); - basics.put( Clob.class.getName(), Hibernate.CLOB ); - basics.put( Serializable.class.getName(), Hibernate.SERIALIZABLE ); + private final TypeScopeImpl typeScope = new TypeScopeImpl(); - Type type = new AdaptedImmutableType(Hibernate.DATE); - basics.put( type.getName(), type ); - type = new AdaptedImmutableType(Hibernate.TIME); - basics.put( type.getName(), type ); - type = new AdaptedImmutableType(Hibernate.TIMESTAMP); - basics.put( type.getName(), type ); - type = new AdaptedImmutableType( new DbTimestampType() ); - basics.put( type.getName(), type ); - type = new AdaptedImmutableType(Hibernate.CALENDAR); - basics.put( type.getName(), type ); - type = new AdaptedImmutableType(Hibernate.CALENDAR_DATE); - basics.put( type.getName(), type ); - type = new AdaptedImmutableType(Hibernate.SERIALIZABLE); - basics.put( type.getName(), type ); - type = new AdaptedImmutableType(Hibernate.BINARY); - basics.put( type.getName(), type ); - - BASIC_TYPES = Collections.unmodifiableMap( basics ); + public static interface TypeScope extends Serializable { + public SessionFactoryImplementor resolveFactory(); } - private TypeFactory() { - throw new UnsupportedOperationException(); + private static class TypeScopeImpl implements TypeFactory.TypeScope { + private SessionFactoryImplementor factory; + + public void injectSessionFactory(SessionFactoryImplementor factory) { + if ( this.factory != null ) { + LOG.scopingTypesToSessionFactoryAfterAlreadyScoped( this.factory, factory ); + } + else { + LOG.tracev( "Scoping types to session factory {0}", factory ); + } + this.factory = factory; + } + + public SessionFactoryImplementor resolveFactory() { + if ( factory == null ) { + throw new HibernateException( "SessionFactory for type scoping not yet known" ); + } + return factory; + } } - /** - * A one-to-one association type for the given class - */ - public static EntityType oneToOne( - String persistentClass, - ForeignKeyDirection foreignKeyType, - String uniqueKeyPropertyName, - boolean lazy, - boolean unwrapProxy, - boolean isEmbeddedInXML, - String entityName, - String propertyName - ) { - return new OneToOneType( - persistentClass, - foreignKeyType, - uniqueKeyPropertyName, - lazy, - unwrapProxy, - isEmbeddedInXML, - entityName, - propertyName - ); + public void injectSessionFactory(SessionFactoryImplementor factory) { + typeScope.injectSessionFactory( factory ); } - /** - * A many-to-one association type for the given class - */ - public static EntityType manyToOne(String persistentClass) { - return new ManyToOneType( persistentClass ); + public SessionFactoryImplementor resolveSessionFactory() { + return typeScope.resolveFactory(); } - /** - * A many-to-one association type for the given class - */ - public static EntityType manyToOne(String persistentClass, boolean lazy) { - return new ManyToOneType( persistentClass, lazy ); + public Type byClass(Class clazz, Properties parameters) { + if ( Type.class.isAssignableFrom( clazz ) ) { + return type( clazz, parameters ); + } + + if ( CompositeUserType.class.isAssignableFrom( clazz ) ) { + return customComponent( clazz, parameters ); + } + + if ( UserType.class.isAssignableFrom( clazz ) ) { + return custom( clazz, parameters ); + } + + if ( Lifecycle.class.isAssignableFrom( clazz ) ) { + // not really a many-to-one association *necessarily* + return manyToOne( clazz.getName() ); + } + + if ( Serializable.class.isAssignableFrom( clazz ) ) { + return serializable( clazz ); + } + + return null; } - /** - * A many-to-one association type for the given class - */ - public static EntityType manyToOne( - String persistentClass, - String uniqueKeyPropertyName, - boolean lazy, - boolean unwrapProxy, - boolean isEmbeddedInXML, - boolean ignoreNotFound - ) { - return new ManyToOneType( - persistentClass, - uniqueKeyPropertyName, - lazy, - unwrapProxy, - isEmbeddedInXML, - ignoreNotFound - ); + public Type type(Class typeClass, Properties parameters) { + try { + Type type = typeClass.newInstance(); + injectParameters( type, parameters ); + return type; + } + catch (Exception e) { + throw new MappingException( "Could not instantiate Type: " + typeClass.getName(), e ); + } } - /** - * Given the name of a Hibernate basic type, return an instance of - * org.hibernate.type.Type. - */ - public static Type basic(String name) { - return (Type) BASIC_TYPES.get( name ); + public static void injectParameters(Object type, Properties parameters) { + if ( ParameterizedType.class.isInstance( type ) ) { + ( (ParameterizedType) type ).setParameterValues(parameters); + } + else if ( parameters!=null && !parameters.isEmpty() ) { + throw new MappingException( "type is not parameterized: " + type.getClass().getName() ); + } } - /** - * Uses heuristics to deduce a Hibernate type given a string naming the type or Java class. - * Return an instance of org.hibernate.type.Type. - */ - public static Type heuristicType(String typeName) throws MappingException { - return heuristicType( typeName, null ); + public CompositeCustomType customComponent(Class typeClass, Properties parameters) { + return customComponent( typeClass, parameters, typeScope ); } /** - * Uses heuristics to deduce a Hibernate type given a string naming the type or Java class. - * Return an instance of org.hibernate.type.Type. + * @deprecated Only for use temporary use by {@link org.hibernate.Hibernate} */ - public static Type heuristicType(String typeName, Properties parameters) - throws MappingException { - Type type = TypeFactory.basic( typeName ); - if ( type == null ) { - Class typeClass; - try { - typeClass = ReflectHelper.classForName( typeName ); - } - catch (ClassNotFoundException cnfe) { - typeClass = null; - } - if ( typeClass != null ) { - if ( Type.class.isAssignableFrom( typeClass ) ) { - try { - type = (Type) typeClass.newInstance(); - } - catch (Exception e) { - throw new MappingException( - "Could not instantiate Type: " + typeClass.getName(), - e - ); - } - injectParameters(type, parameters); - } - else if ( CompositeUserType.class.isAssignableFrom( typeClass ) ) { - type = new CompositeCustomType( typeClass, parameters ); - } - else if ( UserType.class.isAssignableFrom( typeClass ) ) { - type = new CustomType( typeClass, parameters ); - } - else if ( Lifecycle.class.isAssignableFrom( typeClass ) ) { - type = Hibernate.entity( typeClass ); - } - else if ( Serializable.class.isAssignableFrom( typeClass ) ) { - type = Hibernate.serializable( typeClass ); - } - } + @Deprecated + @SuppressWarnings({ "JavaDoc" }) + public static CompositeCustomType customComponent(Class typeClass, Properties parameters, TypeScope scope) { + try { + CompositeUserType userType = typeClass.newInstance(); + injectParameters( userType, parameters ); + return new CompositeCustomType( userType ); } - return type; - + catch ( Exception e ) { + throw new MappingException( "Unable to instantiate custom type: " + typeClass.getName(), e ); + } } /** - * The legacy contract. - * - * @deprecated Use {@link #customCollection(String, java.util.Properties, String, String, boolean)} instead + * @deprecated Use {@link #customCollection(String, java.util.Properties, String, String)} + * instead. + * See Jira issue: HHH-7771 */ - public static CollectionType customCollection( + @Deprecated + public CollectionType customCollection( String typeName, + Properties typeParameters, String role, String propertyRef, boolean embedded) { - return customCollection( typeName, null, role, propertyRef, embedded ); + Class typeClass; + try { + typeClass = ReflectHelper.classForName( typeName ); + } + catch ( ClassNotFoundException cnfe ) { + throw new MappingException( "user collection type class not found: " + typeName, cnfe ); + } + CustomCollectionType result = new CustomCollectionType( typeScope, typeClass, role, propertyRef, embedded ); + if ( typeParameters != null ) { + injectParameters( result.getUserType(), typeParameters ); + } + return result; } - public static CollectionType customCollection( + public CollectionType customCollection( String typeName, Properties typeParameters, String role, - String propertyRef, - boolean embedded) { + String propertyRef) { Class typeClass; try { typeClass = ReflectHelper.classForName( typeName ); } catch ( ClassNotFoundException cnfe ) { throw new MappingException( "user collection type class not found: " + typeName, cnfe ); } - CustomCollectionType result = new CustomCollectionType( typeClass, role, propertyRef, embedded ); + CustomCollectionType result = new CustomCollectionType( typeScope, typeClass, role, propertyRef ); if ( typeParameters != null ) { - TypeFactory.injectParameters( result.getUserType(), typeParameters ); + injectParameters( result.getUserType(), typeParameters ); } return result; } - // Collection Types: + public CustomType custom(Class typeClass, Properties parameters) { + return custom( typeClass, parameters, typeScope ); + } - public static CollectionType array(String role, String propertyRef, boolean embedded, - Class elementClass) { - return new ArrayType( role, propertyRef, elementClass, embedded ); + /** + * @deprecated Only for use temporary use by {@link org.hibernate.Hibernate} + */ + @Deprecated + public static CustomType custom(Class typeClass, Properties parameters, TypeScope scope) { + try { + UserType userType = typeClass.newInstance(); + injectParameters( userType, parameters ); + return new CustomType( userType ); + } + catch ( Exception e ) { + throw new MappingException( "Unable to instantiate custom type: " + typeClass.getName(), e ); + } } - public static CollectionType list(String role, String propertyRef, boolean embedded) { - return new ListType( role, propertyRef, embedded ); + /** + * Build a {@link SerializableType} from the given {@link Serializable} class. + * + * @param serializableClass The {@link Serializable} class. + * @param The actual class type (extends Serializable) + * + * @return The built {@link SerializableType} + */ + public static SerializableType serializable(Class serializableClass) { + return new SerializableType( serializableClass ); } - public static CollectionType bag(String role, String propertyRef, boolean embedded) { - return new BagType( role, propertyRef, embedded ); + + // one-to-one type builders ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + /** + * @deprecated Use {@link #oneToOne(String, ForeignKeyDirection, String, boolean, boolean, String, String, boolean)} instead. + * See Jira issue: HHH-7771 + */ + @Deprecated + public EntityType oneToOne( + String persistentClass, + ForeignKeyDirection foreignKeyType, + String uniqueKeyPropertyName, + boolean lazy, + boolean unwrapProxy, + boolean isEmbeddedInXML, + String entityName, + String propertyName) { + return oneToOne( persistentClass, foreignKeyType, uniqueKeyPropertyName == null, uniqueKeyPropertyName, lazy, unwrapProxy, entityName, + propertyName ); } - public static CollectionType idbag(String role, String propertyRef, boolean embedded) { - return new IdentifierBagType( role, propertyRef, embedded ); + /** + * @deprecated Use {@link #oneToOne(String, ForeignKeyDirection, String, boolean, boolean, String, String, boolean)} instead. + */ + @Deprecated + public EntityType oneToOne( + String persistentClass, + ForeignKeyDirection foreignKeyType, + String uniqueKeyPropertyName, + boolean lazy, + boolean unwrapProxy, + String entityName, + String propertyName) { + return oneToOne( persistentClass, foreignKeyType, uniqueKeyPropertyName == null, uniqueKeyPropertyName, lazy, unwrapProxy, entityName, + propertyName ); } - public static CollectionType map(String role, String propertyRef, boolean embedded) { - return new MapType( role, propertyRef, embedded ); + public EntityType oneToOne( + String persistentClass, + ForeignKeyDirection foreignKeyType, + boolean referenceToPrimaryKey, + String uniqueKeyPropertyName, + boolean lazy, + boolean unwrapProxy, + String entityName, + String propertyName) { + return new OneToOneType( typeScope, persistentClass, foreignKeyType, referenceToPrimaryKey, + uniqueKeyPropertyName, lazy, unwrapProxy, entityName, propertyName ); } + + /** + * @deprecated Use {@link #specialOneToOne(String, ForeignKeyDirection, String, boolean, boolean, String, String, boolean)} instead. + */ + @Deprecated + public EntityType specialOneToOne( + String persistentClass, + ForeignKeyDirection foreignKeyType, + String uniqueKeyPropertyName, + boolean lazy, + boolean unwrapProxy, + String entityName, + String propertyName) { + return specialOneToOne( persistentClass, foreignKeyType, uniqueKeyPropertyName == null, uniqueKeyPropertyName, lazy, unwrapProxy, + entityName, propertyName ); + } - public static CollectionType orderedMap(String role, String propertyRef, boolean embedded) { - return new OrderedMapType( role, propertyRef, embedded ); + public EntityType specialOneToOne( + String persistentClass, + ForeignKeyDirection foreignKeyType, + boolean referenceToPrimaryKey, + String uniqueKeyPropertyName, + boolean lazy, + boolean unwrapProxy, + String entityName, + String propertyName) { + return new SpecialOneToOneType( typeScope, persistentClass, foreignKeyType, referenceToPrimaryKey, + uniqueKeyPropertyName, lazy, unwrapProxy, entityName, propertyName ); } - public static CollectionType set(String role, String propertyRef, boolean embedded) { - return new SetType( role, propertyRef, embedded ); + + // many-to-one type builders ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + public EntityType manyToOne(String persistentClass) { + return new ManyToOneType( typeScope, persistentClass ); } - public static CollectionType orderedSet(String role, String propertyRef, boolean embedded) { - return new OrderedSetType( role, propertyRef, embedded ); + public EntityType manyToOne(String persistentClass, boolean lazy) { + return new ManyToOneType( typeScope, persistentClass, lazy ); } - public static CollectionType sortedMap(String role, String propertyRef, boolean embedded, - Comparator comparator) { - return new SortedMapType( role, propertyRef, comparator, embedded ); + /** + * @deprecated Use {@link #manyToOne(String, boolean, String, boolean, boolean, boolean, boolean)} instead. + * See Jira issue: HHH-7771 + */ + @Deprecated + public EntityType manyToOne( + String persistentClass, + String uniqueKeyPropertyName, + boolean lazy, + boolean unwrapProxy, + boolean isEmbeddedInXML, + boolean ignoreNotFound, + boolean isLogicalOneToOne) { + return manyToOne( persistentClass, uniqueKeyPropertyName == null, uniqueKeyPropertyName, lazy, unwrapProxy, ignoreNotFound, + isLogicalOneToOne ); } - public static CollectionType sortedSet(String role, String propertyRef, boolean embedded, - Comparator comparator) { - return new SortedSetType( role, propertyRef, comparator, embedded ); + /** + * @deprecated Use {@link #manyToOne(String, boolean, String, boolean, boolean, boolean, boolean)} instead. + */ + @Deprecated + public EntityType manyToOne( + String persistentClass, + String uniqueKeyPropertyName, + boolean lazy, + boolean unwrapProxy, + boolean ignoreNotFound, + boolean isLogicalOneToOne) { + return manyToOne( persistentClass, uniqueKeyPropertyName == null, uniqueKeyPropertyName, lazy, unwrapProxy, ignoreNotFound, + isLogicalOneToOne ); } - public static void injectParameters(Object type, Properties parameters) { - if (type instanceof ParameterizedType) { - ( (ParameterizedType) type ).setParameterValues(parameters); - } - else if ( parameters!=null && !parameters.isEmpty() ) { - throw new MappingException( - "type is not parameterized: " + - type.getClass().getName() - ); - } + public EntityType manyToOne( + String persistentClass, + boolean referenceToPrimaryKey, + String uniqueKeyPropertyName, + boolean lazy, + boolean unwrapProxy, + boolean ignoreNotFound, + boolean isLogicalOneToOne) { + return new ManyToOneType( + typeScope, + persistentClass, + referenceToPrimaryKey, + uniqueKeyPropertyName, + lazy, + unwrapProxy, + ignoreNotFound, + isLogicalOneToOne + ); } + // collection type builders ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - // convenience methods relating to operations across arrays of types... - /** - * Deep copy a series of values from one array to another... - * - * @param values The values to copy (the source) - * @param types The value types - * @param copy an array indicating which values to include in the copy - * @param target The array into which to copy the values - * @param session The orginating session + * @deprecated Use {@link #array(String, String, Class)} instead. + * See Jira issue: HHH-7771 */ - public static void deepCopy( - final Object[] values, - final Type[] types, - final boolean[] copy, - final Object[] target, - final SessionImplementor session) { - for ( int i = 0; i < types.length; i++ ) { - if ( copy[i] ) { - if ( values[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY - || values[i] == BackrefPropertyAccessor.UNKNOWN ) { - target[i] = values[i]; - } - else { - target[i] = types[i].deepCopy( values[i], session.getEntityMode(), session - .getFactory() ); - } - } - } + @Deprecated + public CollectionType array(String role, String propertyRef, boolean embedded, Class elementClass) { + return new ArrayType( typeScope, role, propertyRef, elementClass, embedded ); } + public CollectionType array(String role, String propertyRef, Class elementClass) { + return new ArrayType( typeScope, role, propertyRef, elementClass ); + } + /** - * Apply the {@link Type#beforeAssemble} operation across a series of values. - * - * @param row The values - * @param types The value types - * @param session The orginating session + * @deprecated Use {@link #list(String, String)} instead. + * See Jira issue: HHH-7771 */ - public static void beforeAssemble( - final Serializable[] row, - final Type[] types, - final SessionImplementor session) { - for ( int i = 0; i < types.length; i++ ) { - if ( row[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY - && row[i] != BackrefPropertyAccessor.UNKNOWN ) { - types[i].beforeAssemble( row[i], session ); - } - } + @Deprecated + public CollectionType list(String role, String propertyRef, boolean embedded) { + return new ListType( typeScope, role, propertyRef, embedded ); } + public CollectionType list(String role, String propertyRef) { + return new ListType( typeScope, role, propertyRef ); + } + /** - * Apply the {@link Type#assemble} operation across a series of values. - * - * @param row The values - * @param types The value types - * @param session The orginating session - * @param owner The entity "owning" the values - * @return The assembled state + * @deprecated Use {@link #bag(String, String)} instead. + * See Jira issue: HHH-7771 */ - public static Object[] assemble( - final Serializable[] row, - final Type[] types, - final SessionImplementor session, - final Object owner) { - Object[] assembled = new Object[row.length]; - for ( int i = 0; i < types.length; i++ ) { - if ( row[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY || row[i] == BackrefPropertyAccessor.UNKNOWN ) { - assembled[i] = row[i]; - } - else { - assembled[i] = types[i].assemble( row[i], session, owner ); - } - } - return assembled; + @Deprecated + public CollectionType bag(String role, String propertyRef, boolean embedded) { + return new BagType( typeScope, role, propertyRef, embedded ); } + public CollectionType bag(String role, String propertyRef) { + return new BagType( typeScope, role, propertyRef ); + } + /** - * Apply the {@link Type#disassemble} operation across a series of values. - * - * @param row The values - * @param types The value types - * @param nonCacheable An array indicating which values to include in the disassemled state - * @param session The orginating session - * @param owner The entity "owning" the values - * @return The disassembled state + * @deprecated Use {@link #idbag(String, String)} instead. + * See Jira issue: HHH-7771 */ - public static Serializable[] disassemble( - final Object[] row, - final Type[] types, - final boolean[] nonCacheable, - final SessionImplementor session, - final Object owner) { - Serializable[] disassembled = new Serializable[row.length]; - for ( int i = 0; i < row.length; i++ ) { - if ( nonCacheable!=null && nonCacheable[i] ) { - disassembled[i] = LazyPropertyInitializer.UNFETCHED_PROPERTY; - } - else if ( row[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY || row[i] == BackrefPropertyAccessor.UNKNOWN ) { - disassembled[i] = (Serializable) row[i]; - } - else { - disassembled[i] = types[i].disassemble( row[i], session, owner ); - } - } - return disassembled; + @Deprecated + public CollectionType idbag(String role, String propertyRef, boolean embedded) { + return new IdentifierBagType( typeScope, role, propertyRef, embedded ); } + public CollectionType idbag(String role, String propertyRef) { + return new IdentifierBagType( typeScope, role, propertyRef ); + } + /** - * Apply the {@link Type#replace} operation across a series of values. - * - * @param original The source of the state - * @param target The target into which to replace the source values. - * @param types The value types - * @param session The orginating session - * @param owner The entity "owning" the values - * @param copyCache A map representing a cache of already replaced state - * @return The replaced state + * @deprecated Use {@link #map(String, String)} instead. + * See Jira issue: HHH-7771 */ - public static Object[] replace( - final Object[] original, - final Object[] target, - final Type[] types, - final SessionImplementor session, - final Object owner, - final Map copyCache) { - Object[] copied = new Object[original.length]; - for ( int i = 0; i < types.length; i++ ) { - if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY - || original[i] == BackrefPropertyAccessor.UNKNOWN ) { - copied[i] = target[i]; - } - else { - copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache ); - } - } - return copied; + @Deprecated + public CollectionType map(String role, String propertyRef, boolean embedded) { + return new MapType( typeScope, role, propertyRef, embedded ); } + public CollectionType map(String role, String propertyRef) { + return new MapType( typeScope, role, propertyRef ); + } + /** - * Apply the {@link Type#replace} operation across a series of values. - * - * @param original The source of the state - * @param target The target into which to replace the source values. - * @param types The value types - * @param session The orginating session - * @param owner The entity "owning" the values - * @param copyCache A map representing a cache of already replaced state - * @param foreignKeyDirection FK directionality to be applied to the replacement - * @return The replaced state + * @deprecated Use {@link #orderedMap(String, String)} instead. + * See Jira issue: HHH-7771 */ - public static Object[] replace( - final Object[] original, - final Object[] target, - final Type[] types, - final SessionImplementor session, - final Object owner, - final Map copyCache, - final ForeignKeyDirection foreignKeyDirection) { - Object[] copied = new Object[original.length]; - for ( int i = 0; i < types.length; i++ ) { - if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY - || original[i] == BackrefPropertyAccessor.UNKNOWN ) { - copied[i] = target[i]; - } - else { - copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache, foreignKeyDirection ); - } - } - return copied; + @Deprecated + public CollectionType orderedMap(String role, String propertyRef, boolean embedded) { + return new OrderedMapType( typeScope, role, propertyRef, embedded ); } + public CollectionType orderedMap(String role, String propertyRef) { + return new OrderedMapType( typeScope, role, propertyRef ); + } + /** - * Apply the {@link Type#replace} operation across a series of values, as - * long as the corresponding {@link Type} is an association. - *

        - * If the corresponding type is a component type, then apply {@link #replaceAssociations} - * accross the component subtypes but do not replace the component value itself. - * - * @param original The source of the state - * @param target The target into which to replace the source values. - * @param types The value types - * @param session The orginating session - * @param owner The entity "owning" the values - * @param copyCache A map representing a cache of already replaced state - * @param foreignKeyDirection FK directionality to be applied to the replacement - * @return The replaced state + * @deprecated Use {@link #sortedMap(String, String, java.util.Comparator)} instead. + * See Jira issue: HHH-7771 */ - public static Object[] replaceAssociations( - final Object[] original, - final Object[] target, - final Type[] types, - final SessionImplementor session, - final Object owner, - final Map copyCache, - final ForeignKeyDirection foreignKeyDirection) { - Object[] copied = new Object[original.length]; - for ( int i = 0; i < types.length; i++ ) { - if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY - || original[i] == BackrefPropertyAccessor.UNKNOWN ) { - copied[i] = target[i]; - } - else if ( types[i].isComponentType() ) { - // need to extract the component values and check for subtype replacements... - AbstractComponentType componentType = ( AbstractComponentType ) types[i]; - Type[] subtypes = componentType.getSubtypes(); - Object[] origComponentValues = original[i] == null ? new Object[subtypes.length] : componentType.getPropertyValues( original[i], session ); - Object[] targetComponentValues = target[i] == null ? new Object[subtypes.length] : componentType.getPropertyValues( target[i], session ); - replaceAssociations( origComponentValues, targetComponentValues, subtypes, session, null, copyCache, foreignKeyDirection ); - copied[i] = target[i]; - } - else if ( !types[i].isAssociationType() ) { - copied[i] = target[i]; - } - else { - copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache, foreignKeyDirection ); - } - } - return copied; + @Deprecated + public CollectionType sortedMap(String role, String propertyRef, boolean embedded, Comparator comparator) { + return new SortedMapType( typeScope, role, propertyRef, comparator, embedded ); } + public CollectionType sortedMap(String role, String propertyRef, Comparator comparator) { + return new SortedMapType( typeScope, role, propertyRef, comparator ); + } + /** - * Determine if any of the given field values are dirty, returning an array containing - * indices of the dirty fields. - *

        - * If it is determined that no fields are dirty, null is returned. - * - * @param properties The property definitions - * @param currentState The current state of the entity - * @param previousState The baseline state of the entity - * @param includeColumns Columns to be included in the dirty checking, per property - * @param anyUninitializedProperties Does the entity currently hold any uninitialized property values? - * @param session The session from which the dirty check request originated. - * @return Array containing indices of the dirty properties, or null if no properties considered dirty. + * @deprecated Use {@link #set(String, String)} instead. + * See Jira issue: HHH-7771 */ - public static int[] findDirty( - final StandardProperty[] properties, - final Object[] currentState, - final Object[] previousState, - final boolean[][] includeColumns, - final boolean anyUninitializedProperties, - final SessionImplementor session) { - int[] results = null; - int count = 0; - int span = properties.length; + @Deprecated + public CollectionType set(String role, String propertyRef, boolean embedded) { + return new SetType( typeScope, role, propertyRef, embedded ); + } - for ( int i = 0; i < span; i++ ) { - final boolean dirty = currentState[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY - && properties[i].isDirtyCheckable( anyUninitializedProperties ) - && properties[i].getType().isDirty( previousState[i], currentState[i], includeColumns[i], session ); - if ( dirty ) { - if ( results == null ) { - results = new int[span]; - } - results[count++] = i; - } - } + public CollectionType set(String role, String propertyRef) { + return new SetType( typeScope, role, propertyRef ); + } - if ( count == 0 ) { - return null; - } - else { - int[] trimmed = new int[count]; - System.arraycopy( results, 0, trimmed, 0, count ); - return trimmed; - } + /** + * @deprecated Use {@link #orderedSet(String, String)} instead. + * See Jira issue: HHH-7771 + */ + @Deprecated + public CollectionType orderedSet(String role, String propertyRef, boolean embedded) { + return new OrderedSetType( typeScope, role, propertyRef, embedded ); } + public CollectionType orderedSet(String role, String propertyRef) { + return new OrderedSetType( typeScope, role, propertyRef ); + } + /** - * Determine if any of the given field values are modified, returning an array containing - * indices of the modified fields. - *

        - * If it is determined that no fields are dirty, null is returned. - * - * @param properties The property definitions - * @param currentState The current state of the entity - * @param previousState The baseline state of the entity - * @param includeColumns Columns to be included in the mod checking, per property - * @param anyUninitializedProperties Does the entity currently hold any uninitialized property values? - * @param session The session from which the dirty check request originated. - * @return Array containing indices of the modified properties, or null if no properties considered modified. + * @deprecated Use {@link #sortedSet(String, String, java.util.Comparator)} instead. + * See Jira issue: HHH-7771 */ - public static int[] findModified( - final StandardProperty[] properties, - final Object[] currentState, - final Object[] previousState, - final boolean[][] includeColumns, - final boolean anyUninitializedProperties, - final SessionImplementor session) { - int[] results = null; - int count = 0; - int span = properties.length; + @Deprecated + public CollectionType sortedSet(String role, String propertyRef, boolean embedded, Comparator comparator) { + return new SortedSetType( typeScope, role, propertyRef, comparator, embedded ); + } - for ( int i = 0; i < span; i++ ) { - final boolean modified = currentState[i]!=LazyPropertyInitializer.UNFETCHED_PROPERTY - && properties[i].isDirtyCheckable(anyUninitializedProperties) - && properties[i].getType().isModified( previousState[i], currentState[i], includeColumns[i], session ); + public CollectionType sortedSet(String role, String propertyRef, Comparator comparator) { + return new SortedSetType( typeScope, role, propertyRef, comparator ); + } - if ( modified ) { - if ( results == null ) { - results = new int[span]; - } - results[count++] = i; - } - } + // component type builders ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - if ( count == 0 ) { - return null; - } - else { - int[] trimmed = new int[count]; - System.arraycopy( results, 0, trimmed, 0, count ); - return trimmed; - } + public ComponentType component(ComponentMetamodel metamodel) { + return new ComponentType( typeScope, metamodel ); } + public EmbeddedComponentType embeddedComponent(ComponentMetamodel metamodel) { + return new EmbeddedComponentType( typeScope, metamodel ); + } + + + // any type builder ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + public Type any(Type metaType, Type identifierType) { + return new AnyType( typeScope, metaType, identifierType ); + } } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/TypeHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/TypeResolver.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/UUIDBinaryType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/UUIDCharType.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/UrlType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/VersionType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/VersionType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/VersionType.java 17 Aug 2012 14:36:28 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/VersionType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,26 +20,27 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; import java.util.Comparator; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; /** - * A Type that may be used to version data. + * Additional contract for types which may be used to version (and optimistic lock) data. + * * @author Gavin King + * @author Steve Ebersole */ -public interface VersionType extends Type { +public interface VersionType extends Type { /** * Generate an initial version. * * @param session The session from which this request originates. * @return an instance of the type */ - public Object seed(SessionImplementor session); + public T seed(SessionImplementor session); /** * Increment the version. @@ -48,23 +49,14 @@ * @param current the current version * @return an instance of the type */ - public Object next(Object current, SessionImplementor session); + public T next(T current, SessionImplementor session); /** * Get a comparator for version values. * * @return The comparator to use to compare different version values. */ - public Comparator getComparator(); - - /** - * Are the two version values considered equal? - * - * @param x One value to check. - * @param y The other value to check. - * @return true if the values are equal, false otherwise. - */ - public boolean isEqual(Object x, Object y); + public Comparator getComparator(); } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/WrappedMaterializedBlobType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/WrapperBinaryType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/WrapperBinaryType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/WrapperBinaryType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/WrapperBinaryType.java 30 Jul 2014 16:15:56 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,41 +20,27 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; +import org.hibernate.type.descriptor.java.ByteArrayTypeDescriptor; +import org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor; -import org.hibernate.HibernateException; - /** + * A type mapping {@link java.sql.Types#VARBINARY VARBINARY} and {@link Byte Byte[]} + * * @author Emmanuel Bernard + * @author Steve Ebersole */ -public class WrapperBinaryType extends AbstractBynaryType { - protected Object toExternalFormat(byte[] bytes) { - if (bytes == null) return null; - int length = bytes.length; - Byte[] result = new Byte[length]; - for ( int index = 0; index < length ; index++ ) { - result[index] = new Byte( bytes[index] ); - } - return result; - } +public class WrapperBinaryType extends AbstractSingleColumnStandardBasicType { + public static final WrapperBinaryType INSTANCE = new WrapperBinaryType(); - protected byte[] toInternalFormat(Object val) { - if (val == null) return null; - Byte[] bytes = (Byte[]) val; - int length = bytes.length; - byte[] result = new byte[length]; - for ( int i = 0; i < length ; i++ ) { - if (bytes[i] == null) - throw new HibernateException("Unable to store an Byte[] when one of its element is null"); - result[i] = bytes[i].byteValue(); - } - return result; + public WrapperBinaryType() { + super( VarbinaryTypeDescriptor.INSTANCE, ByteArrayTypeDescriptor.INSTANCE ); } - public Class getReturnedClass() { - return Byte[].class; + @Override + public String[] getRegistrationKeys() { + return new String[] { getName(), "Byte[]", Byte[].class.getName() }; } public String getName() { Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/XmlRepresentableType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/type/YesNoType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/YesNoType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/YesNoType.java 17 Aug 2012 14:36:29 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/YesNoType.java 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,29 +20,48 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.type; +import java.io.Serializable; + +import org.hibernate.dialect.Dialect; +import org.hibernate.type.descriptor.java.BooleanTypeDescriptor; +import org.hibernate.type.descriptor.sql.CharTypeDescriptor; + /** - * yes_no: A type that maps an SQL CHAR(1) to a Java Boolean. + * A type that maps between {@link java.sql.Types#CHAR CHAR(1)} and {@link Boolean} (using 'Y' and 'N') + * * @author Gavin King + * @author Steve Ebersole */ -public class YesNoType extends CharBooleanType { +public class YesNoType + extends AbstractSingleColumnStandardBasicType + implements PrimitiveType, DiscriminatorType { - protected final String getTrueString() { - return "Y"; + public static final YesNoType INSTANCE = new YesNoType(); + + public YesNoType() { + super( CharTypeDescriptor.INSTANCE, BooleanTypeDescriptor.INSTANCE ); } - protected final String getFalseString() { - return "N"; + @Override + public String getName() { + return "yes_no"; } - public String getName() { return "yes_no"; } - + @Override + public Class getPrimitiveClass() { + return boolean.class; + } + @Override + public Boolean stringToObject(String xml) throws Exception { + return fromString( xml ); + } + @Override + public Serializable getDefaultValue() { + return Boolean.FALSE; + } + @Override + public String objectToSQLString(Boolean value, Dialect dialect) throws Exception { + return StringType.INSTANCE.objectToSQLString( value ? "Y" : "N", dialect ); + } } - - - - - - - Index: 3rdParty_sources/hibernate-core/org/hibernate/type/package.html =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/type/package.html,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/type/package.html 17 Aug 2012 14:36:27 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/type/package.html 30 Jul 2014 16:15:58 -0000 1.1.2.1 @@ -1,10 +1,10 @@ Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/JdbcTypeNameMapper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/ValueBinder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/ValueExtractor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/WrapperOptions.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/converter/AttributeConverterSqlTypeDescriptorAdapter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/converter/AttributeConverterTypeAdapter.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/converter/package-info.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/AbstractTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/ArrayMutabilityPlan.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/BigDecimalTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/BigIntegerTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/BlobTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/BooleanTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/ByteArrayTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/ByteTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/CalendarDateTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/CalendarTimeTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/CalendarTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/CharacterArrayTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/CharacterTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/ClassTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/ClobTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/CurrencyTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/DataHelper.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/DateTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/DoubleTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/FloatTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/ImmutableMutabilityPlan.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/IncomparableComparator.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/IntegerTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/JavaTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/JavaTypeDescriptorRegistry.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/JdbcDateTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/JdbcTimeTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/JdbcTimestampTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/LocaleTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/LongTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/MutabilityPlan.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/MutableMutabilityPlan.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/NClobTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/PrimitiveByteArrayTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/PrimitiveCharacterArrayTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/SerializableTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/ShortTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/StringTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/TimeZoneTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/UUIDTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/java/UrlTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/BasicBinder.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/BasicExtractor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/BigIntTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/BinaryTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/BitTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/BlobTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/BooleanTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/CharTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/ClobTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/DateTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/DecimalTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/DoubleTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/FloatTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/IntegerTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/JdbcTypeFamilyInformation.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/JdbcTypeJavaClassMappings.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/LongNVarcharTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/LongVarbinaryTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/LongVarcharTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/NCharTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/NClobTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/NVarcharTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/NumericTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/RealTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/SmallIntTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/SqlTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/SqlTypeDescriptorRegistry.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/TimeTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/TimestampTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/TinyIntTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/VarbinaryTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/VarcharTypeDescriptor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/type/descriptor/sql/package.html'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/usertype/CompositeUserType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/usertype/CompositeUserType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/usertype/CompositeUserType.java 17 Aug 2012 14:36:53 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/usertype/CompositeUserType.java 30 Jul 2014 16:16:47 -0000 1.1.2.1 @@ -23,14 +23,13 @@ * */ package org.hibernate.usertype; - import java.io.Serializable; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.hibernate.HibernateException; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.type.Type; /** @@ -102,10 +101,7 @@ /** * Compare two instances of the class mapped by this type for persistence "equality". * Equality of the persistent state. - * - * @param x - * @param y - * @return boolean + * * @throws HibernateException */ public boolean equals(Object x, Object y) throws HibernateException; @@ -192,14 +188,9 @@ * with a new (original) value from the detached entity we are merging. For immutable * objects, or null values, it is safe to simply return the first parameter. For * mutable objects, it is safe to return a copy of the first parameter. However, since - * composite user types often define component values, it might make sense to recursively + * composite user types often define component values, it might make sense to recursively * replace component values in the target object. - * - * @param original - * @param target - * @param session - * @param owner - * @return + * * @throws HibernateException */ public Object replace(Object original, Object target, SessionImplementor session, Object owner) Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/usertype/DynamicParameterizedType.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/usertype/EnhancedUserType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/usertype/EnhancedUserType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/usertype/EnhancedUserType.java 17 Aug 2012 14:36:53 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/usertype/EnhancedUserType.java 30 Jul 2014 16:16:47 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2008, 2012, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,14 +20,11 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.usertype; /** - * A custom type that may function as an identifier or - * discriminator type, or may be marshalled to and from - * an XML document + * A custom type that may function as an identifier or discriminator type * * @author Gavin King */ @@ -38,13 +35,21 @@ public String objectToSQLString(Object value); /** - * Return a string representation of this value, as it - * should appear in an XML document + * Return a string representation of this value, as it should appear in an XML document + * + * @deprecated To be removed in 5. Implement {@link org.hibernate.type.StringRepresentableType#toString(Object)} + * instead. See HHH-7776 for details */ + @Deprecated public String toXMLString(Object value); + /** - * Parse a string representation of this value, as it - * appears in an XML document + * Parse a string representation of this value, as it appears in an XML document + * + * @deprecated To be removed in 5. Implement + * {@link org.hibernate.type.StringRepresentableType#fromStringValue(String)} instead. + * See HHH-7776 for details */ + @Deprecated public Object fromXMLString(String xmlValue); } Index: 3rdParty_sources/hibernate-core/org/hibernate/usertype/LoggableUserType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/usertype/LoggableUserType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/usertype/LoggableUserType.java 17 Aug 2012 14:36:53 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/usertype/LoggableUserType.java 30 Jul 2014 16:16:47 -0000 1.1.2.1 @@ -23,9 +23,8 @@ * */ package org.hibernate.usertype; +import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.engine.SessionFactoryImplementor; - /** * Marker interface for user types which want to perform custom * logging of their corresponding values Index: 3rdParty_sources/hibernate-core/org/hibernate/usertype/ParameterizedType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/usertype/ParameterizedType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/usertype/ParameterizedType.java 17 Aug 2012 14:36:53 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/usertype/ParameterizedType.java 30 Jul 2014 16:16:47 -0000 1.1.2.1 @@ -23,7 +23,6 @@ * */ package org.hibernate.usertype; - import java.util.Properties; /** @@ -41,4 +40,4 @@ * the implementation. */ public void setParameterValues(Properties parameters); -} \ No newline at end of file +} Fisheye: Tag 1.1 refers to a dead (removed) revision in file `3rdParty_sources/hibernate-core/org/hibernate/usertype/Sized.java'. Fisheye: No comparison available. Pass `N' to diff? Index: 3rdParty_sources/hibernate-core/org/hibernate/usertype/UserCollectionType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/usertype/UserCollectionType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/usertype/UserCollectionType.java 17 Aug 2012 14:36:53 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/usertype/UserCollectionType.java 30 Jul 2014 16:16:47 -0000 1.1.2.1 @@ -23,19 +23,18 @@ * */ package org.hibernate.usertype; - import java.util.Iterator; import java.util.Map; import org.hibernate.HibernateException; -import org.hibernate.collection.PersistentCollection; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.collection.spi.PersistentCollection; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.persister.collection.CollectionPersister; /** * A custom type for mapping user-written classes that implement PersistentCollection * - * @see org.hibernate.collection.PersistentCollection + * @see org.hibernate.collection.spi.PersistentCollection * @author Gavin King */ public interface UserCollectionType { Index: 3rdParty_sources/hibernate-core/org/hibernate/usertype/UserType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/usertype/UserType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/usertype/UserType.java 17 Aug 2012 14:36:53 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/usertype/UserType.java 30 Jul 2014 16:16:47 -0000 1.1.2.1 @@ -1,10 +1,10 @@ /* * Hibernate, Relational Persistence for Idiomatic Java * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. + * distributed under license by Red Hat Inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU @@ -20,7 +20,6 @@ * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA - * */ package org.hibernate.usertype; @@ -30,6 +29,7 @@ import java.sql.SQLException; import org.hibernate.HibernateException; +import org.hibernate.engine.spi.SessionImplementor; /** * This interface should be implemented by user-defined "types". @@ -100,27 +100,30 @@ * Retrieve an instance of the mapped class from a JDBC resultset. Implementors * should handle possibility of null values. * + * * @param rs a JDBC result set * @param names the column names - * @param owner the containing entity - * @return Object + * @param session + *@param owner the containing entity @return Object * @throws HibernateException * @throws SQLException */ - public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException; + public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException; /** * Write an instance of the mapped class to a prepared statement. Implementors * should handle possibility of null values. A multi-column type should be written * to parameters starting from index. * + * * @param st a JDBC prepared statement * @param value the object to write * @param index statement parameter index + * @param session * @throws HibernateException * @throws SQLException */ - public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException; + public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException; /** * Return a deep copy of the persistent state, stopping at entities and at @@ -174,6 +177,7 @@ * @return the value to be merged */ public Object replace(Object original, Object target, Object owner) throws HibernateException; + } Index: 3rdParty_sources/hibernate-core/org/hibernate/usertype/UserVersionType.java =================================================================== RCS file: /usr/local/cvsroot/3rdParty_sources/hibernate-core/org/hibernate/usertype/UserVersionType.java,v diff -u -r1.1 -r1.1.2.1 --- 3rdParty_sources/hibernate-core/org/hibernate/usertype/UserVersionType.java 17 Aug 2012 14:36:53 -0000 1.1 +++ 3rdParty_sources/hibernate-core/org/hibernate/usertype/UserVersionType.java 30 Jul 2014 16:16:47 -0000 1.1.2.1 @@ -23,10 +23,9 @@ * */ package org.hibernate.usertype; - import java.util.Comparator; -import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.spi.SessionImplementor; /** * A user type that may be used for a version property Index: lams_central/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_central/.classpath,v diff -u -r1.20.2.1 -r1.20.2.2 --- lams_central/.classpath 30 Jul 2014 14:23:09 -0000 1.20.2.1 +++ lams_central/.classpath 30 Jul 2014 16:17:40 -0000 1.20.2.2 @@ -19,9 +19,9 @@ - + - + Index: lams_central/src/java/org/lamsfoundation/lams/web/ForgotPasswordServlet.java =================================================================== RCS file: /usr/local/cvsroot/lams_central/src/java/org/lamsfoundation/lams/web/ForgotPasswordServlet.java,v diff -u -r1.9 -r1.9.2.1 --- lams_central/src/java/org/lamsfoundation/lams/web/ForgotPasswordServlet.java 27 Mar 2013 15:10:03 -0000 1.9 +++ lams_central/src/java/org/lamsfoundation/lams/web/ForgotPasswordServlet.java 30 Jul 2014 16:17:40 -0000 1.9.2.1 @@ -13,10 +13,10 @@ import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; -import org.hibernate.Hibernate; import org.hibernate.id.Configurable; import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.UUIDHexGenerator; +import org.hibernate.type.StringType; import org.lamsfoundation.lams.usermanagement.ForgotPasswordRequest; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; @@ -322,7 +322,7 @@ Properties props = new Properties(); IdentifierGenerator uuidGen = new UUIDHexGenerator(); - ( (Configurable) uuidGen).configure(Hibernate.STRING, props, null); + ( (Configurable) uuidGen).configure(StringType.INSTANCE, props, null); return ((String) uuidGen.generate(null, null)).toLowerCase(); } Index: lams_common/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_common/.classpath,v diff -u -r1.25.2.1 -r1.25.2.2 --- lams_common/.classpath 30 Jul 2014 14:22:53 -0000 1.25.2.1 +++ lams_common/.classpath 30 Jul 2014 16:17:32 -0000 1.25.2.2 @@ -16,11 +16,6 @@ - - - - - @@ -40,6 +35,11 @@ + + + + + Index: lams_common/src/java/org/lamsfoundation/lams/cache/CacheManager.java =================================================================== RCS file: /usr/local/cvsroot/lams_common/src/java/org/lamsfoundation/lams/cache/CacheManager.java,v diff -u -r1.10 -r1.10.2.1 --- lams_common/src/java/org/lamsfoundation/lams/cache/CacheManager.java 22 Feb 2012 13:26:17 -0000 1.10 +++ lams_common/src/java/org/lamsfoundation/lams/cache/CacheManager.java 30 Jul 2014 16:17:32 -0000 1.10.2.1 @@ -234,44 +234,19 @@ public Set getCachedClasses() { Set cachedClasses = new TreeSet(); - - for (Entry cacheEntry : ((Map) getSessionFactory() + for (Entry cacheEntry : ((Map) getSessionFactory() .getAllClassMetadata()).entrySet()) { - if (cacheEntry.getValue().hasCache()) { - cachedClasses.add(cacheEntry.getKey()); - } + cachedClasses.add(cacheEntry.getKey()); } - for (Entry cacheEntry : ((Map) getSessionFactory() - .getAllCollectionMetadata()).entrySet()) { - if (cacheEntry.getValue().hasCache()) { - cachedClasses.add(cacheEntry.getKey()); - } - } - return cachedClasses; } public void clearCachedClass(String className) { - for (Entry cacheEntry : ((Map) getSessionFactory() - .getAllClassMetadata()).entrySet()) { - if ((className == null || className.equals(cacheEntry.getKey())) && cacheEntry.getValue().hasCache()) { - getSessionFactory().evictEntity(cacheEntry.getKey()); - if (log.isDebugEnabled()) { - log.debug("Evicted entity: " + cacheEntry.getKey()); - } - } + getSessionFactory().getCache().evictEntityRegion(className); + if (log.isDebugEnabled()) { + log.debug("Evicted entity region: " + className); } - - for (Entry cacheEntry : ((Map) getSessionFactory() - .getAllCollectionMetadata()).entrySet()) { - if ((className == null || className.equals(cacheEntry.getKey())) && cacheEntry.getValue().hasCache()) { - getSessionFactory().evictCollection(cacheEntry.getKey()); - if (log.isDebugEnabled()) { - log.debug("Evicted collection: " + cacheEntry.getKey()); - } - } - } } /* Index: lams_common/src/java/org/lamsfoundation/lams/util/FileUtil.java =================================================================== RCS file: /usr/local/cvsroot/lams_common/src/java/org/lamsfoundation/lams/util/FileUtil.java,v diff -u -r1.43 -r1.43.2.1 --- lams_common/src/java/org/lamsfoundation/lams/util/FileUtil.java 24 Jun 2014 09:48:07 -0000 1.43 +++ lams_common/src/java/org/lamsfoundation/lams/util/FileUtil.java 30 Jul 2014 16:17:32 -0000 1.43.2.1 @@ -27,13 +27,11 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.nio.channels.FileChannel; import java.util.Date; import java.util.Properties; @@ -42,10 +40,10 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; -import org.hibernate.Hibernate; import org.hibernate.id.Configurable; import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.UUIDHexGenerator; +import org.hibernate.type.StringType; import org.jdom.JDOMException; import org.lamsfoundation.lams.learningdesign.service.ToolContentVersionFilter; import org.lamsfoundation.lams.util.zipfile.ZipFileUtilException; @@ -68,8 +66,7 @@ public static final String LAMS_WWW_DIR = "lams-www.war"; public static final String LAMS_RUNTIME_CONTENT_DIR = "runtime"; private static final long numMilliSecondsInADay = 24 * 60 * 60 * 1000; - private static final int FILE_COPY_BUFFER_SIZE = 1024; - + public static final String ALLOWED_EXTENSIONS_FLASH = ".swf,.fla"; public static final String ALLOWED_EXTENSIONS_IMAGE = ".jpg,.gif,.jpeg,.png,.bmp"; public static final String ALLOWED_EXTENSIONS_MEDIA = ".3gp,.avi,.flv,.m4v,.mkv,.mov,.mp3,.mp4,.mpe,.mpeg,.mpg,.mpv,.mts,.m2ts,ogg,.wma,.wmv"; @@ -94,7 +91,7 @@ for (int i = 0; i < files.length; i++) { File file = files[i]; if (file.isDirectory()) { - deleteDirectory(file); + FileUtil.deleteDirectory(file); } else if (!file.delete()) { FileUtil.log.error("Unable to delete file " + file.getName()); retValue = false; @@ -110,12 +107,12 @@ public static boolean deleteDirectory(String directoryName) throws FileUtilException { boolean isDeleted = false; - if (directoryName == null || directoryName.length() == 0) { + if ((directoryName == null) || (directoryName.length() == 0)) { throw new FileUtilException("A directory name must be specified"); } File dir = new File(directoryName); - isDeleted = deleteDirectory(dir); + isDeleted = FileUtil.deleteDirectory(dir); return isDeleted; @@ -128,11 +125,11 @@ */ public static boolean isEmptyDirectory(String directoryName, boolean checkSubdirectories) throws FileUtilException { - if (directoryName == null || directoryName.length() == 0) { + if ((directoryName == null) || (directoryName.length() == 0)) { throw new FileUtilException("A directory name must be specified"); } - return isEmptyDirectory(new File(directoryName), checkSubdirectories); + return FileUtil.isEmptyDirectory(new File(directoryName), checkSubdirectories); } @@ -146,9 +143,9 @@ return false; } else { boolean isEmpty = true; - for (int i = 0; i < files.length && isEmpty; i++) { + for (int i = 0; (i < files.length) && isEmpty; i++) { File file = files[i]; - isEmpty = file.isDirectory() ? isEmptyDirectory(file, true) : false; + isEmpty = file.isDirectory() ? FileUtil.isEmptyDirectory(file, true) : false; } return isEmpty; } @@ -174,7 +171,7 @@ */ public static String createTempDirectory(String suffix) throws FileUtilException { - String tempSysDirName = getTempDir(); + String tempSysDirName = FileUtil.getTempDir(); if (tempSysDirName == null) { throw new FileUtilException( "No temporary directory known to the server. [System.getProperty( \"java.io.tmpdir\" ) returns null. ]\n Cannot upload package."); @@ -189,16 +186,16 @@ tempSysDirName = javaTemp; } - String tempDirName = tempSysDirName + File.separator + FileUtil.prefix + generateUniqueContentFolderID() + "_" - + suffix; + String tempDirName = tempSysDirName + File.separator + FileUtil.prefix + + FileUtil.generateUniqueContentFolderID() + "_" + suffix; File tempDir = new File(tempDirName); // try 100 different variations. If I can't find a unique // one in 100 tries, then give up. int i = 0; - while (tempDir.exists() && i < 100) { - tempDirName = tempSysDirName + File.separator + FileUtil.prefix + generateUniqueContentFolderID() + "_" - + suffix; + while (tempDir.exists() && (i < 100)) { + tempDirName = tempSysDirName + File.separator + FileUtil.prefix + FileUtil.generateUniqueContentFolderID() + + "_" + suffix; tempDir = new File(tempDirName); i++; } @@ -227,7 +224,7 @@ public static boolean createDirectory(String directoryName) throws FileUtilException { boolean isCreated = false; // check directoryName to see if its empty or null - if (directoryName == null || directoryName.length() == 0) { + if ((directoryName == null) || (directoryName.length() == 0)) { throw new FileUtilException("A directory name must be specified"); } @@ -256,25 +253,26 @@ boolean isSubDirCreated = false; boolean isParentDirCreated; - if (parentDirName == null || parentDirName.length() == 0 || subDirName == null || subDirName.length() == 0) { + if ((parentDirName == null) || (parentDirName.length() == 0) || (subDirName == null) + || (subDirName.length() == 0)) { throw new FileUtilException("A parent or subdirectory name must be specified"); } File parentDir = new File(parentDirName); if (!parentDir.exists()) { - isParentDirCreated = createDirectory(parentDirName); + isParentDirCreated = FileUtil.createDirectory(parentDirName); } else { isParentDirCreated = true; // parent directory already exists } - if (trailingForwardSlashPresent(parentDirName)) { - parentDirName = removeTrailingForwardSlash(parentDirName); + if (FileUtil.trailingForwardSlashPresent(parentDirName)) { + parentDirName = FileUtil.removeTrailingForwardSlash(parentDirName); } // concatenate the two together String combinedDirName = parentDirName + File.separator + subDirName; - isSubDirCreated = createDirectory(combinedDirName); + isSubDirCreated = FileUtil.createDirectory(combinedDirName); return isSubDirCreated && isParentDirCreated; } @@ -301,7 +299,7 @@ */ public static boolean trailingForwardSlashPresent(String stringToCheck) { int indexOfSlash = stringToCheck.lastIndexOf("/"); - if (indexOfSlash == stringToCheck.length() - 1) { + if (indexOfSlash == (stringToCheck.length() - 1)) { return true; } else { return false; @@ -317,16 +315,16 @@ // get dump directory name and make sure directory exists String dumpDirectory = Configuration.get(ConfigurationKeys.LAMS_DUMP_DIR); if (dumpDirectory == null) { - dumpDirectory = getTempDir(); + dumpDirectory = FileUtil.getTempDir(); } - createDirectory(dumpDirectory); + FileUtil.createDirectory(dumpDirectory); String dumpFilename = dumpDirectory + File.separator + id + System.currentTimeMillis() + (extension != null ? "." + extension : ""); File dumpFile = new File(dumpFilename); int i = 0; - while (dumpFile.exists() && i < 100) { + while (dumpFile.exists() && (i < 100)) { dumpFilename = dumpDirectory + File.separator + id + System.currentTimeMillis() + "_" + i + (extension != null ? "." + extension : ""); dumpFile = new File(dumpFilename); @@ -359,7 +357,7 @@ * @throws FileUtilException */ public static String createDumpFile(byte[] data, String id, String extension) throws FileUtilException { - String dumpFilename = generateDumpFilename(id, extension); + String dumpFilename = FileUtil.generateDumpFilename(id, extension); OutputStream dumpFile = null; try { dumpFile = new FileOutputStream(dumpFilename); @@ -445,7 +443,7 @@ fullpath = path + File.separator + file; } - return makeCanonicalPath(fullpath); + return FileUtil.makeCanonicalPath(fullpath); } @@ -508,7 +506,8 @@ /** * Verify if a file with such extension is allowed to be uploaded. * - * @param fileType file type can be of the following values:File, Image, Flash, Media + * @param fileType + * file type can be of the following values:File, Image, Flash, Media * @param fileName */ public static boolean isExtensionAllowed(String fileType, String fileName) { @@ -518,16 +517,16 @@ if ("File".equals(fileType)) { // executables are not allowed - return !isExecutableFile(fileName); + return !FileUtil.isExecutableFile(fileName); } else if ("Image".equals(fileType)) { - allowedExtensions = ALLOWED_EXTENSIONS_IMAGE; + allowedExtensions = FileUtil.ALLOWED_EXTENSIONS_IMAGE; } else if ("Flash".equals(fileType)) { - allowedExtensions = ALLOWED_EXTENSIONS_FLASH; + allowedExtensions = FileUtil.ALLOWED_EXTENSIONS_FLASH; } else if ("Media".equals(fileType)) { - allowedExtensions = ALLOWED_EXTENSIONS_MEDIA; + allowedExtensions = FileUtil.ALLOWED_EXTENSIONS_MEDIA; } else { // unknown fileType @@ -540,7 +539,7 @@ return true; } } - + return false; } @@ -587,12 +586,12 @@ } // calculate comparison date - long newestDateToKeep = System.currentTimeMillis() - numDays * FileUtil.numMilliSecondsInADay; + long newestDateToKeep = System.currentTimeMillis() - (numDays * FileUtil.numMilliSecondsInADay); Date date = new Date(newestDateToKeep); FileUtil.log.info("Getting all temp zipfile expanded directories before " + date.toString() + " (server time) (" + newestDateToKeep + ")"); - File tempSysDir = new File(getTempDir()); + File tempSysDir = new File(FileUtil.getTempDir()); File candidates[] = tempSysDir.listFiles(new TempDirectoryFilter(newestDateToKeep, FileUtil.log)); return candidates; } @@ -612,7 +611,7 @@ long totalSize = 0; if (fileList != null) { for (int i = 0; i < fileList.length; i++) { - totalSize += calculateFileSize(fileList[i]); + totalSize += FileUtil.calculateFileSize(fileList[i]); } return totalSize; } else { @@ -661,11 +660,11 @@ String agent = request.getHeader("USER-AGENT"); String filename = null; - if (null != agent && -1 != agent.indexOf("MSIE")) { + if ((null != agent) && (-1 != agent.indexOf("MSIE"))) { // if MSIE then urlencode it filename = URLEncoder.encode(unEncodedFilename, FileUtil.ENCODING_UTF_8); - } else if (null != agent && -1 != agent.indexOf("Mozilla")) { + } else if ((null != agent) && (-1 != agent.indexOf("Mozilla"))) { // if Mozilla then base64 url_safe encoding filename = MimeUtility.encodeText(unEncodedFilename, FileUtil.ENCODING_UTF_8, "B"); @@ -684,36 +683,35 @@ Properties props = new Properties(); IdentifierGenerator uuidGen = new UUIDHexGenerator(); - ((Configurable) uuidGen).configure(Hibernate.STRING, props, null); + ((Configurable) uuidGen).configure(StringType.INSTANCE, props, null); // lowercase to resolve OS issues newUniqueContentFolderID = ((String) uuidGen.generate(null, null)).toLowerCase(); return newUniqueContentFolderID; } - + /** - * Return content folder (unique to each learner and lesson) which is used for storing user generated content. - * It's been used by CKEditor. + * Return content folder (unique to each learner and lesson) which is used for storing user generated content. It's + * been used by CKEditor. * * @param toolSessionId * @param userId * @return */ public static String getLearnerContentFolder(Long lessonId, Long userId) { - return LAMS_RUNTIME_CONTENT_DIR + "/" + lessonId + "/" + userId; + return FileUtil.LAMS_RUNTIME_CONTENT_DIR + "/" + lessonId + "/" + userId; } - + /** - * Return lesson's content folder which is used for storing user generated content. - * It's been used by CKEditor. + * Return lesson's content folder which is used for storing user generated content. It's been used by CKEditor. * * @param toolSessionId * @param userId * @return */ public static String getLearnerContentFolder(Long lessonId) { - return LAMS_RUNTIME_CONTENT_DIR + "/" + lessonId; + return FileUtil.LAMS_RUNTIME_CONTENT_DIR + "/" + lessonId; } /** @@ -774,9 +772,9 @@ } else { // try removing the field from our XML and retry String message = ce.getMessage(); - String classname = extractValue(message, "required-type"); - String fieldname = extractValue(message, "message"); - if (fieldname == null || fieldname.equals("") + String classname = FileUtil.extractValue(message, "required-type"); + String fieldname = FileUtil.extractValue(message, "message"); + if ((fieldname == null) || fieldname.equals("") || lastFieldRemoved.equals(classname + "." + fieldname)) { // can't retry, so get out of here! break; @@ -785,7 +783,7 @@ contentFilter = new ToolContentVersionFilter(); } - Class problemClass = getClass(classname); + Class problemClass = FileUtil.getClass(classname); if (problemClass == null) { // can't retry, so get out of here! break; @@ -815,7 +813,7 @@ int startIndex = message.indexOf(fieldToLookFor); if (startIndex > -1) { startIndex = message.indexOf(":", startIndex + 1); - if (startIndex > -1 && startIndex + 2 < message.length()) { + if ((startIndex > -1) && ((startIndex + 2) < message.length())) { startIndex = startIndex + 2; int endIndex = message.indexOf(" ", startIndex); String value = message.substring(startIndex, endIndex); @@ -851,7 +849,7 @@ if (!tempDir.exists()) { boolean success = tempDir.mkdirs(); if (!success) { - log.error("Could not create temp directory: " + ret); + FileUtil.log.error("Could not create temp directory: " + ret); return System.getProperty("java.io.tmpdir"); } } Index: lams_contentrepository/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_contentrepository/.classpath,v diff -u -r1.21.2.1 -r1.21.2.2 --- lams_contentrepository/.classpath 30 Jul 2014 14:22:47 -0000 1.21.2.1 +++ lams_contentrepository/.classpath 30 Jul 2014 16:17:27 -0000 1.21.2.2 @@ -9,9 +9,9 @@ - + - + Index: lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/dao/hibernate/CredentialDAO.java =================================================================== RCS file: /usr/local/cvsroot/lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/dao/hibernate/CredentialDAO.java,v diff -u -r1.7 -r1.7.2.1 --- lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/dao/hibernate/CredentialDAO.java 1 Jul 2009 02:48:55 -0000 1.7 +++ lams_contentrepository/src/java/org/lamsfoundation/lams/contentrepository/dao/hibernate/CredentialDAO.java 30 Jul 2014 16:17:27 -0000 1.7.2.1 @@ -32,6 +32,7 @@ import org.apache.log4j.Logger; import org.hibernate.HibernateException; +import org.hibernate.ScrollableResults; import org.hibernate.Session; import org.lamsfoundation.lams.contentrepository.CrCredential; import org.lamsfoundation.lams.contentrepository.ICredentials; @@ -95,59 +96,34 @@ // There will be better ways to do this, but this will do for starters // until I get more familiar with Spring. - boolean credentialMatched = false; + StringBuffer buf = new StringBuffer(200); + buf.append("select count(*) num from lams_cr_credential c"); + if (workspace != null) { + buf.append(", lams_cr_workspace_credential wc "); + } + buf.append(" where c.name = \""); + buf.append(credential.getName()); + buf.append("\" and c.password = \""); + buf.append(credential.getPassword()); + buf.append("\""); + if (workspace != null) { + buf.append(" and wc.credential_id = c.credential_id "); + buf.append(" and wc.workspace_id = "); + buf.append(workspace.getWorkspaceId()); + } + boolean credentialMatched = false; Session hibernateSession = getSession(); - Connection conn = null; - PreparedStatement ps = null; - try { - conn = hibernateSession.connection(); - - StringBuffer buf = new StringBuffer(200); - buf.append("select count(*) num from lams_cr_credential c"); - if (workspace != null) { - buf.append(", lams_cr_workspace_credential wc "); - } - buf.append(" where c.name = \""); - buf.append(credential.getName()); - buf.append("\" and c.password = \""); - buf.append(credential.getPassword()); - buf.append("\""); - if (workspace != null) { - buf.append(" and wc.credential_id = c.credential_id "); - buf.append(" and wc.workspace_id = "); - buf.append(workspace.getWorkspaceId()); - } - - ps = conn.prepareStatement(buf.toString()); - ps.execute(); - ResultSet rs = ps.getResultSet(); - if (rs.next()) { - long val = rs.getLong("num"); - if (val > 0) { - credentialMatched = true; - if (val > 1) { - log.warn("More than one credential found for workspace " + workspace.getWorkspaceId() - + " credential name " + credential.getName()); - } + ScrollableResults result = hibernateSession.createSQLQuery(buf.toString()).scroll(); + if (result.next()) { + long val = result.getLong(0); + if (val > 0) { + credentialMatched = true; + if (val > 1) { + log.warn("More than one credential found for workspace " + workspace.getWorkspaceId() + + " credential name " + credential.getName()); } } - - } catch (HibernateException e) { - log.error("Hibernate exception occured during login. ", e); - throw new RepositoryRuntimeException("Unable to login due to internal error.", e); - } catch (SQLException se) { - log.error("SQL exception occured during login. ", se); - throw new RepositoryRuntimeException("Unable to login due to internal error.", se); - } finally { - if (ps != null) { - try { - ps.close(); - } catch (SQLException se2) { - log.error("SQL exception occured during login, while closing statement. ", se2); - throw new RepositoryRuntimeException("Unable to login due to internal error.", se2); - } - } } return credentialMatched; Index: lams_tool_assessment/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/.classpath,v diff -u -r1.11.2.1 -r1.11.2.2 --- lams_tool_assessment/.classpath 30 Jul 2014 14:22:49 -0000 1.11.2.1 +++ lams_tool_assessment/.classpath 30 Jul 2014 16:17:38 -0000 1.11.2.2 @@ -13,9 +13,9 @@ - + - + Index: lams_tool_bbb/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_bbb/.classpath,v diff -u -r1.6.2.1 -r1.6.2.2 --- lams_tool_bbb/.classpath 30 Jul 2014 14:22:45 -0000 1.6.2.1 +++ lams_tool_bbb/.classpath 30 Jul 2014 16:17:12 -0000 1.6.2.2 @@ -9,9 +9,9 @@ - + - + Index: lams_tool_chat/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_chat/.classpath,v diff -u -r1.11.2.1 -r1.11.2.2 --- lams_tool_chat/.classpath 30 Jul 2014 14:23:18 -0000 1.11.2.1 +++ lams_tool_chat/.classpath 30 Jul 2014 16:17:37 -0000 1.11.2.2 @@ -4,9 +4,9 @@ - + - + Index: lams_tool_daco/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_daco/.classpath,v diff -u -r1.9.2.1 -r1.9.2.2 --- lams_tool_daco/.classpath 30 Jul 2014 14:23:02 -0000 1.9.2.1 +++ lams_tool_daco/.classpath 30 Jul 2014 16:17:16 -0000 1.9.2.2 @@ -3,9 +3,9 @@ - + - + Index: lams_tool_forum/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_forum/.classpath,v diff -u -r1.20.2.1 -r1.20.2.2 --- lams_tool_forum/.classpath 30 Jul 2014 14:23:17 -0000 1.20.2.1 +++ lams_tool_forum/.classpath 30 Jul 2014 16:17:36 -0000 1.20.2.2 @@ -12,9 +12,9 @@ - + - + Index: lams_tool_gmap/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_gmap/.classpath,v diff -u -r1.8.2.1 -r1.8.2.2 --- lams_tool_gmap/.classpath 30 Jul 2014 14:23:31 -0000 1.8.2.1 +++ lams_tool_gmap/.classpath 30 Jul 2014 16:17:13 -0000 1.8.2.2 @@ -4,9 +4,9 @@ - + - + Index: lams_tool_imscc/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_imscc/.classpath,v diff -u -r1.7.2.1 -r1.7.2.2 --- lams_tool_imscc/.classpath 30 Jul 2014 14:23:01 -0000 1.7.2.1 +++ lams_tool_imscc/.classpath 30 Jul 2014 16:17:18 -0000 1.7.2.2 @@ -14,9 +14,9 @@ - + - + Index: lams_tool_kaltura/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_kaltura/.classpath,v diff -u -r1.2.2.1 -r1.2.2.2 --- lams_tool_kaltura/.classpath 30 Jul 2014 14:22:58 -0000 1.2.2.1 +++ lams_tool_kaltura/.classpath 30 Jul 2014 16:15:25 -0000 1.2.2.2 @@ -4,9 +4,9 @@ - + - + Index: lams_tool_lamc/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_lamc/.classpath,v diff -u -r1.12.2.1 -r1.12.2.2 --- lams_tool_lamc/.classpath 30 Jul 2014 14:22:46 -0000 1.12.2.1 +++ lams_tool_lamc/.classpath 30 Jul 2014 16:17:41 -0000 1.12.2.2 @@ -4,9 +4,9 @@ - + - + Index: lams_tool_laqa/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_laqa/.classpath,v diff -u -r1.16.2.1 -r1.16.2.2 --- lams_tool_laqa/.classpath 30 Jul 2014 14:22:51 -0000 1.16.2.1 +++ lams_tool_laqa/.classpath 30 Jul 2014 16:17:46 -0000 1.16.2.2 @@ -4,9 +4,9 @@ - + - + Index: lams_tool_nb/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_nb/.classpath,v diff -u -r1.12.2.1 -r1.12.2.2 --- lams_tool_nb/.classpath 30 Jul 2014 14:23:25 -0000 1.12.2.1 +++ lams_tool_nb/.classpath 30 Jul 2014 16:17:33 -0000 1.12.2.2 @@ -4,9 +4,9 @@ - + - + Index: lams_tool_notebook/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_notebook/.classpath,v diff -u -r1.12.2.1 -r1.12.2.2 --- lams_tool_notebook/.classpath 30 Jul 2014 14:23:15 -0000 1.12.2.1 +++ lams_tool_notebook/.classpath 30 Jul 2014 16:17:14 -0000 1.12.2.2 @@ -4,9 +4,9 @@ - + - + Index: lams_tool_pixlr/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_pixlr/.classpath,v diff -u -r1.4.2.1 -r1.4.2.2 --- lams_tool_pixlr/.classpath 30 Jul 2014 14:23:10 -0000 1.4.2.1 +++ lams_tool_pixlr/.classpath 30 Jul 2014 16:17:16 -0000 1.4.2.2 @@ -4,9 +4,9 @@ - + - + Index: lams_tool_sbmt/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_sbmt/.classpath,v diff -u -r1.23.2.1 -r1.23.2.2 --- lams_tool_sbmt/.classpath 30 Jul 2014 14:23:30 -0000 1.23.2.1 +++ lams_tool_sbmt/.classpath 30 Jul 2014 16:17:42 -0000 1.23.2.2 @@ -3,9 +3,9 @@ - + - + Index: lams_tool_scratchie/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_scratchie/.classpath,v diff -u -r1.6.2.1 -r1.6.2.2 --- lams_tool_scratchie/.classpath 30 Jul 2014 14:23:29 -0000 1.6.2.1 +++ lams_tool_scratchie/.classpath 30 Jul 2014 16:17:31 -0000 1.6.2.2 @@ -3,7 +3,7 @@ - + Index: lams_tool_scribe/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_scribe/.classpath,v diff -u -r1.6.2.1 -r1.6.2.2 --- lams_tool_scribe/.classpath 30 Jul 2014 14:22:50 -0000 1.6.2.1 +++ lams_tool_scribe/.classpath 30 Jul 2014 16:17:44 -0000 1.6.2.2 @@ -4,9 +4,9 @@ - + - + Index: lams_tool_spreadsheet/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_spreadsheet/.classpath,v diff -u -r1.8.2.1 -r1.8.2.2 --- lams_tool_spreadsheet/.classpath 30 Jul 2014 14:22:44 -0000 1.8.2.1 +++ lams_tool_spreadsheet/.classpath 30 Jul 2014 16:17:34 -0000 1.8.2.2 @@ -4,9 +4,9 @@ - + - + Index: lams_tool_survey/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_survey/.classpath,v diff -u -r1.9.2.1 -r1.9.2.2 --- lams_tool_survey/.classpath 30 Jul 2014 14:23:19 -0000 1.9.2.1 +++ lams_tool_survey/.classpath 30 Jul 2014 16:17:48 -0000 1.9.2.2 @@ -4,9 +4,9 @@ - + - + Index: lams_tool_task/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_task/.classpath,v diff -u -r1.8.2.1 -r1.8.2.2 --- lams_tool_task/.classpath 30 Jul 2014 14:23:26 -0000 1.8.2.1 +++ lams_tool_task/.classpath 30 Jul 2014 16:17:11 -0000 1.8.2.2 @@ -4,9 +4,9 @@ - + - + Index: lams_tool_videorecorder/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_videorecorder/.classpath,v diff -u -r1.5.2.1 -r1.5.2.2 --- lams_tool_videorecorder/.classpath 30 Jul 2014 14:22:59 -0000 1.5.2.1 +++ lams_tool_videorecorder/.classpath 30 Jul 2014 16:17:17 -0000 1.5.2.2 @@ -4,9 +4,9 @@ - + - + Index: lams_tool_vote/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_vote/.classpath,v diff -u -r1.10.2.1 -r1.10.2.2 --- lams_tool_vote/.classpath 30 Jul 2014 14:23:04 -0000 1.10.2.1 +++ lams_tool_vote/.classpath 30 Jul 2014 16:17:47 -0000 1.10.2.2 @@ -4,9 +4,9 @@ - + - + Index: lams_tool_wiki/.classpath =================================================================== RCS file: /usr/local/cvsroot/lams_tool_wiki/.classpath,v diff -u -r1.9.2.1 -r1.9.2.2 --- lams_tool_wiki/.classpath 30 Jul 2014 14:23:24 -0000 1.9.2.1 +++ lams_tool_wiki/.classpath 30 Jul 2014 16:17:30 -0000 1.9.2.2 @@ -13,9 +13,9 @@ - + - +