HHH-7950 bind custom tuplizer on composite attribute
This commit is contained in:
parent
2922922133
commit
34c3cec657
|
@ -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(),
|
||||||
|
|
|
@ -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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue