diff --git a/core/src/main/java/org/hibernate/cfg/Configuration.java b/core/src/main/java/org/hibernate/cfg/Configuration.java index 2656043096..7e060bd0e3 100644 --- a/core/src/main/java/org/hibernate/cfg/Configuration.java +++ b/core/src/main/java/org/hibernate/cfg/Configuration.java @@ -58,6 +58,7 @@ import org.w3c.dom.Document; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; +import org.hibernate.DuplicateMappingException; import org.hibernate.EmptyInterceptor; import org.hibernate.HibernateException; import org.hibernate.Interceptor; @@ -66,9 +67,6 @@ import org.hibernate.MappingException; import org.hibernate.MappingNotFoundException; import org.hibernate.SessionFactory; import org.hibernate.SessionFactoryObserver; -import org.hibernate.DuplicateMappingException; -import org.hibernate.id.IdentifierGeneratorAggregator; -import org.hibernate.tuple.entity.EntityTuplizerFactory; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.MySQLDialect; import org.hibernate.dialect.function.SQLFunction; @@ -107,36 +105,39 @@ import org.hibernate.event.RefreshEventListener; import org.hibernate.event.ReplicateEventListener; import org.hibernate.event.SaveOrUpdateEventListener; import org.hibernate.id.IdentifierGenerator; +import org.hibernate.id.IdentifierGeneratorAggregator; import org.hibernate.id.PersistentIdentifierGenerator; -import org.hibernate.id.factory.IdentifierGeneratorFactory; import org.hibernate.id.factory.DefaultIdentifierGeneratorFactory; +import org.hibernate.id.factory.IdentifierGeneratorFactory; import org.hibernate.impl.SessionFactoryImpl; import org.hibernate.mapping.AuxiliaryDatabaseObject; import org.hibernate.mapping.Collection; +import org.hibernate.mapping.Column; +import org.hibernate.mapping.DenormalizedTable; +import org.hibernate.mapping.FetchProfile; import org.hibernate.mapping.ForeignKey; import org.hibernate.mapping.IdentifierCollection; import org.hibernate.mapping.Index; +import org.hibernate.mapping.MappedSuperclass; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.mapping.RootClass; import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Table; -import org.hibernate.mapping.UniqueKey; -import org.hibernate.mapping.FetchProfile; -import org.hibernate.mapping.DenormalizedTable; import org.hibernate.mapping.TypeDef; -import org.hibernate.mapping.Column; -import org.hibernate.mapping.MappedSuperclass; +import org.hibernate.mapping.UniqueKey; import org.hibernate.proxy.EntityNotFoundDelegate; import org.hibernate.secure.JACCConfiguration; import org.hibernate.tool.hbm2ddl.DatabaseMetadata; -import org.hibernate.tool.hbm2ddl.TableMetadata; import org.hibernate.tool.hbm2ddl.IndexMetadata; +import org.hibernate.tool.hbm2ddl.TableMetadata; +import org.hibernate.tuple.entity.EntityTuplizerFactory; import org.hibernate.type.BasicType; -import org.hibernate.type.BasicTypeRegistry; import org.hibernate.type.SerializationException; import org.hibernate.type.Type; import org.hibernate.type.TypeResolver; +import org.hibernate.usertype.CompositeUserType; +import org.hibernate.usertype.UserType; import org.hibernate.util.ArrayHelper; import org.hibernate.util.CollectionHelper; import org.hibernate.util.ConfigHelper; @@ -2287,10 +2288,25 @@ public class Configuration implements Serializable { return typeResolver; } + /** + * Allows registration of a type into the type regsitry. The phrase 'override' in the method name simply + * reminds that registration *potentially* replaces a previously registered type . + * + * @param type The type to register. + */ public void registerTypeOverride(BasicType type) { getTypeResolver().registerTypeOverride( type ); } + + public void registerTypeOverride(UserType type, String[] keys) { + getTypeResolver().registerTypeOverride( type, keys ); + } + + public void registerTypeOverride(CompositeUserType type, String[] keys) { + getTypeResolver().registerTypeOverride( type, keys ); + } + public SessionFactoryObserver getSessionFactoryObserver() { return sessionFactoryObserver; } diff --git a/core/src/main/java/org/hibernate/type/BasicTypeRegistry.java b/core/src/main/java/org/hibernate/type/BasicTypeRegistry.java index 2f896b4f7a..663357f409 100644 --- a/core/src/main/java/org/hibernate/type/BasicTypeRegistry.java +++ b/core/src/main/java/org/hibernate/type/BasicTypeRegistry.java @@ -31,6 +31,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.hibernate.HibernateException; +import org.hibernate.usertype.CompositeUserType; +import org.hibernate.usertype.UserType; /** * A registry of {@link BasicType} instances @@ -146,6 +148,14 @@ public class BasicTypeRegistry implements Serializable { } } + public void register(UserType type, String[] keys) { + register( new CustomType( type, keys ) ); + } + + public void register(CompositeUserType type, String[] keys) { + register( new CompositeCustomType( type, keys ) ); + } + public BasicType getRegisteredType(String key) { return registry.get( key ); } diff --git a/core/src/main/java/org/hibernate/type/CompositeCustomType.java b/core/src/main/java/org/hibernate/type/CompositeCustomType.java index 386420bf6b..edde1f7f8e 100644 --- a/core/src/main/java/org/hibernate/type/CompositeCustomType.java +++ b/core/src/main/java/org/hibernate/type/CompositeCustomType.java @@ -29,10 +29,10 @@ import java.sql.PreparedStatement; 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; @@ -42,20 +42,40 @@ import org.hibernate.engine.Mapping; import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.engine.SessionImplementor; import org.hibernate.usertype.CompositeUserType; +import org.hibernate.usertype.LoggableUserType; +import org.hibernate.util.ArrayHelper; /** - * 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 CompositeType { +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(CompositeUserType userType) { + this( userType, ArrayHelper.EMPTY_STRING_ARRAY ); + } + + 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; } @@ -155,8 +175,8 @@ public class CompositeCustomType extends AbstractType implements CompositeType { public int getColumnSpan(Mapping mapping) throws MappingException { Type[] types = userType.getPropertyTypes(); int n=0; - for (int i=0; i { public static final UrlType INSTANCE = new UrlType(); @@ -83,4 +112,111 @@ public class BasicTypeRegistryTest extends TestCase { return true; } } + + public static class TotallyIrrelevantUserType implements UserType { + + public int[] sqlTypes() { + return new int[0]; + } + + public Class returnedClass() { + return null; + } + + public boolean equals(Object x, Object y) throws HibernateException { + return false; + } + + public int hashCode(Object x) throws HibernateException { + return 0; + } + + public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException { + return null; + } + + public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { + } + + public Object deepCopy(Object value) throws HibernateException { + return null; + } + + public boolean isMutable() { + return false; + } + + public Serializable disassemble(Object value) throws HibernateException { + return null; + } + + public Object assemble(Serializable cached, Object owner) throws HibernateException { + return null; + } + + public Object replace(Object original, Object target, Object owner) throws HibernateException { + return null; + } + } + + public static class TotallyIrrelevantCompositeUserType implements CompositeUserType { + + public String[] getPropertyNames() { + return new String[0]; + } + + public Type[] getPropertyTypes() { + return new Type[0]; + } + + public Object getPropertyValue(Object component, int property) throws HibernateException { + return null; + } + + public void setPropertyValue(Object component, int property, Object value) throws HibernateException { + } + + public Class returnedClass() { + return null; + } + + public boolean equals(Object x, Object y) throws HibernateException { + return false; + } + + public int hashCode(Object x) throws HibernateException { + return 0; + } + + public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) + throws HibernateException, SQLException { + return null; + } + + public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) + throws HibernateException, SQLException { + } + + public Object deepCopy(Object value) throws HibernateException { + return null; + } + + public boolean isMutable() { + return false; + } + + public Serializable disassemble(Object value, SessionImplementor session) throws HibernateException { + return null; + } + + public Object assemble(Serializable cached, SessionImplementor session, Object owner) + throws HibernateException { + return null; + } + + public Object replace(Object original, Object target, SessionImplementor session, Object owner) + throws HibernateException { + return null; + } + } }