HHH-7950 bind custom tuplizer on composite attribute

This commit is contained in:
Strong Liu 2013-01-28 22:36:59 +08:00
parent 2922922133
commit 34c3cec657
33 changed files with 341 additions and 236 deletions

View File

@ -89,7 +89,7 @@ public class BeanValidationEventListener
init( factory, properties ); init( factory, properties );
} }
} }
@Override
public boolean onPreInsert(PreInsertEvent event) { public boolean onPreInsert(PreInsertEvent event) {
validate( validate(
event.getEntity(), event.getPersister().getEntityMode(), event.getPersister(), event.getEntity(), event.getPersister().getEntityMode(), event.getPersister(),
@ -97,7 +97,7 @@ public class BeanValidationEventListener
); );
return false; return false;
} }
@Override
public boolean onPreUpdate(PreUpdateEvent event) { public boolean onPreUpdate(PreUpdateEvent event) {
validate( validate(
event.getEntity(), event.getPersister().getEntityMode(), event.getPersister(), event.getEntity(), event.getPersister().getEntityMode(), event.getPersister(),
@ -105,7 +105,7 @@ public class BeanValidationEventListener
); );
return false; return false;
} }
@Override
public boolean onPreDelete(PreDeleteEvent event) { public boolean onPreDelete(PreDeleteEvent event) {
validate( validate(
event.getEntity(), event.getPersister().getEntityMode(), event.getPersister(), event.getEntity(), event.getPersister().getEntityMode(), event.getPersister(),

View File

@ -31,6 +31,7 @@ import java.util.Properties;
import javax.validation.groups.Default; import javax.validation.groups.Default;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
/** /**
@ -44,12 +45,18 @@ public class GroupsPerOperation {
private static final Class<?>[] EMPTY_GROUPS = new Class<?>[] { }; private static final Class<?>[] EMPTY_GROUPS = new Class<?>[] { };
private Map<Operation, Class<?>[]> groupsPerOperation = new HashMap<Operation, Class<?>[]>(4); private Map<Operation, Class<?>[]> groupsPerOperation = new HashMap<Operation, Class<?>[]>(4);
private ClassLoaderService classLoaderService;
public GroupsPerOperation(Properties properties) { public GroupsPerOperation(Properties properties) {
this(properties, null);
}
public GroupsPerOperation(Properties properties, ClassLoaderService classLoaderService){
setGroupsForOperation( Operation.INSERT, properties ); setGroupsForOperation( Operation.INSERT, properties );
setGroupsForOperation( Operation.UPDATE, properties ); setGroupsForOperation( Operation.UPDATE, properties );
setGroupsForOperation( Operation.DELETE, properties ); setGroupsForOperation( Operation.DELETE, properties );
setGroupsForOperation( Operation.DDL, properties ); setGroupsForOperation( Operation.DDL, properties );
this.classLoaderService = classLoaderService;
} }
private void setGroupsForOperation(Operation operation, Properties properties) { private void setGroupsForOperation(Operation operation, Properties properties) {
@ -71,11 +78,16 @@ public class GroupsPerOperation {
for (String groupName : groupNames) { for (String groupName : groupNames) {
String cleanedGroupName = groupName.trim(); String cleanedGroupName = groupName.trim();
if ( cleanedGroupName.length() > 0) { if ( cleanedGroupName.length() > 0) {
try { if ( classLoaderService != null ) {
groupsList.add( ReflectHelper.classForName( cleanedGroupName ) ); groupsList.add( classLoaderService.classForName( cleanedGroupName ) );
} }
catch ( ClassNotFoundException e ) { else {
throw new HibernateException( "Unable to load class " + cleanedGroupName, e ); try {
groupsList.add( ReflectHelper.classForName( cleanedGroupName ) );
}
catch ( ClassNotFoundException e ) {
throw new HibernateException( "Unable to load class " + cleanedGroupName, e );
}
} }
} }
} }

View File

@ -143,7 +143,7 @@ class TypeSafeActivator {
for ( PersistentClass persistentClass : persistentClasses ) { for ( PersistentClass persistentClass : persistentClasses ) {
final String className = persistentClass.getClassName(); final String className = persistentClass.getClassName();
if ( className == null || className.length() == 0 ) { if ( StringHelper.isEmpty( className ) ) {
continue; continue;
} }
Class<?> clazz; Class<?> clazz;
@ -251,7 +251,7 @@ class TypeSafeActivator {
ClassLoaderService classLoaderService, ClassLoaderService classLoaderService,
Dialect dialect) { Dialect dialect) {
final ValidatorFactory factory = getValidatorFactory( properties ); final ValidatorFactory factory = getValidatorFactory( properties );
final Class<?>[] groupsArray = new GroupsPerOperation( properties ).get( GroupsPerOperation.Operation.DDL ); final Class<?>[] groupsArray = new GroupsPerOperation( properties, classLoaderService ).get( GroupsPerOperation.Operation.DDL );
final Set<Class<?>> groups = new HashSet<Class<?>>( Arrays.asList( groupsArray ) ); final Set<Class<?>> groups = new HashSet<Class<?>>( Arrays.asList( groupsArray ) );
for ( EntityBinding binding : bindings ) { for ( EntityBinding binding : bindings ) {

View File

@ -76,8 +76,8 @@ public class DerbyDialect extends DB2Dialect {
final Class sysinfoClass = ReflectHelper.classForName( "org.apache.derby.tools.sysinfo", this.getClass() ); final Class sysinfoClass = ReflectHelper.classForName( "org.apache.derby.tools.sysinfo", this.getClass() );
final Method majorVersionGetter = sysinfoClass.getMethod( "getMajorVersion", ReflectHelper.NO_PARAM_SIGNATURE ); final Method majorVersionGetter = sysinfoClass.getMethod( "getMajorVersion", ReflectHelper.NO_PARAM_SIGNATURE );
final Method minorVersionGetter = sysinfoClass.getMethod( "getMinorVersion", ReflectHelper.NO_PARAM_SIGNATURE ); final Method minorVersionGetter = sysinfoClass.getMethod( "getMinorVersion", ReflectHelper.NO_PARAM_SIGNATURE );
driverVersionMajor = ( (Integer) majorVersionGetter.invoke( null, ReflectHelper.NO_PARAMS ) ).intValue(); driverVersionMajor = (Integer) majorVersionGetter.invoke( null, ReflectHelper.NO_PARAMS );
driverVersionMinor = ( (Integer) minorVersionGetter.invoke( null, ReflectHelper.NO_PARAMS ) ).intValue(); driverVersionMinor = (Integer) minorVersionGetter.invoke( null, ReflectHelper.NO_PARAMS );
} }
catch ( Exception e ) { catch ( Exception e ) {
LOG.unableToLoadDerbyDriver( e.getMessage() ); LOG.unableToLoadDerbyDriver( e.getMessage() );
@ -229,11 +229,7 @@ public String getForUpdateString() {
} }
private int getWithIndex(String querySelect) { private int getWithIndex(String querySelect) {
int i = querySelect.lastIndexOf( "with " ); return querySelect.toLowerCase().lastIndexOf( "with " );
if ( i < 0 ) {
i = querySelect.lastIndexOf( "WITH " );
}
return i;
} }
@Override @Override

View File

@ -28,6 +28,7 @@ import java.util.TreeMap;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
/** /**
* This class maps a type to names. Associations * This class maps a type to names. Associations
@ -63,8 +64,8 @@ import org.hibernate.internal.util.StringHelper;
*/ */
public class TypeNames { public class TypeNames {
private Map<Integer, Map<Long, String>> weighted = new HashMap<Integer, Map<Long, String>>(); private final Map<Integer, Map<Long, String>> weighted = new HashMap<Integer, Map<Long, String>>();
private Map<Integer, String> defaults = new HashMap<Integer, String>(); private final Map<Integer, String> defaults = new HashMap<Integer, String>();
/** /**
* get default type name for specified type * get default type name for specified type
@ -88,11 +89,11 @@ public class TypeNames {
*/ */
public String get(int typeCode, long size, int precision, int scale) throws MappingException { public String get(int typeCode, long size, int precision, int scale) throws MappingException {
Map<Long, String> map = weighted.get( typeCode ); Map<Long, String> map = weighted.get( typeCode );
if ( map!=null && map.size()>0 ) { if ( CollectionHelper.isNotEmpty( map ) ) {
// iterate entries ordered by capacity to find first fit // iterate entries ordered by capacity to find first fit
for (Map.Entry<Long, String> entry: map.entrySet()) { for ( final Long key : map.keySet() ) {
if ( size <= entry.getKey() ) { if ( size <= key ) {
return replace( entry.getValue(), size, precision, scale ); return replace( map.get( key ), size, precision, scale );
} }
} }
} }

View File

@ -61,6 +61,9 @@ import org.hibernate.service.spi.Stoppable;
public class DriverManagerConnectionProviderImpl public class DriverManagerConnectionProviderImpl
implements ConnectionProvider, Configurable, Stoppable, ServiceRegistryAwareService { implements ConnectionProvider, Configurable, Stoppable, ServiceRegistryAwareService {
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, DriverManagerConnectionProviderImpl.class.getName() ); private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, DriverManagerConnectionProviderImpl.class.getName() );
private static final boolean traceEnabled = LOG.isTraceEnabled();
private static final boolean debugEnabled = LOG.isDebugEnabled();
private String url; private String url;
private Properties connectionProps; private Properties connectionProps;
@ -92,7 +95,7 @@ public class DriverManagerConnectionProviderImpl
throw new UnknownUnwrapTypeException( unwrapType ); throw new UnknownUnwrapTypeException( unwrapType );
} }
} }
@Override
public void configure(Map configurationValues) { public void configure(Map configurationValues) {
LOG.usingHibernateBuiltInConnectionPool(); LOG.usingHibernateBuiltInConnectionPool();
@ -148,12 +151,12 @@ public class DriverManagerConnectionProviderImpl
LOG.usingDriver( driverClassName, url ); LOG.usingDriver( driverClassName, url );
// if debug level is enabled, then log the password, otherwise mask it // if debug level is enabled, then log the password, otherwise mask it
if ( LOG.isDebugEnabled() ) if ( debugEnabled )
LOG.connectionProperties( connectionProps ); LOG.connectionProperties( connectionProps );
else else
LOG.connectionProperties( ConfigurationHelper.maskOut( connectionProps, "password" ) ); LOG.connectionProperties( ConfigurationHelper.maskOut( connectionProps, "password" ) );
} }
@Override
public void stop() { public void stop() {
LOG.cleaningUpConnectionPool( url ); LOG.cleaningUpConnectionPool( url );
@ -168,9 +171,8 @@ public class DriverManagerConnectionProviderImpl
pool.clear(); pool.clear();
stopped = true; stopped = true;
} }
@Override
public Connection getConnection() throws SQLException { public Connection getConnection() throws SQLException {
final boolean traceEnabled = LOG.isTraceEnabled();
if ( traceEnabled ) LOG.tracev( "Total checked-out connections: {0}", checkedOut.intValue() ); if ( traceEnabled ) LOG.tracev( "Total checked-out connections: {0}", checkedOut.intValue() );
// essentially, if we have available connections in the pool, use one... // essentially, if we have available connections in the pool, use one...
@ -191,8 +193,6 @@ public class DriverManagerConnectionProviderImpl
} }
// otherwise we open a new connection... // otherwise we open a new connection...
final boolean debugEnabled = LOG.isDebugEnabled();
if ( debugEnabled ) LOG.debug( "Opening new JDBC connection" ); if ( debugEnabled ) LOG.debug( "Opening new JDBC connection" );
Connection conn = DriverManager.getConnection( url, connectionProps ); Connection conn = DriverManager.getConnection( url, connectionProps );
@ -210,11 +210,9 @@ public class DriverManagerConnectionProviderImpl
checkedOut.incrementAndGet(); checkedOut.incrementAndGet();
return conn; return conn;
} }
@Override
public void closeConnection(Connection conn) throws SQLException { public void closeConnection(Connection conn) throws SQLException {
checkedOut.decrementAndGet(); checkedOut.decrementAndGet();
final boolean traceEnabled = LOG.isTraceEnabled();
// add to the pool if the max size is not yet reached. // add to the pool if the max size is not yet reached.
synchronized ( pool ) { synchronized ( pool ) {
int currentSize = pool.size(); int currentSize = pool.size();
@ -224,7 +222,6 @@ public class DriverManagerConnectionProviderImpl
return; return;
} }
} }
LOG.debug( "Closing JDBC connection" ); LOG.debug( "Closing JDBC connection" );
conn.close(); conn.close();
} }
@ -236,7 +233,7 @@ public class DriverManagerConnectionProviderImpl
} }
super.finalize(); super.finalize();
} }
@Override
public boolean supportsAggressiveRelease() { public boolean supportsAggressiveRelease() {
return false; return false;
} }

View File

@ -29,6 +29,8 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import org.hibernate.QueryException; import org.hibernate.QueryException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.dialect.function.SQLFunction; import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.hql.internal.QuerySplitter; import org.hibernate.hql.internal.QuerySplitter;
import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.ReflectHelper;
@ -44,7 +46,7 @@ public class SelectParser implements Parser {
//TODO: arithmetic expressions, multiple new Foo(...) //TODO: arithmetic expressions, multiple new Foo(...)
private static final Set COUNT_MODIFIERS = new HashSet(); private static final Set<String> COUNT_MODIFIERS = new HashSet<String>();
static { static {
COUNT_MODIFIERS.add( "distinct" ); COUNT_MODIFIERS.add( "distinct" );
@ -52,7 +54,7 @@ public class SelectParser implements Parser {
COUNT_MODIFIERS.add( "*" ); COUNT_MODIFIERS.add( "*" );
} }
private LinkedList aggregateFuncTokenList = new LinkedList(); private LinkedList<String> aggregateFuncTokenList = new LinkedList<String>();
private boolean ready; private boolean ready;
private boolean aggregate; private boolean aggregate;
@ -72,7 +74,7 @@ public class SelectParser implements Parser {
pathExpressionParser.setUseThetaStyleJoin( true ); pathExpressionParser.setUseThetaStyleJoin( true );
aggregatePathExpressionParser.setUseThetaStyleJoin( true ); aggregatePathExpressionParser.setUseThetaStyleJoin( true );
} }
@Override
public void token(String token, QueryTranslatorImpl q) throws QueryException { public void token(String token, QueryTranslatorImpl q) throws QueryException {
String lctoken = token.toLowerCase(); String lctoken = token.toLowerCase();
@ -92,9 +94,12 @@ public class SelectParser implements Parser {
if ( afterNew ) { if ( afterNew ) {
afterNew = false; afterNew = false;
try { try {
holderClass = ReflectHelper.classForName( QuerySplitter.getImportedClass( token, q.getFactory() ) ); final ClassLoaderService classLoaderService = q.getFactory()
.getServiceRegistry()
.getService( ClassLoaderService.class );
holderClass = classLoaderService.classForName( QuerySplitter.getImportedClass( token, q.getFactory() ) );
} }
catch ( ClassNotFoundException cnfe ) { catch ( ClassLoadingException cnfe ) {
throw new QueryException( cnfe ); throw new QueryException( cnfe );
} }
if ( holderClass == null ) throw new QueryException( "class not found: " + token ); if ( holderClass == null ) throw new QueryException( "class not found: " + token );
@ -238,7 +243,7 @@ public class SelectParser implements Parser {
private SQLFunction getFunction(String name, QueryTranslatorImpl q) { private SQLFunction getFunction(String name, QueryTranslatorImpl q) {
return q.getFactory().getSqlFunctionRegistry().findSQLFunction( name ); return q.getFactory().getSqlFunctionRegistry().findSQLFunction( name );
} }
@Override
public void start(QueryTranslatorImpl q) { public void start(QueryTranslatorImpl q) {
ready = true; ready = true;
first = true; first = true;
@ -248,7 +253,7 @@ public class SelectParser implements Parser {
holderClass = null; holderClass = null;
aggregateFuncTokenList.clear(); aggregateFuncTokenList.clear();
} }
@Override
public void end(QueryTranslatorImpl q) { public void end(QueryTranslatorImpl q) {
} }

View File

@ -30,6 +30,8 @@ import java.util.concurrent.ConcurrentHashMap;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.id.Assigned; import org.hibernate.id.Assigned;
@ -66,6 +68,7 @@ public class DefaultIdentifierGeneratorFactory implements MutableIdentifierGener
DefaultIdentifierGeneratorFactory.class.getName()); DefaultIdentifierGeneratorFactory.class.getName());
private transient Dialect dialect; private transient Dialect dialect;
private transient ClassLoaderService classLoaderService;
private ConcurrentHashMap<String, Class> generatorStrategyToClassNameMap = new ConcurrentHashMap<String, Class>(); private ConcurrentHashMap<String, Class> generatorStrategyToClassNameMap = new ConcurrentHashMap<String, Class>();
/** /**
@ -133,9 +136,18 @@ public class DefaultIdentifierGeneratorFactory implements MutableIdentifierGener
Class generatorClass = generatorStrategyToClassNameMap.get( strategy ); Class generatorClass = generatorStrategyToClassNameMap.get( strategy );
try { try {
if ( generatorClass == null ) { if ( generatorClass == null ) {
generatorClass = ReflectHelper.classForName( strategy ); if ( classLoaderService != null ) {
generatorClass = classLoaderService.classForName( strategy );
}
else {
generatorClass = ReflectHelper.classForName( strategy );
}
register( strategy, generatorClass );
} }
} }
catch ( ClassLoadingException e ) {
throw new MappingException( String.format( "Could not interpret id generator strategy [%s]", strategy ) );
}
catch ( ClassNotFoundException e ) { catch ( ClassNotFoundException e ) {
throw new MappingException( String.format( "Could not interpret id generator strategy [%s]", strategy ) ); throw new MappingException( String.format( "Could not interpret id generator strategy [%s]", strategy ) );
} }
@ -145,5 +157,6 @@ public class DefaultIdentifierGeneratorFactory implements MutableIdentifierGener
@Override @Override
public void injectServices(ServiceRegistryImplementor serviceRegistry) { public void injectServices(ServiceRegistryImplementor serviceRegistry) {
this.dialect = serviceRegistry.getService( JdbcServices.class ).getDialect(); this.dialect = serviceRegistry.getService( JdbcServices.class ).getDialect();
this.classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
} }
} }

View File

@ -92,7 +92,7 @@ public final class ReflectHelper {
* @return The equals method reference * @return The equals method reference
* @throws NoSuchMethodException Should indicate an attempt to extract equals method from interface. * @throws NoSuchMethodException Should indicate an attempt to extract equals method from interface.
*/ */
public static Method extractEqualsMethod(Class clazz) throws NoSuchMethodException { public static Method extractEqualsMethod(Class<?> clazz) throws NoSuchMethodException {
return clazz.getMethod( "equals", SINGLE_OBJECT_PARAM_SIGNATURE ); return clazz.getMethod( "equals", SINGLE_OBJECT_PARAM_SIGNATURE );
} }
@ -103,7 +103,7 @@ public final class ReflectHelper {
* @return The hashCode method reference * @return The hashCode method reference
* @throws NoSuchMethodException Should indicate an attempt to extract hashCode method from interface. * @throws NoSuchMethodException Should indicate an attempt to extract hashCode method from interface.
*/ */
public static Method extractHashCodeMethod(Class clazz) throws NoSuchMethodException { public static Method extractHashCodeMethod(Class<?> clazz) throws NoSuchMethodException {
return clazz.getMethod( "hashCode", NO_PARAM_SIGNATURE ); return clazz.getMethod( "hashCode", NO_PARAM_SIGNATURE );
} }
@ -148,7 +148,7 @@ public final class ReflectHelper {
* @param intf The interface to check it against. * @param intf The interface to check it against.
* @return True if the class does implement the interface, false otherwise. * @return True if the class does implement the interface, false otherwise.
*/ */
public static boolean implementsInterface(Class clazz, Class intf) { public static boolean implementsInterface(Class clazz, Class<?> intf) {
assert intf.isInterface() : "Interface to check was not an interface"; assert intf.isInterface() : "Interface to check was not an interface";
return intf.isAssignableFrom( clazz ); return intf.isAssignableFrom( clazz );
} }
@ -173,7 +173,12 @@ public final class ReflectHelper {
} }
catch ( Throwable ignore ) { catch ( Throwable ignore ) {
} }
return Class.forName( name, true, caller.getClassLoader() ); if ( caller != null ) {
return Class.forName( name, true, caller.getClassLoader() );
}
else {
return Class.forName( name );
}
} }
/** /**
@ -187,15 +192,7 @@ public final class ReflectHelper {
* @throws ClassNotFoundException From {@link Class#forName(String)}. * @throws ClassNotFoundException From {@link Class#forName(String)}.
*/ */
public static Class classForName(String name) throws ClassNotFoundException { public static Class classForName(String name) throws ClassNotFoundException {
try { return classForName( name, null );
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
if ( contextClassLoader != null ) {
return contextClassLoader.loadClass(name);
}
}
catch ( Throwable ignore ) {
}
return Class.forName( name );
} }
/** /**
@ -231,7 +228,7 @@ public final class ReflectHelper {
*/ */
public static Class reflectedPropertyClass(String className, String name) throws MappingException { public static Class reflectedPropertyClass(String className, String name) throws MappingException {
try { try {
Class clazz = ReflectHelper.classForName( className ); Class clazz = classForName( className );
return getter( clazz, name ).getReturnType(); return getter( clazz, name ).getReturnType();
} }
catch ( ClassNotFoundException cnfe ) { catch ( ClassNotFoundException cnfe ) {
@ -301,7 +298,7 @@ public final class ReflectHelper {
* @return The default constructor. * @return The default constructor.
* @throws PropertyNotFoundException Indicates there was not publicly accessible, no-arg constructor (todo : why PropertyNotFoundException???) * @throws PropertyNotFoundException Indicates there was not publicly accessible, no-arg constructor (todo : why PropertyNotFoundException???)
*/ */
public static Constructor getDefaultConstructor(Class clazz) throws PropertyNotFoundException { public static Constructor getDefaultConstructor(Class<?> clazz) throws PropertyNotFoundException {
if ( isAbstractClass( clazz ) ) { if ( isAbstractClass( clazz ) ) {
return null; return null;
} }
@ -378,7 +375,7 @@ public final class ReflectHelper {
throw new PropertyNotFoundException( "no appropriate constructor in class: " + clazz.getName() ); throw new PropertyNotFoundException( "no appropriate constructor in class: " + clazz.getName() );
} }
public static Method getMethod(Class clazz, Method method) { public static Method getMethod(Class<?> clazz, Method method) {
try { try {
return clazz.getMethod( method.getName(), method.getParameterTypes() ); return clazz.getMethod( method.getName(), method.getParameterTypes() );
} }

View File

@ -40,6 +40,7 @@ import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode; import org.hibernate.EntityMode;
import org.hibernate.MultiTenancyStrategy; import org.hibernate.MultiTenancyStrategy;
import org.hibernate.TruthValue; import org.hibernate.TruthValue;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.cfg.ObjectNameNormalizer; import org.hibernate.cfg.ObjectNameNormalizer;
@ -1046,6 +1047,12 @@ public class Binder {
naturalIdMutability, naturalIdMutability,
createMetaAttributeContext( attributeBindingContainer, attributeSource ) createMetaAttributeContext( attributeBindingContainer, attributeSource )
); );
if ( attributeSource.getExplicitTuplizerClassName() != null ) {
Class tuplizerClass = bindingContext().getServiceRegistry()
.getService( ClassLoaderService.class )
.classForName( attributeSource.getExplicitTuplizerClassName() );
attributeBinding.setCustomComponentTuplizerClass( tuplizerClass );
}
bindAttributes( attributeBinding, attributeSource ); bindAttributes( attributeBinding, attributeSource );
typeHelper.bindAggregatedCompositeAttributeType( typeHelper.bindAggregatedCompositeAttributeType(
isAttributeIdentifier, isAttributeIdentifier,

View File

@ -104,7 +104,8 @@ public class ComponentAttributeSourceImpl implements ComponentAttributeSource {
@Override @Override
public String getExplicitTuplizerClassName() { public String getExplicitTuplizerClassName() {
return embeddableClass.getCustomTuplizer(); return StringHelper.isEmpty( embeddableClass.getCustomTuplizerClass() ) ? embeddableClass.getCustomTuplizer() : embeddableClass
.getCustomTuplizerClass();
} }
@Override @Override

View File

@ -99,12 +99,13 @@ public class BasicAttribute extends MappedAttribute {
private final String customReadFragment; private final String customReadFragment;
private AttributeTypeResolver resolver; private AttributeTypeResolver resolver;
public static BasicAttribute createSimpleAttribute(String name, public static BasicAttribute createSimpleAttribute(
Class<?> attributeType, String name,
Nature attributeNature, Class<?> attributeType,
Map<DotName, List<AnnotationInstance>> annotations, Nature attributeNature,
String accessType, Map<DotName, List<AnnotationInstance>> annotations,
EntityBindingContext context) { String accessType,
EntityBindingContext context) {
return new BasicAttribute( name, attributeType, attributeNature, accessType, annotations, context ); return new BasicAttribute( name, attributeType, attributeNature, accessType, annotations, context );
} }
@ -124,7 +125,8 @@ public class BasicAttribute extends MappedAttribute {
annotations, annotations,
HibernateDotNames.SOURCE HibernateDotNames.SOURCE
); );
this.versionSourceType = sourceAnnotation !=null ? JandexHelper.getEnumValue( sourceAnnotation, "value", SourceType.class ) : null; this.versionSourceType = sourceAnnotation !=null ?
JandexHelper.getEnumValue( sourceAnnotation, "value", SourceType.class ) : null;
} }
else { else {
versionSourceType = null; versionSourceType = null;
@ -133,7 +135,7 @@ public class BasicAttribute extends MappedAttribute {
if ( isId() ) { if ( isId() ) {
// an id must be unique and cannot be nullable // an id must be unique and cannot be nullable
for(Column columnValue : getColumnValues()) { for ( Column columnValue : getColumnValues() ) {
columnValue.setUnique( true ); columnValue.setUnique( true );
columnValue.setNullable( false ); columnValue.setNullable( false );
} }

View File

@ -247,8 +247,8 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
if ( naturalIdAnnotation == null ) { if ( naturalIdAnnotation == null ) {
return SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID; return SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID;
} }
final boolean mutable = naturalIdAnnotation.value( "mutable" ) == null ? false : final boolean mutable = naturalIdAnnotation.value( "mutable" ) != null && naturalIdAnnotation.value( "mutable" )
naturalIdAnnotation.value( "mutable" ).asBoolean(); .asBoolean();
return mutable ? SingularAttributeBinding.NaturalIdMutability.MUTABLE : SingularAttributeBinding.NaturalIdMutability.IMMUTABLE; return mutable ? SingularAttributeBinding.NaturalIdMutability.MUTABLE : SingularAttributeBinding.NaturalIdMutability.IMMUTABLE;
} }

View File

@ -54,6 +54,7 @@ import org.hibernate.metamodel.internal.source.annotations.attribute.AttributeOv
import org.hibernate.metamodel.internal.source.annotations.attribute.BasicAttribute; import org.hibernate.metamodel.internal.source.annotations.attribute.BasicAttribute;
import org.hibernate.metamodel.internal.source.annotations.attribute.MappedAttribute; import org.hibernate.metamodel.internal.source.annotations.attribute.MappedAttribute;
import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute; import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute;
import org.hibernate.metamodel.internal.source.annotations.util.AnnotationParserHelper;
import org.hibernate.metamodel.internal.source.annotations.util.HibernateDotNames; import org.hibernate.metamodel.internal.source.annotations.util.HibernateDotNames;
import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames; import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper; import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper;
@ -574,11 +575,26 @@ public class ConfiguredClass {
else { else {
naturalIdMutability = SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID; naturalIdMutability = SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID;
} }
//tuplizer on field
final AnnotationInstance tuplizersAnnotation = JandexHelper.getSingleAnnotation(
annotations, HibernateDotNames.TUPLIZERS
);
final AnnotationInstance tuplizerAnnotation = JandexHelper.getSingleAnnotation(
annotations,
HibernateDotNames.TUPLIZER
);
final String customTuplizerClass = AnnotationParserHelper.determineCustomTuplizer(
tuplizersAnnotation,
tuplizerAnnotation
);
final EmbeddableHierarchy hierarchy = EmbeddableHierarchy.createEmbeddableHierarchy( final EmbeddableHierarchy hierarchy = EmbeddableHierarchy.createEmbeddableHierarchy(
localBindingContext.<Object>locateClassByName( embeddableClassInfo.toString() ), localBindingContext.<Object>locateClassByName( embeddableClassInfo.toString() ),
attributeName, attributeName,
classAccessType, classAccessType,
naturalIdMutability, naturalIdMutability,
customTuplizerClass,
localBindingContext localBindingContext
); );
return hierarchy.getLeaf(); return hierarchy.getLeaf();
@ -593,10 +609,10 @@ public class ConfiguredClass {
* *
* @return an instance of the {@code AttributeType} enum * @return an instance of the {@code AttributeType} enum
*/ */
private MappedAttribute.Nature determineAttributeNature( Map<DotName, private MappedAttribute.Nature determineAttributeNature(
List<AnnotationInstance>> annotations, final Map<DotName,List<AnnotationInstance>> annotations,
Class<?> attributeType, final Class<?> attributeType,
Class<?> referencedCollectionType ) { final Class<?> referencedCollectionType ) {
EnumSet<MappedAttribute.Nature> discoveredAttributeTypes = EnumSet.noneOf( MappedAttribute.Nature.class ); EnumSet<MappedAttribute.Nature> discoveredAttributeTypes = EnumSet.noneOf( MappedAttribute.Nature.class );
AnnotationInstance oneToOne = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_ONE ); AnnotationInstance oneToOne = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_ONE );
if ( oneToOne != null ) { if ( oneToOne != null ) {
@ -633,12 +649,10 @@ public class ConfiguredClass {
// annotations. (see HHH-7678) // annotations. (see HHH-7678)
// However, it's important to ignore this if the field is // However, it's important to ignore this if the field is
// annotated with @EmbeddedId. // annotated with @EmbeddedId.
ClassInfo typeClassInfo = localBindingContext.getIndex() if ( isEmbeddableType( attributeType ) ) {
.getClassByName( DotName.createSimple( attributeType.getName() ) ); LOG.warn( attributeType.getName() + " has @Embeddable on it, but the attribute of this type in entity["
if ( typeClassInfo != null + getName()
&& JandexHelper.getSingleAnnotation( + "] doesn't have @Embedded, which may cause compatibility issue" );
typeClassInfo.annotations(),
JPADotNames.EMBEDDABLE ) != null ) {
discoveredAttributeTypes.add( MappedAttribute.Nature.EMBEDDED ); discoveredAttributeTypes.add( MappedAttribute.Nature.EMBEDDED );
} }
} }
@ -771,48 +785,15 @@ public class ConfiguredClass {
return prefix; return prefix;
} }
private String determineCustomTuplizer() { protected String determineCustomTuplizer() {
final AnnotationInstance tuplizersAnnotation = JandexHelper.getSingleAnnotation( final AnnotationInstance tuplizersAnnotation = JandexHelper.getSingleAnnotation(
classInfo, HibernateDotNames.TUPLIZERS classInfo, HibernateDotNames.TUPLIZERS, ClassInfo.class
); );
final AnnotationInstance tuplizerAnnotation = JandexHelper.getSingleAnnotation( final AnnotationInstance tuplizerAnnotation = JandexHelper.getSingleAnnotation(
classInfo, classInfo,
HibernateDotNames.TUPLIZER HibernateDotNames.TUPLIZER,
ClassInfo.class
); );
if ( tuplizersAnnotation != null ) { return AnnotationParserHelper.determineCustomTuplizer( tuplizersAnnotation, tuplizerAnnotation );
AnnotationInstance[] annotations = JandexHelper.getValue(
tuplizersAnnotation,
"value",
AnnotationInstance[].class
);
for ( final AnnotationInstance annotationInstance : annotations ) {
final String impl = findTuplizerImpl( annotationInstance );
if ( StringHelper.isNotEmpty( impl ) ) {
return impl;
}
}
}
else if ( tuplizerAnnotation != null ) {
final String impl = findTuplizerImpl( tuplizerAnnotation );
if ( StringHelper.isNotEmpty( impl ) ) {
return impl;
}
}
return null;
}
private String findTuplizerImpl(final AnnotationInstance tuplizerAnnotation) {
EntityMode mode;
if ( tuplizerAnnotation.value( "entityModeType" ) != null ) {
mode = EntityMode.valueOf( tuplizerAnnotation.value( "entityModeType" ).asEnum() );
}
else if ( tuplizerAnnotation.value( "entityMode" ) != null ) {
mode = EntityMode.parse( tuplizerAnnotation.value( "entityMode" ).asString() );
}
else {
mode = EntityMode.POJO;
}
return mode == EntityMode.POJO ? tuplizerAnnotation.value( "impl" ).asString() : null;
} }
} }

View File

@ -41,6 +41,8 @@ import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
public class EmbeddableClass extends ConfiguredClass { public class EmbeddableClass extends ConfiguredClass {
private final String embeddedAttributeName; private final String embeddedAttributeName;
private final String parentReferencingAttributeName; private final String parentReferencingAttributeName;
//custom tuplizer defined on the embedded field
private final String customTuplizerClass;
private SingularAttributeBinding.NaturalIdMutability naturalIdMutability; private SingularAttributeBinding.NaturalIdMutability naturalIdMutability;
public EmbeddableClass( public EmbeddableClass(
@ -49,11 +51,13 @@ public class EmbeddableClass extends ConfiguredClass {
ConfiguredClass parent, ConfiguredClass parent,
AccessType defaultAccessType, AccessType defaultAccessType,
SingularAttributeBinding.NaturalIdMutability naturalIdMutability, SingularAttributeBinding.NaturalIdMutability naturalIdMutability,
String customTuplizerClass,
AnnotationBindingContext context) { AnnotationBindingContext context) {
super( classInfo, defaultAccessType, parent, context ); super( classInfo, defaultAccessType, parent, context );
this.embeddedAttributeName = embeddedAttributeName; this.embeddedAttributeName = embeddedAttributeName;
this.naturalIdMutability = naturalIdMutability; this.naturalIdMutability = naturalIdMutability;
this.parentReferencingAttributeName = checkParentAnnotation(); this.parentReferencingAttributeName = checkParentAnnotation();
this.customTuplizerClass = customTuplizerClass;
} }
private String checkParentAnnotation() { private String checkParentAnnotation() {
@ -79,6 +83,10 @@ public class EmbeddableClass extends ConfiguredClass {
public void setNaturalIdMutability(SingularAttributeBinding.NaturalIdMutability naturalIdMutability) { public void setNaturalIdMutability(SingularAttributeBinding.NaturalIdMutability naturalIdMutability) {
this.naturalIdMutability = naturalIdMutability; this.naturalIdMutability = naturalIdMutability;
} }
public String getCustomTuplizerClass() {
return customTuplizerClass;
}
} }

View File

@ -35,7 +35,7 @@ import org.hibernate.AssertionFailure;
import org.hibernate.metamodel.internal.source.annotations.AnnotationBindingContext; import org.hibernate.metamodel.internal.source.annotations.AnnotationBindingContext;
import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames; import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper; import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import static org.hibernate.metamodel.spi.binding.SingularAttributeBinding.NaturalIdMutability;
/** /**
* Contains information about the access and inheritance type for all classes within a class hierarchy. * Contains information about the access and inheritance type for all classes within a class hierarchy.
@ -45,7 +45,6 @@ import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
public class EmbeddableHierarchy implements Iterable<EmbeddableClass> { public class EmbeddableHierarchy implements Iterable<EmbeddableClass> {
private final AccessType defaultAccessType; private final AccessType defaultAccessType;
private final List<EmbeddableClass> embeddables; private final List<EmbeddableClass> embeddables;
/** /**
* Builds the configured class hierarchy for a an embeddable class. * Builds the configured class hierarchy for a an embeddable class.
* *
@ -56,11 +55,15 @@ public class EmbeddableHierarchy implements Iterable<EmbeddableClass> {
* *
* @return a set of {@code ConfiguredClassHierarchy}s. One for each "leaf" entity. * @return a set of {@code ConfiguredClassHierarchy}s. One for each "leaf" entity.
*/ */
public static EmbeddableHierarchy createEmbeddableHierarchy(Class<?> embeddableClass, String propertyName, public static EmbeddableHierarchy createEmbeddableHierarchy(
AccessType accessType, final Class<?> embeddableClass,
SingularAttributeBinding.NaturalIdMutability naturalIdMutability, AnnotationBindingContext context) { final String propertyName,
final AccessType accessType,
final NaturalIdMutability naturalIdMutability,
final String customTuplizerClass,
final AnnotationBindingContext context) {
ClassInfo embeddableClassInfo = context.getClassInfo( embeddableClass.getName() ); final ClassInfo embeddableClassInfo = context.getClassInfo( embeddableClass.getName() );
if ( embeddableClassInfo == null ) { if ( embeddableClassInfo == null ) {
throw new AssertionFailure( throw new AssertionFailure(
String.format( String.format(
@ -85,11 +88,10 @@ public class EmbeddableHierarchy implements Iterable<EmbeddableClass> {
Class<?> clazz = embeddableClass; Class<?> clazz = embeddableClass;
while ( clazz != null && !clazz.equals( Object.class ) ) { while ( clazz != null && !clazz.equals( Object.class ) ) {
ClassInfo tmpClassInfo = context.getIndex().getClassByName( DotName.createSimple( clazz.getName() ) ); ClassInfo tmpClassInfo = context.getIndex().getClassByName( DotName.createSimple( clazz.getName() ) );
clazz = clazz.getSuperclass();
if ( tmpClassInfo == null ) { if ( tmpClassInfo == null ) {
continue; continue;
} }
clazz = clazz.getSuperclass();
classInfoList.add( 0, tmpClassInfo ); classInfoList.add( 0, tmpClassInfo );
} }
@ -97,6 +99,7 @@ public class EmbeddableHierarchy implements Iterable<EmbeddableClass> {
classInfoList, classInfoList,
propertyName, propertyName,
naturalIdMutability, naturalIdMutability,
customTuplizerClass,
context, context,
accessType accessType
); );
@ -104,13 +107,13 @@ public class EmbeddableHierarchy implements Iterable<EmbeddableClass> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private EmbeddableHierarchy( private EmbeddableHierarchy(
List<ClassInfo> classInfoList, final List<ClassInfo> classInfoList,
String propertyName, final String propertyName,
SingularAttributeBinding.NaturalIdMutability naturalIdMutability, final NaturalIdMutability naturalIdMutability,
AnnotationBindingContext context, final String customTuplizerClass,
AccessType defaultAccessType) { final AnnotationBindingContext context,
final AccessType defaultAccessType) {
this.defaultAccessType = defaultAccessType; this.defaultAccessType = defaultAccessType;
// the resolved type for the top level class in the hierarchy // the resolved type for the top level class in the hierarchy
context.resolveAllTypes( classInfoList.get( classInfoList.size() - 1 ).name().toString() ); context.resolveAllTypes( classInfoList.get( classInfoList.size() - 1 ).name().toString() );
@ -118,7 +121,7 @@ public class EmbeddableHierarchy implements Iterable<EmbeddableClass> {
ConfiguredClass parent = null; ConfiguredClass parent = null;
for ( ClassInfo info : classInfoList ) { for ( ClassInfo info : classInfoList ) {
EmbeddableClass embeddable = new EmbeddableClass( EmbeddableClass embeddable = new EmbeddableClass(
info, propertyName, parent, defaultAccessType,naturalIdMutability, context info, propertyName, parent, defaultAccessType,naturalIdMutability,customTuplizerClass, context
); );
embeddables.add( embeddable ); embeddables.add( embeddable );
parent = embeddable; parent = embeddable;
@ -133,6 +136,7 @@ public class EmbeddableHierarchy implements Iterable<EmbeddableClass> {
/** /**
* @return An iterator iterating in top down manner over the configured classes in this hierarchy. * @return An iterator iterating in top down manner over the configured classes in this hierarchy.
*/ */
@Override
public Iterator<EmbeddableClass> iterator() { public Iterator<EmbeddableClass> iterator() {
return embeddables.iterator(); return embeddables.iterator();
} }

View File

@ -27,9 +27,12 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName; import org.jboss.jandex.DotName;
import org.hibernate.EntityMode;
import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle; import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.metamodel.spi.binding.CustomSQL; import org.hibernate.metamodel.spi.binding.CustomSQL;
/** /**
@ -69,6 +72,45 @@ public class AnnotationParserHelper {
return new CustomSQL( sql, isCallable, checkStyle ); return new CustomSQL( sql, isCallable, checkStyle );
} }
public static String determineCustomTuplizer(
final AnnotationInstance tuplizersAnnotation,
final AnnotationInstance tuplizerAnnotation) {
if ( tuplizersAnnotation != null ) {
AnnotationInstance[] annotations = JandexHelper.getValue(
tuplizersAnnotation,
"value",
AnnotationInstance[].class
);
for ( final AnnotationInstance annotationInstance : annotations ) {
final String impl = findTuplizerImpl( annotationInstance );
if ( StringHelper.isNotEmpty( impl ) ) {
return impl;
}
}
}
else if ( tuplizerAnnotation != null ) {
final String impl = findTuplizerImpl( tuplizerAnnotation );
if ( StringHelper.isNotEmpty( impl ) ) {
return impl;
}
}
return null;
}
private static String findTuplizerImpl(final AnnotationInstance tuplizerAnnotation) {
final EntityMode mode;
if ( tuplizerAnnotation.value( "entityModeType" ) != null ) {
mode = EntityMode.valueOf( tuplizerAnnotation.value( "entityModeType" ).asEnum() );
}
else if ( tuplizerAnnotation.value( "entityMode" ) != null ) {
mode = EntityMode.parse( tuplizerAnnotation.value( "entityMode" ).asString() );
}
else {
mode = EntityMode.POJO;
}
return mode == EntityMode.POJO ? tuplizerAnnotation.value( "impl" ).asString() : null;
}
} }

View File

@ -31,6 +31,8 @@ import org.hibernate.metamodel.spi.domain.PluralAttribute;
import org.hibernate.metamodel.spi.domain.SingularAttribute; import org.hibernate.metamodel.spi.domain.SingularAttribute;
import org.hibernate.metamodel.spi.relational.TableSpecification; import org.hibernate.metamodel.spi.relational.TableSpecification;
import org.hibernate.metamodel.spi.source.MetaAttributeContext; import org.hibernate.metamodel.spi.source.MetaAttributeContext;
import org.hibernate.tuple.Tuplizer;
import org.hibernate.tuple.component.ComponentTuplizer;
/** /**
* A container for attribute bindings that make up composite grouping * A container for attribute bindings that make up composite grouping
@ -91,6 +93,11 @@ public abstract class AbstractCompositeAttributeBindingContainer
return primaryTable; return primaryTable;
} }
@Override
public Class<? extends ComponentTuplizer> getCustomTuplizerClass() {
return null;
}
protected abstract boolean isModifiable(); protected abstract boolean isModifiable();
@Override @Override

View File

@ -8,14 +8,14 @@
* *
* This copyrighted material is made available to anyone wishing to use, modify, * 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 * copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation. * Lesser General License, as published by the Free Software Foundation.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General License
* for more details. * for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General License
* along with this distribution; if not, write to: * along with this distribution; if not, write to:
* Free Software Foundation, Inc. * Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor * 51 Franklin Street, Fifth Floor
@ -32,6 +32,7 @@ import org.hibernate.metamodel.spi.domain.SingularAttribute;
import org.hibernate.metamodel.spi.relational.TableSpecification; import org.hibernate.metamodel.spi.relational.TableSpecification;
import org.hibernate.metamodel.spi.relational.Value; import org.hibernate.metamodel.spi.relational.Value;
import org.hibernate.metamodel.spi.source.MetaAttributeContext; import org.hibernate.metamodel.spi.source.MetaAttributeContext;
import org.hibernate.tuple.Tuplizer;
/** /**
* Common contract for {@link EntityBinding} and {@link CompositeAttributeBinding} in so far as they are both * Common contract for {@link EntityBinding} and {@link CompositeAttributeBinding} in so far as they are both
@ -45,21 +46,21 @@ public interface AttributeBindingContainer {
* *
* @return The path base for this container. * @return The path base for this container.
*/ */
public String getPathBase(); String getPathBase();
/** /**
* Obtain the underlying domain attribute container. * Obtain the underlying domain attribute container.
* *
* @return The attribute container * @return The attribute container
*/ */
public AttributeContainer getAttributeContainer(); AttributeContainer getAttributeContainer();
/** /**
* Obtain all attribute bindings * Obtain all attribute bindings
* *
* @return All attribute bindings * @return All attribute bindings
*/ */
public Iterable<AttributeBinding> attributeBindings(); Iterable<AttributeBinding> attributeBindings();
/** /**
* Return the number of attribute bindings returned by * Return the number of attribute bindings returned by
@ -68,7 +69,13 @@ public interface AttributeBindingContainer {
* @return the number of attribute bindings returned by * @return the number of attribute bindings returned by
* {@link #attributeBindings()}. * {@link #attributeBindings()}.
*/ */
public int attributeBindingSpan(); int attributeBindingSpan();
/**
* Return the custom tuplizer class.
* @return
*/
Class<? extends Tuplizer> getCustomTuplizerClass();
/** /**
* Locate a specific attribute binding, by its local name. * Locate a specific attribute binding, by its local name.
@ -77,7 +84,7 @@ public interface AttributeBindingContainer {
* *
* @return The attribute binding or {@code null} if none could be found. * @return The attribute binding or {@code null} if none could be found.
*/ */
public AttributeBinding locateAttributeBinding(String name); AttributeBinding locateAttributeBinding(String name);
/** /**
* Locate a specific attribute binding, by its values. * Locate a specific attribute binding, by its values.
@ -86,14 +93,14 @@ public interface AttributeBindingContainer {
* *
* @return The attribute binding or {@code null} if none could be found. * @return The attribute binding or {@code null} if none could be found.
*/ */
public AttributeBinding locateAttributeBinding(List<Value> values); AttributeBinding locateAttributeBinding(List<Value> values);
/** /**
* Seeks out the entity binding that is the root of this component path. * Seeks out the entity binding that is the root of this component path.
* *
* @return The entity binding * @return The entity binding
*/ */
public EntityBinding seekEntityBinding(); EntityBinding seekEntityBinding();
/** /**
* Obtain the {@link Class} reference for this attribute container. Generally this is used to perform reflection * Obtain the {@link Class} reference for this attribute container. Generally this is used to perform reflection
@ -101,14 +108,14 @@ public interface AttributeBindingContainer {
* *
* @return The {@link Class} reference * @return The {@link Class} reference
*/ */
public Class<?> getClassReference(); Class<?> getClassReference();
/** /**
* Obtain the meta-attribute context for this container. * Obtain the meta-attribute context for this container.
* *
* @return The meta-attribute context. * @return The meta-attribute context.
*/ */
public MetaAttributeContext getMetaAttributeContext(); MetaAttributeContext getMetaAttributeContext();
/** /**
@ -117,7 +124,7 @@ public interface AttributeBindingContainer {
* *
* @return the table specification. * @return the table specification.
*/ */
public abstract TableSpecification getPrimaryTable(); TableSpecification getPrimaryTable();
/** /**
* Factory method for basic attribute bindings. * Factory method for basic attribute bindings.
@ -132,7 +139,7 @@ public interface AttributeBindingContainer {
* *
* @return The attribute binding instance. * @return The attribute binding instance.
*/ */
public BasicAttributeBinding makeBasicAttributeBinding( BasicAttributeBinding makeBasicAttributeBinding(
SingularAttribute attribute, SingularAttribute attribute,
List<RelationalValueBinding> relationalValueBindings, List<RelationalValueBinding> relationalValueBindings,
String propertyAccessorName, String propertyAccessorName,
@ -154,7 +161,7 @@ public interface AttributeBindingContainer {
* *
* @return The attribute binding instance. * @return The attribute binding instance.
*/ */
public CompositeAttributeBinding makeAggregatedCompositeAttributeBinding( CompositeAttributeBinding makeAggregatedCompositeAttributeBinding(
SingularAttribute attribute, SingularAttribute attribute,
SingularAttribute parentReferenceAttribute, SingularAttribute parentReferenceAttribute,
String propertyAccessorName, String propertyAccessorName,
@ -176,7 +183,7 @@ public interface AttributeBindingContainer {
* @param isConstrained * @param isConstrained
* @return The attribute binding instance. * @return The attribute binding instance.
*/ */
public OneToOneAttributeBinding makeOneToOneAttributeBinding( OneToOneAttributeBinding makeOneToOneAttributeBinding(
SingularAttribute attribute, SingularAttribute attribute,
String propertyAccessorName, String propertyAccessorName,
boolean includedInOptimisticLocking, boolean includedInOptimisticLocking,
@ -204,7 +211,7 @@ public interface AttributeBindingContainer {
* *
* @return The attribute binding instance. * @return The attribute binding instance.
*/ */
public ManyToOneAttributeBinding makeManyToOneAttributeBinding( ManyToOneAttributeBinding makeManyToOneAttributeBinding(
SingularAttribute attribute, SingularAttribute attribute,
String propertyAccessorName, String propertyAccessorName,
boolean includedInOptimisticLocking, boolean includedInOptimisticLocking,
@ -229,7 +236,7 @@ public interface AttributeBindingContainer {
* *
* @return The attribute binding instance. * @return The attribute binding instance.
*/ */
public BagBinding makeBagAttributeBinding( BagBinding makeBagAttributeBinding(
PluralAttribute attribute, PluralAttribute attribute,
PluralAttributeElementBinding.Nature nature, PluralAttributeElementBinding.Nature nature,
SingularAttributeBinding referencedAttributeBinding, SingularAttributeBinding referencedAttributeBinding,
@ -251,7 +258,7 @@ public interface AttributeBindingContainer {
* *
* @return The attribute binding instance. * @return The attribute binding instance.
*/ */
public ListBinding makeListAttributeBinding( ListBinding makeListAttributeBinding(
PluralAttribute attribute, PluralAttribute attribute,
PluralAttributeElementBinding.Nature nature, PluralAttributeElementBinding.Nature nature,
SingularAttributeBinding referencedAttributeBinding, SingularAttributeBinding referencedAttributeBinding,
@ -274,7 +281,7 @@ public interface AttributeBindingContainer {
* *
* @return The attribute binding instance. * @return The attribute binding instance.
*/ */
public ArrayBinding makeArrayAttributeBinding( ArrayBinding makeArrayAttributeBinding(
PluralAttribute attribute, PluralAttribute attribute,
PluralAttributeElementBinding.Nature nature, PluralAttributeElementBinding.Nature nature,
SingularAttributeBinding referencedAttributeBinding, SingularAttributeBinding referencedAttributeBinding,
@ -297,7 +304,7 @@ public interface AttributeBindingContainer {
* *
* @return The attribute binding instance. * @return The attribute binding instance.
*/ */
public MapBinding makeMapAttributeBinding( MapBinding makeMapAttributeBinding(
PluralAttribute attribute, PluralAttribute attribute,
PluralAttributeElementBinding.Nature elementNature, PluralAttributeElementBinding.Nature elementNature,
PluralAttributeIndexBinding.Nature indexNature, PluralAttributeIndexBinding.Nature indexNature,
@ -319,7 +326,7 @@ public interface AttributeBindingContainer {
* *
* @return The attribute binding instance. * @return The attribute binding instance.
*/ */
public SetBinding makeSetAttributeBinding( SetBinding makeSetAttributeBinding(
PluralAttribute attribute, PluralAttribute attribute,
PluralAttributeElementBinding.Nature nature, PluralAttributeElementBinding.Nature nature,
SingularAttributeBinding referencedAttributeBinding, SingularAttributeBinding referencedAttributeBinding,

View File

@ -38,6 +38,7 @@ import org.hibernate.metamodel.spi.domain.SingularAttribute;
import org.hibernate.metamodel.spi.relational.TableSpecification; import org.hibernate.metamodel.spi.relational.TableSpecification;
import org.hibernate.metamodel.spi.relational.Value; import org.hibernate.metamodel.spi.relational.Value;
import org.hibernate.metamodel.spi.source.MetaAttributeContext; import org.hibernate.metamodel.spi.source.MetaAttributeContext;
import org.hibernate.tuple.component.ComponentTuplizer;
/** /**
* A specialized binding contract for a singular attribute binding that * A specialized binding contract for a singular attribute binding that
@ -50,7 +51,7 @@ public class CompositeAttributeBinding
implements SingularNonAssociationAttributeBinding, CompositeAttributeBindingContainer, Cascadeable { implements SingularNonAssociationAttributeBinding, CompositeAttributeBindingContainer, Cascadeable {
private final AbstractCompositeAttributeBindingContainer compositeAttributeBindingContainer; private final AbstractCompositeAttributeBindingContainer compositeAttributeBindingContainer;
private Class<? extends ComponentTuplizer> customComponentTuplizerClass = null;
private CompositeAttributeBinding( private CompositeAttributeBinding(
AttributeBindingContainer container, AttributeBindingContainer container,
SingularAttribute attribute, SingularAttribute attribute,
@ -204,6 +205,15 @@ public class CompositeAttributeBinding
return compositeAttributeBindingContainer.getParentReference(); return compositeAttributeBindingContainer.getParentReference();
} }
@Override
public Class<? extends ComponentTuplizer> getCustomTuplizerClass() {
return customComponentTuplizerClass;
}
public void setCustomComponentTuplizerClass(Class<? extends ComponentTuplizer> customComponentTuplizerClass) {
this.customComponentTuplizerClass = customComponentTuplizerClass;
}
@Override @Override
public List<RelationalValueBinding> getRelationalValueBindings() { public List<RelationalValueBinding> getRelationalValueBindings() {
final List<RelationalValueBinding> bindings = new ArrayList<RelationalValueBinding>(); final List<RelationalValueBinding> bindings = new ArrayList<RelationalValueBinding>();
@ -359,6 +369,8 @@ public class CompositeAttributeBinding
return compositeAttributeBindingContainer.getPrimaryTable(); return compositeAttributeBindingContainer.getPrimaryTable();
} }
@Override @Override
public BasicAttributeBinding makeBasicAttributeBinding( public BasicAttributeBinding makeBasicAttributeBinding(
SingularAttribute attribute, SingularAttribute attribute,

View File

@ -24,6 +24,8 @@
package org.hibernate.metamodel.spi.binding; package org.hibernate.metamodel.spi.binding;
import org.hibernate.metamodel.spi.domain.SingularAttribute; import org.hibernate.metamodel.spi.domain.SingularAttribute;
import org.hibernate.tuple.Tuplizer;
import org.hibernate.tuple.component.ComponentTuplizer;
/** /**
* @author Gail Badner * @author Gail Badner
@ -32,4 +34,7 @@ public interface CompositeAttributeBindingContainer
extends AttributeBindingContainer { extends AttributeBindingContainer {
boolean isAggregated(); boolean isAggregated();
SingularAttribute getParentReference(); SingularAttribute getParentReference();
@Override
Class<? extends ComponentTuplizer> getCustomTuplizerClass();
} }

View File

@ -428,13 +428,13 @@ public class EntityBinding extends AbstractAttributeBindingContainer implements
public void setCustomEntityPersisterClass(Class<? extends EntityPersister> customEntityPersisterClass) { public void setCustomEntityPersisterClass(Class<? extends EntityPersister> customEntityPersisterClass) {
this.customEntityPersisterClass = customEntityPersisterClass; this.customEntityPersisterClass = customEntityPersisterClass;
} }
@Override
public Class<? extends EntityTuplizer> getCustomEntityTuplizerClass() { public Class<? extends EntityTuplizer> getCustomTuplizerClass() {
if ( customEntityTuplizerClass != null ) { if ( customEntityTuplizerClass != null ) {
return customEntityTuplizerClass; return customEntityTuplizerClass;
} }
else if ( superEntityBinding != null ) { else if ( superEntityBinding != null ) {
return superEntityBinding.getCustomEntityTuplizerClass(); return superEntityBinding.getCustomTuplizerClass();
} }
return null; return null;
} }

View File

@ -101,16 +101,15 @@ public class ComponentMetamodel implements Serializable {
// todo : move this to SF per HHH-3517; also see HHH-1907 and ComponentMetamodel // todo : move this to SF per HHH-3517; also see HHH-1907 and ComponentMetamodel
final ComponentTuplizerFactory componentTuplizerFactory = new ComponentTuplizerFactory(); final ComponentTuplizerFactory componentTuplizerFactory = new ComponentTuplizerFactory();
// TODO: provide support for custom tuplizer final Class<? extends ComponentTuplizer> tuplizerClass = component.getCustomTuplizerClass();
final String tuplizerClassName = null; if ( tuplizerClass == null ) {
if ( tuplizerClassName == null ) {
componentTuplizer = componentTuplizerFactory.constructDefaultTuplizer( componentTuplizer = componentTuplizerFactory.constructDefaultTuplizer(
entityMode, component, isIdentifierMapper entityMode, component, isIdentifierMapper
); );
} }
else { else {
componentTuplizer = componentTuplizerFactory.constructTuplizer( componentTuplizer = componentTuplizerFactory.constructTuplizer(
tuplizerClassName, component, isIdentifierMapper tuplizerClass, component, isIdentifierMapper
); );
} }
} }

View File

@ -143,11 +143,11 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer {
} }
instantiator = buildInstantiator( componentClass, !component.isAggregated(), optimizer ); instantiator = buildInstantiator( componentClass, !component.isAggregated(), optimizer );
} }
@Override
public Class getMappedClass() { public Class getMappedClass() {
return componentClass; return componentClass;
} }
@Override
public Object[] getPropertyValues(Object component) throws HibernateException { public Object[] getPropertyValues(Object component) throws HibernateException {
if ( component == BackrefPropertyAccessor.UNKNOWN ) { if ( component == BackrefPropertyAccessor.UNKNOWN ) {
return new Object[propertySpan]; return new Object[propertySpan];
@ -159,7 +159,7 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer {
return super.getPropertyValues( component ); return super.getPropertyValues( component );
} }
} }
@Override
public void setPropertyValues(Object component, Object[] values) throws HibernateException { public void setPropertyValues(Object component, Object[] values) throws HibernateException {
if ( optimizer != null && optimizer.getAccessOptimizer() != null ) { if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
optimizer.getAccessOptimizer().setPropertyValues( component, values ); optimizer.getAccessOptimizer().setPropertyValues( component, values );
@ -168,15 +168,15 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer {
super.setPropertyValues( component, values ); super.setPropertyValues( component, values );
} }
} }
@Override
public Object getParent(Object component) { public Object getParent(Object component) {
return parentGetter.get( component ); return parentGetter.get( component );
} }
@Override
public boolean hasParentProperty() { public boolean hasParentProperty() {
return parentGetter != null; return parentGetter != null;
} }
@Override
public boolean isMethodOf(Method method) { public boolean isMethodOf(Method method) {
for ( int i = 0; i < propertySpan; i++ ) { for ( int i = 0; i < propertySpan; i++ ) {
final Method getterMethod = getters[i].getMethod(); final Method getterMethod = getters[i].getMethod();
@ -186,15 +186,15 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer {
} }
return false; return false;
} }
@Override
public void setParent(Object component, Object parent, SessionFactoryImplementor factory) { public void setParent(Object component, Object parent, SessionFactoryImplementor factory) {
parentSetter.set( component, parent, factory ); parentSetter.set( component, parent, factory );
} }
@Override
protected Getter buildGetter(Component component, Property prop) { protected Getter buildGetter(Component component, Property prop) {
return prop.getGetter( component.getComponentClass() ); return prop.getGetter( component.getComponentClass() );
} }
@Override
protected Setter buildSetter(Component component, Property prop) { protected Setter buildSetter(Component component, Property prop) {
return prop.getSetter( component.getComponentClass() ); return prop.getSetter( component.getComponentClass() );
} }
@ -205,43 +205,36 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer {
} }
private static Instantiator buildInstantiator(Class<?> mappedClass, boolean isVirtual, ReflectionOptimizer optimizer) { private static Instantiator buildInstantiator(Class<?> mappedClass, boolean isVirtual, ReflectionOptimizer optimizer) {
if (isVirtual && ReflectHelper.isAbstractClass( mappedClass ) ) { if ( isVirtual && ReflectHelper.isAbstractClass( mappedClass ) ) {
return new ProxiedInstantiator( mappedClass ); return new ProxiedInstantiator( mappedClass );
} }
if ( optimizer == null ) { final ReflectionOptimizer.InstantiationOptimizer instantiationOptimizer =
return new PojoInstantiator( mappedClass, null ); optimizer == null ? null : optimizer.getInstantiationOptimizer();
} return new PojoInstantiator( mappedClass, instantiationOptimizer );
else {
return new PojoInstantiator( mappedClass, optimizer.getInstantiationOptimizer() );
}
} }
private static class ProxiedInstantiator implements Instantiator { private static class ProxiedInstantiator implements Instantiator {
private final Class proxiedClass; private final Class proxiedClass;
private final BasicProxyFactory factory; private final BasicProxyFactory factory;
public ProxiedInstantiator(Class<?> proxyClass) { public ProxiedInstantiator(final Class<?> proxyClass) {
this.proxiedClass = proxyClass; this.proxiedClass = proxyClass;
if ( proxiedClass.isInterface() ) { final boolean isInterface = proxiedClass.isInterface();
factory = Environment.getBytecodeProvider() final Class superClass = isInterface ? null : proxiedClass;
.getProxyFactoryFactory() final Class[] interfaces = isInterface ? new Class[] { proxiedClass } : null;
.buildBasicProxyFactory( null, new Class[] { proxiedClass } ); factory = Environment.getBytecodeProvider()
} .getProxyFactoryFactory()
else { .buildBasicProxyFactory( superClass, interfaces );
factory = Environment.getBytecodeProvider()
.getProxyFactoryFactory()
.buildBasicProxyFactory( proxiedClass, null );
}
} }
@Override
public Object instantiate(Serializable id) { public Object instantiate(Serializable id) {
throw new AssertionFailure( "ProxiedInstantiator can only be used to instantiate component" ); throw new AssertionFailure( "ProxiedInstantiator can only be used to instantiate component" );
} }
@Override
public Object instantiate() { public Object instantiate() {
return factory.getProxy(); return factory.getProxy();
} }
@Override
public boolean isInstance(Object object) { public boolean isInstance(Object object) {
return proxiedClass.isInstance( object ); return proxiedClass.isInstance( object );
} }

View File

@ -53,9 +53,7 @@ import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property; import org.hibernate.mapping.Property;
import org.hibernate.mapping.PropertyGeneration; import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.spi.binding.AttributeBinding; import org.hibernate.metamodel.spi.binding.AttributeBinding;
import org.hibernate.metamodel.spi.binding.CompositeAttributeBinding;
import org.hibernate.metamodel.spi.binding.EntityBinding; import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.metamodel.spi.binding.EntityIdentifier;
import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.binding.SingularAttributeBinding;
import org.hibernate.metamodel.spi.domain.Aggregate; import org.hibernate.metamodel.spi.domain.Aggregate;
import org.hibernate.metamodel.spi.domain.Attribute; import org.hibernate.metamodel.spi.domain.Attribute;
@ -584,7 +582,7 @@ public class EntityMetamodel implements Serializable {
entityMode = hasPojoRepresentation ? EntityMode.POJO : EntityMode.MAP; entityMode = hasPojoRepresentation ? EntityMode.POJO : EntityMode.MAP;
final EntityTuplizerFactory entityTuplizerFactory = sessionFactory.getSettings().getEntityTuplizerFactory(); final EntityTuplizerFactory entityTuplizerFactory = sessionFactory.getSettings().getEntityTuplizerFactory();
Class<? extends EntityTuplizer> tuplizerClass = entityBinding.getCustomEntityTuplizerClass(); Class<? extends EntityTuplizer> tuplizerClass = entityBinding.getCustomTuplizerClass();
if ( tuplizerClass == null ) { if ( tuplizerClass == null ) {
entityTuplizer = entityTuplizerFactory.constructDefaultTuplizer( entityMode, this, entityBinding ); entityTuplizer = entityTuplizerFactory.constructDefaultTuplizer( entityMode, this, entityBinding );

View File

@ -72,7 +72,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
private final Class mappedClass; private final Class mappedClass;
private final Class proxyInterface; private final Class proxyInterface;
private final boolean lifecycleImplementor; private final boolean lifecycleImplementor;
private final Set lazyPropertyNames = new HashSet(); private final Set<String> lazyPropertyNames = new HashSet<String>();
private final ReflectionOptimizer optimizer; private final ReflectionOptimizer optimizer;
private final boolean isInstrumented; private final boolean isInstrumented;
@ -117,6 +117,8 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
super( entityMetamodel, mappedEntity ); super( entityMetamodel, mappedEntity );
this.mappedClass = mappedEntity.getEntity().getClassReference(); this.mappedClass = mappedEntity.getEntity().getClassReference();
this.proxyInterface = mappedEntity.getProxyInterfaceType().getValue(); this.proxyInterface = mappedEntity.getProxyInterfaceType().getValue();
//with Jandex, if this entity is mapped by annotation, then we already get this info from jandex.
//but i don't know if this mirror improvement worth it.
this.lifecycleImplementor = Lifecycle.class.isAssignableFrom( mappedClass ); this.lifecycleImplementor = Lifecycle.class.isAssignableFrom( mappedClass );
this.isInstrumented = entityMetamodel.isInstrumented(); this.isInstrumented = entityMetamodel.isInstrumented();

View File

@ -90,7 +90,7 @@ public class ByteArrayBlobType extends AbstractLobType {
int length = array.length; int length = array.length;
Byte[] copy = new Byte[length]; Byte[] copy = new Byte[length];
for ( int index = 0; index < length ; index++ ) { for ( int index = 0; index < length ; index++ ) {
copy[index] = Byte.valueOf( array[index].byteValue() ); copy[index] = array[index];
} }
return copy; return copy;
} }
@ -174,7 +174,7 @@ public class ByteArrayBlobType extends AbstractLobType {
int length = bytes.length; int length = bytes.length;
byte[] result = new byte[length]; byte[] result = new byte[length];
for ( int i = 0; i < length ; i++ ) { for ( int i = 0; i < length ; i++ ) {
result[i] = bytes[i].byteValue(); result[i] = bytes[i];
} }
return result; return result;
} }
@ -183,7 +183,7 @@ public class ByteArrayBlobType extends AbstractLobType {
int length = bytes.length; int length = bytes.length;
Byte[] result = new Byte[length]; Byte[] result = new Byte[length];
for ( int index = 0; index < length ; index++ ) { for ( int index = 0; index < length ; index++ ) {
result[index] = Byte.valueOf( bytes[index] ); result[index] = bytes[index];
} }
return result; return result;
} }

View File

@ -32,9 +32,6 @@ import java.sql.SQLException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.dom4j.Element;
import org.dom4j.Node;
import org.hibernate.EntityMode; import org.hibernate.EntityMode;
import org.hibernate.FetchMode; import org.hibernate.FetchMode;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
@ -158,7 +155,7 @@ public class ComponentType extends AbstractType implements CompositeType, Proced
public final boolean isComponentType() { public final boolean isComponentType() {
return true; return true;
} }
@Override
public Class getReturnedClass() { public Class getReturnedClass() {
return componentTuplizer.getMappedClass(); return componentTuplizer.getMappedClass();
} }
@ -327,7 +324,7 @@ public class ComponentType extends AbstractType implements CompositeType, Proced
return old != null; return old != null;
} }
if ( old == null ) { if ( old == null ) {
return current != null; return true;
} }
Object[] currentValues = getPropertyValues( current, session ); Object[] currentValues = getPropertyValues( current, session );
Object[] oldValues = ( Object[] ) old; Object[] oldValues = ( Object[] ) old;

View File

@ -33,6 +33,7 @@ import org.dom4j.Node;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.EntityMode; import org.hibernate.EntityMode;
import org.hibernate.Filter;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.engine.internal.ForeignKeys; import org.hibernate.engine.internal.ForeignKeys;
@ -416,7 +417,7 @@ public abstract class EntityType extends AbstractType implements AssociationType
return isEmbeddedInXML; return isEmbeddedInXML;
} }
public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters) public String getOnCondition(String alias, SessionFactoryImplementor factory, Map<String, Filter> enabledFilters)
throws MappingException { throws MappingException {
if ( isReferenceToPrimaryKey() ) { //TODO: this is a bit arbitrary, expose a switch to the user? if ( isReferenceToPrimaryKey() ) { //TODO: this is a bit arbitrary, expose a switch to the user?
return ""; return "";
@ -430,10 +431,6 @@ public abstract class EntityType extends AbstractType implements AssociationType
* Resolve an identifier or unique key value * Resolve an identifier or unique key value
*/ */
public Object resolve(Object value, SessionImplementor session, Object owner) throws HibernateException { public Object resolve(Object value, SessionImplementor session, Object owner) throws HibernateException {
if ( isNotEmbedded( session ) ) {
return value;
}
if ( value == null ) { if ( value == null ) {
return null; return null;
} }
@ -456,10 +453,6 @@ public abstract class EntityType extends AbstractType implements AssociationType
} }
protected final Object getIdentifier(Object value, SessionImplementor session) throws HibernateException { protected final Object getIdentifier(Object value, SessionImplementor session) throws HibernateException {
if ( isNotEmbedded(session) ) {
return value;
}
if ( isReferenceToPrimaryKey() ) { if ( isReferenceToPrimaryKey() ) {
return ForeignKeys.getEntityIdentifierIfNotUnsaved( getAssociatedEntityName(), value, session ); //tolerates nulls return ForeignKeys.getEntityIdentifierIfNotUnsaved( getAssociatedEntityName(), value, session ); //tolerates nulls
} }

View File

@ -73,7 +73,7 @@ public abstract class BaseAnnotationIndexTestCase extends BaseUnitTestCase {
); );
AnnotationBindingContext context = new AnnotationBindingContextImpl( meta, index ); AnnotationBindingContext context = new AnnotationBindingContextImpl( meta, index );
return EmbeddableHierarchy.createEmbeddableHierarchy( configuredClasses[0], "", accessType, return EmbeddableHierarchy.createEmbeddableHierarchy( configuredClasses[0], "", accessType,
naturalIdMutability, context ); naturalIdMutability,null, context );
} }
} }

View File

@ -1,6 +1,7 @@
//$Id$ //$Id$
package org.hibernate.test.annotations.tuplizer; package org.hibernate.test.annotations.tuplizer;
import org.hibernate.mapping.Component; import org.hibernate.mapping.Component;
import org.hibernate.metamodel.spi.binding.CompositeAttributeBindingContainer;
import org.hibernate.tuple.Instantiator; import org.hibernate.tuple.Instantiator;
import org.hibernate.tuple.component.PojoComponentTuplizer; import org.hibernate.tuple.component.PojoComponentTuplizer;
@ -8,12 +9,23 @@ import org.hibernate.tuple.component.PojoComponentTuplizer;
* @author Emmanuel Bernard * @author Emmanuel Bernard
*/ */
public class DynamicComponentTuplizer extends PojoComponentTuplizer { public class DynamicComponentTuplizer extends PojoComponentTuplizer {
private final Instantiator instantiator;
public DynamicComponentTuplizer(Component component) { public DynamicComponentTuplizer(Component component) {
super( component ); super( component );
this.instantiator = new DynamicInstantiator(component.getComponentClassName() );
}
public DynamicComponentTuplizer(CompositeAttributeBindingContainer component, boolean isIdentifierMapper) {
super( component, isIdentifierMapper );
this.instantiator = new DynamicInstantiator(component.getClassReference().getName() );
} }
protected Instantiator buildInstantiator(Component component) { protected Instantiator buildInstantiator(Component component) {
return new DynamicInstantiator( component.getComponentClassName() ); //To change body of overridden methods use File | Settings | File Templates. return new DynamicInstantiator( component.getComponentClassName() );
}
@Override
protected Instantiator getInstantiator() {
return instantiator;
} }
} }

View File

@ -1,6 +1,8 @@
//$Id$ //$Id$
package org.hibernate.test.annotations.tuplizer; package org.hibernate.test.annotations.tuplizer;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.property.Getter; import org.hibernate.property.Getter;
import org.hibernate.property.Setter; import org.hibernate.property.Setter;
import org.hibernate.proxy.ProxyFactory; import org.hibernate.proxy.ProxyFactory;
@ -13,19 +15,33 @@ import org.hibernate.tuple.entity.PojoEntityTuplizer;
*/ */
public class DynamicEntityTuplizer extends PojoEntityTuplizer { public class DynamicEntityTuplizer extends PojoEntityTuplizer {
public DynamicEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) { public DynamicEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
super( entityMetamodel, mappedEntity ); super( entityMetamodel, mappedEntity );
}
protected Instantiator buildInstantiator(PersistentClass persistentClass) {
return new DynamicInstantiator( persistentClass.getEntityName() );
}
protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
// allows defining a custom proxy factory, which is responsible for
// generating lazy proxies for a given entity.
//
// Here we simply use the default...
return super.buildProxyFactory( persistentClass, idGetter, idSetter );
}
} }
public DynamicEntityTuplizer(EntityMetamodel entityMetamodel, EntityBinding mappedEntity) {
super( entityMetamodel, mappedEntity );
}
protected Instantiator buildInstantiator(PersistentClass persistentClass) {
return new DynamicInstantiator( persistentClass.getEntityName() );
}
@Override
protected Instantiator buildInstantiator(EntityBinding entityBinding) {
return new DynamicInstantiator( entityBinding.getEntityName() );
}
@Override
protected ProxyFactory buildProxyFactoryInternal(EntityBinding entityBinding, Getter idGetter, Setter idSetter) {
return super.buildProxyFactoryInternal( entityBinding, idGetter, idSetter );
}
protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
// allows defining a custom proxy factory, which is responsible for
// generating lazy proxies for a given entity.
//
// Here we simply use the default...
return super.buildProxyFactory( persistentClass, idGetter, idSetter );
}
}

View File

@ -26,7 +26,6 @@ package org.hibernate.test.annotations.tuplizer;
import org.junit.Test; import org.junit.Test;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -35,7 +34,6 @@ import static org.junit.Assert.assertNotNull;
/** /**
* @author Emmanuel Bernard * @author Emmanuel Bernard
*/ */
@FailureExpectedWithNewMetamodel
public class TuplizerTest extends BaseCoreFunctionalTestCase { public class TuplizerTest extends BaseCoreFunctionalTestCase {
@Test @Test
public void testEntityTuplizer() throws Exception { public void testEntityTuplizer() throws Exception {
@ -46,7 +44,7 @@ public class TuplizerTest extends BaseCoreFunctionalTestCase {
cuisine.setCountry( country ); cuisine.setCountry( country );
Session s = openSession( new EntityNameInterceptor() ); Session s = openSession( new EntityNameInterceptor() );
s.getTransaction().begin(); s.getTransaction().begin();
s.persist( cuisine ); s.persist( cuisine );
s.flush(); s.flush();
s.clear(); s.clear();
cuisine = (Cuisine) s.get(Cuisine.class, cuisine.getId() ); cuisine = (Cuisine) s.get(Cuisine.class, cuisine.getId() );
@ -59,6 +57,6 @@ public class TuplizerTest extends BaseCoreFunctionalTestCase {
@Override @Override
protected Class[] getAnnotatedClasses() { protected Class[] getAnnotatedClasses() {
return new Class[] { Cuisine.class }; return new Class[] { Cuisine.class, Country.class };
} }
} }