HHH-7736 partial joined subclass support
This commit is contained in:
parent
4359b9971b
commit
e998269402
|
@ -26,9 +26,34 @@ package org.hibernate.cache.spi.entry;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* {@link CacheEntry} structure, used for construct / deconstruct the cache entry to different format that store in the 2LC.
|
||||||
|
*
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public interface CacheEntryStructure {
|
public interface CacheEntryStructure<S,T> {
|
||||||
public Object structure(Object item);
|
/**
|
||||||
public Object destructure(Object map, SessionFactoryImplementor factory);
|
* Convert the giving {@param source} to the target format of {@link T}.
|
||||||
|
* <br>
|
||||||
|
* The generic type of {@link S} should be either of :
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link CacheEntry}</li>
|
||||||
|
* <li>{@link CollectionCacheEntry}</li>
|
||||||
|
* </ul>
|
||||||
|
* </br>
|
||||||
|
*
|
||||||
|
* This is called just before cache entry being stored into 2LC.
|
||||||
|
*
|
||||||
|
* @param source The raw cache entry.
|
||||||
|
* @return The target type of value that being persisted into 2LC.
|
||||||
|
*/
|
||||||
|
public T structure(S source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deconstruct the {@param target} that load from 2LC to its source type of {@link S}.
|
||||||
|
*
|
||||||
|
* @param target The item that load from the 2LC.
|
||||||
|
* @param factory The SessionFactoryImplementor.
|
||||||
|
* @return The source type of cache entry.
|
||||||
|
*/
|
||||||
|
public S destructure(T target, SessionFactoryImplementor factory);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,36 +33,36 @@ import org.hibernate.persister.entity.EntityPersister;
|
||||||
/**
|
/**
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public class StructuredCacheEntry implements CacheEntryStructure {
|
public class StructuredCacheEntry implements CacheEntryStructure<CacheEntry, Map> {
|
||||||
|
|
||||||
private EntityPersister persister;
|
private final EntityPersister persister;
|
||||||
|
|
||||||
public StructuredCacheEntry(EntityPersister persister) {
|
public StructuredCacheEntry(EntityPersister persister) {
|
||||||
this.persister = persister;
|
this.persister = persister;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object destructure(Object item, SessionFactoryImplementor factory) {
|
@Override
|
||||||
Map map = (Map) item;
|
public CacheEntry destructure(Map map, SessionFactoryImplementor factory) {
|
||||||
boolean lazyPropertiesUnfetched = ( (Boolean) map.get("_lazyPropertiesUnfetched") ).booleanValue();
|
boolean lazyPropertiesUnfetched = ( (Boolean) map.get( "_lazyPropertiesUnfetched" ) ).booleanValue();
|
||||||
String subclass = (String) map.get("_subclass");
|
String subclass = (String) map.get( "_subclass" );
|
||||||
Object version = map.get("_version");
|
Object version = map.get( "_version" );
|
||||||
EntityPersister subclassPersister = factory.getEntityPersister(subclass);
|
EntityPersister subclassPersister = factory.getEntityPersister( subclass );
|
||||||
String[] names = subclassPersister.getPropertyNames();
|
String[] names = subclassPersister.getPropertyNames();
|
||||||
Serializable[] state = new Serializable[names.length];
|
Serializable[] state = new Serializable[names.length];
|
||||||
for ( int i=0; i<names.length; i++ ) {
|
for ( int i = 0; i < names.length; i++ ) {
|
||||||
state[i] = (Serializable) map.get( names[i] );
|
state[i] = (Serializable) map.get( names[i] );
|
||||||
}
|
}
|
||||||
return new CacheEntry(state, subclass, lazyPropertiesUnfetched, version);
|
return new CacheEntry( state, subclass, lazyPropertiesUnfetched, version );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object structure(Object item) {
|
@Override
|
||||||
CacheEntry entry = (CacheEntry) item;
|
public Map structure(CacheEntry entry) {
|
||||||
String[] names = persister.getPropertyNames();
|
String[] names = persister.getPropertyNames();
|
||||||
Map map = new HashMap(names.length+2);
|
Map map = new HashMap( names.length + 3 );
|
||||||
map.put( "_subclass", entry.getSubclass() );
|
map.put( "_subclass", entry.getSubclass() );
|
||||||
map.put( "_version", entry.getVersion() );
|
map.put( "_version", entry.getVersion() );
|
||||||
map.put( "_lazyPropertiesUnfetched", entry.areLazyPropertiesUnfetched() );
|
map.put( "_lazyPropertiesUnfetched", entry.areLazyPropertiesUnfetched() );
|
||||||
for ( int i=0; i<names.length; i++ ) {
|
for ( int i = 0; i < names.length; i++ ) {
|
||||||
map.put( names[i], entry.getDisassembledState()[i] );
|
map.put( names[i], entry.getDisassembledState()[i] );
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
|
|
|
@ -30,17 +30,19 @@ import java.util.List;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* For other plural attributes except map, this impl is used.
|
||||||
|
* </br>
|
||||||
|
* Internally, a list that contains all collection states is stored into 2LC.
|
||||||
|
*
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public class StructuredCollectionCacheEntry implements CacheEntryStructure {
|
public class StructuredCollectionCacheEntry implements CacheEntryStructure<CollectionCacheEntry, List<Serializable>> {
|
||||||
|
@Override
|
||||||
public Object structure(Object item) {
|
public List<Serializable> structure(CollectionCacheEntry entry) {
|
||||||
CollectionCacheEntry entry = (CollectionCacheEntry) item;
|
|
||||||
return Arrays.asList( entry.getState() );
|
return Arrays.asList( entry.getState() );
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public Object destructure(Object item, SessionFactoryImplementor factory) {
|
public CollectionCacheEntry destructure(List<Serializable> list, SessionFactoryImplementor factory) {
|
||||||
List list = (List) item;
|
|
||||||
return new CollectionCacheEntry( list.toArray( new Serializable[list.size()] ) );
|
return new CollectionCacheEntry( list.toArray( new Serializable[list.size()] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,31 +31,30 @@ import java.util.Map;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* (De)structure the map type collection attribute that is being cached into 2LC.
|
||||||
|
*
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public class StructuredMapCacheEntry implements CacheEntryStructure {
|
public class StructuredMapCacheEntry implements CacheEntryStructure<CollectionCacheEntry, Map<Serializable,Serializable>> {
|
||||||
|
@Override
|
||||||
public Object structure(Object item) {
|
public Map<Serializable, Serializable> structure(CollectionCacheEntry entry) {
|
||||||
CollectionCacheEntry entry = (CollectionCacheEntry) item;
|
final Serializable[] states = entry.getState();
|
||||||
Serializable[] state = entry.getState();
|
final Map<Serializable, Serializable> map = new HashMap<Serializable, Serializable>( states.length );
|
||||||
Map map = new HashMap(state.length);
|
for ( final Serializable state : states ) {
|
||||||
for ( int i=0; i<state.length; ) {
|
map.put( state, state );
|
||||||
map.put( state[i++], state[i++] );
|
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object destructure(Object item, SessionFactoryImplementor factory) {
|
@Override
|
||||||
Map map = (Map) item;
|
public CollectionCacheEntry destructure(Map<Serializable, Serializable> map, SessionFactoryImplementor factory) {
|
||||||
Serializable[] state = new Serializable[ map.size()*2 ];
|
Serializable[] states = new Serializable[map.size() * 2];
|
||||||
int i=0;
|
int i = 0;
|
||||||
Iterator iter = map.entrySet().iterator();
|
for ( final Serializable key : map.keySet() ) {
|
||||||
while ( iter.hasNext() ) {
|
states[i++] = key;
|
||||||
Map.Entry me = (Map.Entry) iter.next();
|
states[i++] = map.get( key );
|
||||||
state[i++] = (Serializable) me.getKey();
|
|
||||||
state[i++] = (Serializable) me.getValue();
|
|
||||||
}
|
}
|
||||||
return new CollectionCacheEntry(state);
|
return new CollectionCacheEntry( states );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,14 +26,23 @@ package org.hibernate.cache.spi.entry;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* The very simple implementation of {@code CacheEntryStructure} that doing nothing but just return what it get.
|
||||||
|
*
|
||||||
|
* </br>
|
||||||
|
*
|
||||||
|
* This is used when {@link org.hibernate.cfg.AvailableSettings#USE_STRUCTURED_CACHE} is set to {@code false}.
|
||||||
|
*
|
||||||
|
* NOTE: This property is set to {@code false} by default.
|
||||||
|
*
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public class UnstructuredCacheEntry implements CacheEntryStructure {
|
public class UnstructuredCacheEntry implements CacheEntryStructure<Object, Object> {
|
||||||
|
@Override
|
||||||
public Object structure(Object item) {
|
public Object structure(Object item) {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Object destructure(Object map, SessionFactoryImplementor factory) {
|
public Object destructure(Object map, SessionFactoryImplementor factory) {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,33 +36,33 @@ import java.util.List;
|
||||||
* invoke the Iterators in sequence until all Iterators are exhausted.
|
* invoke the Iterators in sequence until all Iterators are exhausted.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class JoinedIterator implements Iterator {
|
public class JoinedIterator<T> implements Iterator<T> {
|
||||||
|
|
||||||
private static final Iterator[] ITERATORS = {};
|
private static final Iterator[] ITERATORS = {};
|
||||||
|
|
||||||
// wrapped iterators
|
// wrapped iterators
|
||||||
private Iterator[] iterators;
|
private Iterator<T>[] iterators;
|
||||||
|
|
||||||
// index of current iterator in the wrapped iterators array
|
// index of current iterator in the wrapped iterators array
|
||||||
private int currentIteratorIndex;
|
private int currentIteratorIndex;
|
||||||
|
|
||||||
// the current iterator
|
// the current iterator
|
||||||
private Iterator currentIterator;
|
private Iterator<T> currentIterator;
|
||||||
|
|
||||||
// the last used iterator
|
// the last used iterator
|
||||||
private Iterator lastUsedIterator;
|
private Iterator<T> lastUsedIterator;
|
||||||
|
|
||||||
public JoinedIterator(List iterators) {
|
public JoinedIterator(List<Iterator<T>> iterators) {
|
||||||
this( (Iterator[]) iterators.toArray(ITERATORS) );
|
this( iterators.toArray(ITERATORS) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public JoinedIterator(Iterator[] iterators) {
|
public JoinedIterator(Iterator<T>[] iterators) {
|
||||||
if( iterators==null )
|
if( iterators==null )
|
||||||
throw new NullPointerException("Unexpected NULL iterators argument");
|
throw new NullPointerException("Unexpected NULL iterators argument");
|
||||||
this.iterators = iterators;
|
this.iterators = iterators;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JoinedIterator(Iterator first, Iterator second) {
|
public JoinedIterator(Iterator<T> first, Iterator<T> second) {
|
||||||
this( new Iterator[] { first, second } );
|
this( new Iterator[] { first, second } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ public class JoinedIterator implements Iterator {
|
||||||
return currentIterator.hasNext();
|
return currentIterator.hasNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object next() {
|
public T next() {
|
||||||
updateCurrentIterator();
|
updateCurrentIterator();
|
||||||
return currentIterator.next();
|
return currentIterator.next();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,17 +29,17 @@ import java.util.Iterator;
|
||||||
/**
|
/**
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public final class SingletonIterator implements Iterator {
|
public final class SingletonIterator<T> implements Iterator<T> {
|
||||||
|
|
||||||
private Object value;
|
private T value;
|
||||||
private boolean hasNext = true;
|
private boolean hasNext = true;
|
||||||
|
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
return hasNext;
|
return hasNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object next() {
|
public T next() {
|
||||||
if (hasNext) {
|
if ( hasNext ) {
|
||||||
hasNext = false;
|
hasNext = false;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ public final class SingletonIterator implements Iterator {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SingletonIterator(Object value) {
|
public SingletonIterator(T value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.util.ReflectHelper;
|
import org.hibernate.internal.util.ReflectHelper;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.internal.util.ValueHolder;
|
import org.hibernate.internal.util.ValueHolder;
|
||||||
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.metamodel.internal.HibernateTypeHelper.ReflectedCollectionJavaTypes;
|
import org.hibernate.metamodel.internal.HibernateTypeHelper.ReflectedCollectionJavaTypes;
|
||||||
import org.hibernate.metamodel.spi.MetadataImplementor;
|
import org.hibernate.metamodel.spi.MetadataImplementor;
|
||||||
import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding;
|
import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding;
|
||||||
|
@ -133,6 +134,7 @@ import org.hibernate.metamodel.spi.source.PluralAttributeElementSource;
|
||||||
import org.hibernate.metamodel.spi.source.PluralAttributeIndexSource;
|
import org.hibernate.metamodel.spi.source.PluralAttributeIndexSource;
|
||||||
import org.hibernate.metamodel.spi.source.PluralAttributeKeySource;
|
import org.hibernate.metamodel.spi.source.PluralAttributeKeySource;
|
||||||
import org.hibernate.metamodel.spi.source.PluralAttributeSource;
|
import org.hibernate.metamodel.spi.source.PluralAttributeSource;
|
||||||
|
import org.hibernate.metamodel.spi.source.PrimaryKeyJoinColumnSource;
|
||||||
import org.hibernate.metamodel.spi.source.RelationalValueSource;
|
import org.hibernate.metamodel.spi.source.RelationalValueSource;
|
||||||
import org.hibernate.metamodel.spi.source.RelationalValueSourceContainer;
|
import org.hibernate.metamodel.spi.source.RelationalValueSourceContainer;
|
||||||
import org.hibernate.metamodel.spi.source.RootEntitySource;
|
import org.hibernate.metamodel.spi.source.RootEntitySource;
|
||||||
|
@ -158,7 +160,7 @@ import org.jboss.logging.Logger;
|
||||||
/**
|
/**
|
||||||
* The common binder shared between annotations and {@code hbm.xml} processing.
|
* The common binder shared between annotations and {@code hbm.xml} processing.
|
||||||
* <p/>
|
* <p/>
|
||||||
* The API consists of {@link #Binder(org.hibernate.metamodel.spi.MetadataImplementor, IdentifierGeneratorFactory)} and {@link #bindEntities(Iterable)}
|
* The API consists of {@link #Binder(org.hibernate.metamodel.spi.MetadataImplementor, IdentifierGeneratorFactory)} and {@link #bindEntityHierarchies}
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
* @author Hardy Ferentschik
|
* @author Hardy Ferentschik
|
||||||
|
@ -270,7 +272,7 @@ public class Binder {
|
||||||
|
|
||||||
private AttributeBinding attributeBinding( final String entityName, final String attributeName ) {
|
private AttributeBinding attributeBinding( final String entityName, final String attributeName ) {
|
||||||
// Check if binding has already been created
|
// Check if binding has already been created
|
||||||
final EntityBinding entityBinding = entityBinding( entityName );
|
final EntityBinding entityBinding = findOrBindingEntityBinding( entityName );
|
||||||
final AttributeSource attributeSource = attributeSourcesByName.get( attributeSourcesByNameKey( entityName, attributeName ) );
|
final AttributeSource attributeSource = attributeSourcesByName.get( attributeSourcesByNameKey( entityName, attributeName ) );
|
||||||
bindAttribute( entityBinding, attributeSource );
|
bindAttribute( entityBinding, attributeSource );
|
||||||
return entityBinding.locateAttributeBinding( attributeName );
|
return entityBinding.locateAttributeBinding( attributeName );
|
||||||
|
@ -772,21 +774,100 @@ public class Binder {
|
||||||
typeHelper.bindJdbcDataType( resolvedType, value );
|
typeHelper.bindJdbcDataType( resolvedType, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
private EntityBinding bindEntities( final EntityHierarchy entityHierarchy ) {
|
private EntityBinding bindSubEntity(final EntitySource entitySource, final EntityBinding superEntityBinding) {
|
||||||
|
// Return existing binding if available
|
||||||
|
EntityBinding entityBinding = metadata.getEntityBinding( entitySource.getEntityName() );
|
||||||
|
if ( entityBinding != null ) {
|
||||||
|
return entityBinding;
|
||||||
|
}
|
||||||
|
final LocalBindingContext bindingContext = entitySource.getLocalBindingContext();
|
||||||
|
bindingContexts.push( bindingContext );
|
||||||
|
try {
|
||||||
|
// Create new entity binding
|
||||||
|
entityBinding = createEntityBinding( entitySource, superEntityBinding );
|
||||||
|
entityBinding.setMutable( entityBinding.getHierarchyDetails().getRootEntityBinding().isMutable() );
|
||||||
|
bindPrimaryTable( entityBinding, entitySource );
|
||||||
|
bindSubEntityPrimaryKey( entityBinding, entitySource );
|
||||||
|
bindSecondaryTables( entityBinding, entitySource );
|
||||||
|
bindUniqueConstraints( entityBinding, entitySource );
|
||||||
|
bindAttributes( entityBinding, entitySource );
|
||||||
|
bindSubEntities( entityBinding, entitySource );
|
||||||
|
return entityBinding;
|
||||||
|
} finally {
|
||||||
|
bindingContexts.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bindSubEntityPrimaryKey(final EntityBinding entityBinding, final EntitySource entitySource) {
|
||||||
|
final InheritanceType inheritanceType = entityBinding.getHierarchyDetails().getInheritanceType();
|
||||||
|
final EntityBinding superEntityBinding = entityBinding.getSuperEntityBinding();
|
||||||
|
if ( superEntityBinding == null ) {
|
||||||
|
throw new AssertionFailure( "super entitybinding is null " );
|
||||||
|
}
|
||||||
|
if ( inheritanceType == InheritanceType.JOINED ) {
|
||||||
|
SubclassEntitySource subclassEntitySource = (SubclassEntitySource) entitySource;
|
||||||
|
ForeignKey fk = entityBinding.getPrimaryTable().createForeignKey(
|
||||||
|
superEntityBinding.getPrimaryTable(),
|
||||||
|
subclassEntitySource.getJoinedForeignKeyName()
|
||||||
|
);
|
||||||
|
final List<PrimaryKeyJoinColumnSource> primaryKeyJoinColumnSources = subclassEntitySource.getPrimaryKeyJoinColumnSources();
|
||||||
|
final boolean hasPrimaryKeyJoinColumns = CollectionHelper.isNotEmpty( primaryKeyJoinColumnSources );
|
||||||
|
final List<Column> superEntityBindingPrimaryKeyColumns = superEntityBinding.getPrimaryTable().getPrimaryKey().getColumns();
|
||||||
|
|
||||||
|
for ( int i = 0; i < superEntityBindingPrimaryKeyColumns.size(); i++ ) {
|
||||||
|
Column superEntityBindingPrimaryKeyColumn = superEntityBindingPrimaryKeyColumns.get( i );
|
||||||
|
PrimaryKeyJoinColumnSource primaryKeyJoinColumnSource = hasPrimaryKeyJoinColumns && i < primaryKeyJoinColumnSources
|
||||||
|
.size() ? primaryKeyJoinColumnSources.get( i ) : null;
|
||||||
|
final String columnName;
|
||||||
|
if ( primaryKeyJoinColumnSource != null && StringHelper.isNotEmpty( primaryKeyJoinColumnSource.getColumnName() ) ) {
|
||||||
|
columnName = bindingContext().getNamingStrategy().columnName( primaryKeyJoinColumnSource.getColumnName() );
|
||||||
|
} else {
|
||||||
|
columnName = superEntityBindingPrimaryKeyColumn.getColumnName().getText();
|
||||||
|
}
|
||||||
|
Column column = entityBinding.getPrimaryTable().locateOrCreateColumn( columnName );
|
||||||
|
column.setCheckCondition( superEntityBindingPrimaryKeyColumn.getCheckCondition() );
|
||||||
|
column.setComment( superEntityBindingPrimaryKeyColumn.getComment() );
|
||||||
|
column.setDefaultValue( superEntityBindingPrimaryKeyColumn.getDefaultValue() );
|
||||||
|
column.setIdentity( superEntityBindingPrimaryKeyColumn.isIdentity() );
|
||||||
|
column.setNullable( superEntityBindingPrimaryKeyColumn.isNullable() );
|
||||||
|
column.setReadFragment( superEntityBindingPrimaryKeyColumn.getReadFragment() );
|
||||||
|
column.setWriteFragment( superEntityBindingPrimaryKeyColumn.getWriteFragment() );
|
||||||
|
column.setUnique( superEntityBindingPrimaryKeyColumn.isUnique() );
|
||||||
|
final String sqlType;
|
||||||
|
if(primaryKeyJoinColumnSource!=null && StringHelper.isNotEmpty( primaryKeyJoinColumnSource.getColumnDefinition() )){
|
||||||
|
sqlType = primaryKeyJoinColumnSource.getColumnDefinition();
|
||||||
|
} else {
|
||||||
|
sqlType = superEntityBindingPrimaryKeyColumn.getSqlType();
|
||||||
|
}
|
||||||
|
column.setSqlType( sqlType );
|
||||||
|
column.setSize( superEntityBindingPrimaryKeyColumn.getSize() );
|
||||||
|
column.setJdbcDataType( superEntityBindingPrimaryKeyColumn.getJdbcDataType() );
|
||||||
|
entityBinding.getPrimaryTable().getPrimaryKey().addColumn( column );
|
||||||
|
//todo still need to figure out how to handle the referencedColumnName property
|
||||||
|
fk.addColumnMapping( column, superEntityBindingPrimaryKeyColumn );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binding a single entity hierarchy.
|
||||||
|
*
|
||||||
|
* @param entityHierarchy The entity hierarchy to be binded.
|
||||||
|
*
|
||||||
|
* @return The root {@link EntityBinding} of the entity hierarchy mapping.
|
||||||
|
*/
|
||||||
|
private EntityBinding bindEntityHierarchy(final EntityHierarchy entityHierarchy) {
|
||||||
final RootEntitySource rootEntitySource = entityHierarchy.getRootEntitySource();
|
final RootEntitySource rootEntitySource = entityHierarchy.getRootEntitySource();
|
||||||
// Return existing binding if available
|
// Return existing binding if available
|
||||||
EntityBinding rootEntityBinding = metadata.getEntityBinding( rootEntitySource.getEntityName() );
|
EntityBinding rootEntityBinding = metadata.getEntityBinding( rootEntitySource.getEntityName() );
|
||||||
if ( rootEntityBinding != null ) {
|
if ( rootEntityBinding != null ) {
|
||||||
return rootEntityBinding;
|
return rootEntityBinding;
|
||||||
}
|
}
|
||||||
// Save inheritance type and entity mode that will apply to entire hierarchy
|
setupBindingContext( entityHierarchy, rootEntitySource );
|
||||||
inheritanceTypes.push( entityHierarchy.getHierarchyInheritanceType() );
|
|
||||||
entityModes.push( rootEntitySource.getEntityMode() );
|
|
||||||
final LocalBindingContext bindingContext = rootEntitySource.getLocalBindingContext();
|
|
||||||
bindingContexts.push( bindingContext );
|
|
||||||
try {
|
try {
|
||||||
// Create root entity binding
|
// Create root entity binding
|
||||||
rootEntityBinding = createEntityBinding( rootEntitySource, null );
|
rootEntityBinding = createEntityBinding( rootEntitySource, null );
|
||||||
|
bindPrimaryTable( rootEntityBinding, rootEntitySource );
|
||||||
// Create/Bind root-specific information
|
// Create/Bind root-specific information
|
||||||
bindIdentifier( rootEntityBinding, rootEntitySource.getIdentifierSource() );
|
bindIdentifier( rootEntityBinding, rootEntitySource.getIdentifierSource() );
|
||||||
bindSecondaryTables( rootEntityBinding, rootEntitySource );
|
bindSecondaryTables( rootEntityBinding, rootEntitySource );
|
||||||
|
@ -808,14 +889,30 @@ public class Binder {
|
||||||
bindSubEntities( rootEntityBinding, rootEntitySource );
|
bindSubEntities( rootEntityBinding, rootEntitySource );
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
bindingContexts.pop();
|
cleanupBindingContext();
|
||||||
inheritanceTypes.pop();
|
|
||||||
entityModes.pop();
|
|
||||||
}
|
}
|
||||||
return rootEntityBinding;
|
return rootEntityBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bindEntities( final Iterable< EntityHierarchy > entityHierarchies ) {
|
private void cleanupBindingContext() {
|
||||||
|
bindingContexts.pop();
|
||||||
|
inheritanceTypes.pop();
|
||||||
|
entityModes.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupBindingContext(EntityHierarchy entityHierarchy, RootEntitySource rootEntitySource) {
|
||||||
|
// Save inheritance type and entity mode that will apply to entire hierarchy
|
||||||
|
inheritanceTypes.push( entityHierarchy.getHierarchyInheritanceType() );
|
||||||
|
entityModes.push( rootEntitySource.getEntityMode() );
|
||||||
|
bindingContexts.push( rootEntitySource.getLocalBindingContext() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The entry point of {@linkplain Binder} class, binds all the entity hierarchy one by one.
|
||||||
|
*
|
||||||
|
* @param entityHierarchies The entity hierarchies resolved from mappings
|
||||||
|
*/
|
||||||
|
public void bindEntityHierarchies(final Iterable<EntityHierarchy> entityHierarchies) {
|
||||||
entitySourcesByName.clear();
|
entitySourcesByName.clear();
|
||||||
attributeSourcesByName.clear();
|
attributeSourcesByName.clear();
|
||||||
inheritanceTypes.clear();
|
inheritanceTypes.clear();
|
||||||
|
@ -829,29 +926,7 @@ public class Binder {
|
||||||
}
|
}
|
||||||
// Bind each entity hierarchy
|
// Bind each entity hierarchy
|
||||||
for ( final EntityHierarchy entityHierarchy : entityHierarchies ) {
|
for ( final EntityHierarchy entityHierarchy : entityHierarchies ) {
|
||||||
bindEntities( entityHierarchy );
|
bindEntityHierarchy( entityHierarchy );
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private EntityBinding bindEntity( final EntitySource entitySource, final EntityBinding superEntityBinding ) {
|
|
||||||
// Return existing binding if available
|
|
||||||
EntityBinding entityBinding = metadata.getEntityBinding( entitySource.getEntityName() );
|
|
||||||
if ( entityBinding != null ) {
|
|
||||||
return entityBinding;
|
|
||||||
}
|
|
||||||
final LocalBindingContext bindingContext = entitySource.getLocalBindingContext();
|
|
||||||
bindingContexts.push( bindingContext );
|
|
||||||
try {
|
|
||||||
// Create new entity binding
|
|
||||||
entityBinding = createEntityBinding( entitySource, superEntityBinding );
|
|
||||||
entityBinding.setMutable( entityBinding.getHierarchyDetails().getRootEntityBinding().isMutable() );
|
|
||||||
bindSecondaryTables( entityBinding, entitySource );
|
|
||||||
bindUniqueConstraints( entityBinding, entitySource );
|
|
||||||
bindAttributes( entityBinding, entitySource );
|
|
||||||
bindSubEntities( entityBinding, entitySource );
|
|
||||||
return entityBinding;
|
|
||||||
} finally {
|
|
||||||
bindingContexts.pop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1122,7 +1197,7 @@ public class Binder {
|
||||||
bindingContext().qualifyClassName( attributeSource.getReferencedEntityName() != null
|
bindingContext().qualifyClassName( attributeSource.getReferencedEntityName() != null
|
||||||
? attributeSource.getReferencedEntityName()
|
? attributeSource.getReferencedEntityName()
|
||||||
: referencedJavaTypeValue.getValue().getName() );
|
: referencedJavaTypeValue.getValue().getName() );
|
||||||
final EntityBinding referencedEntityBinding = entityBinding( referencedEntityName );
|
final EntityBinding referencedEntityBinding = findOrBindingEntityBinding( referencedEntityName );
|
||||||
//now find the referenced attribute binding, either the referenced entity's id attribute or the referenced attribute
|
//now find the referenced attribute binding, either the referenced entity's id attribute or the referenced attribute
|
||||||
//todo referenced entityBinding null check?
|
//todo referenced entityBinding null check?
|
||||||
// Foreign key...
|
// Foreign key...
|
||||||
|
@ -1528,7 +1603,7 @@ public class Binder {
|
||||||
createAttributePath( attributeBinding )
|
createAttributePath( attributeBinding )
|
||||||
) );
|
) );
|
||||||
}
|
}
|
||||||
EntityBinding referencedEntityBinding = entityBinding( referencedEntityName );
|
EntityBinding referencedEntityBinding = findOrBindingEntityBinding( referencedEntityName );
|
||||||
bindOneToManyCollectionKey( attributeBinding, attributeSource, referencedEntityBinding );
|
bindOneToManyCollectionKey( attributeBinding, attributeSource, referencedEntityBinding );
|
||||||
bindOneToManyCollectionElement(
|
bindOneToManyCollectionElement(
|
||||||
(OneToManyPluralAttributeElementBinding) attributeBinding.getPluralAttributeElementBinding(),
|
(OneToManyPluralAttributeElementBinding) attributeBinding.getPluralAttributeElementBinding(),
|
||||||
|
@ -1563,21 +1638,37 @@ public class Binder {
|
||||||
return attributeBinding;
|
return attributeBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindPrimaryTable( final EntityBinding entityBinding, final EntitySource entitySource ) {
|
private void bindPrimaryTable(final EntityBinding entityBinding, final EntitySource entitySource) {
|
||||||
final TableSpecification table = createTable(
|
final EntityBinding superEntityBinding = entityBinding.getSuperEntityBinding();
|
||||||
entitySource.getPrimaryTable(), new DefaultNamingStrategy() {
|
final InheritanceType inheritanceType = entityBinding.getHierarchyDetails().getInheritanceType();
|
||||||
|
final TableSpecification table;
|
||||||
@Override
|
final String tableName;
|
||||||
public String defaultName() {
|
if ( superEntityBinding != null && inheritanceType == InheritanceType.SINGLE_TABLE ) {
|
||||||
String name = StringHelper.isNotEmpty( entityBinding.getJpaEntityName() ) ? entityBinding.getJpaEntityName() : entityBinding
|
table = superEntityBinding.getPrimaryTable();
|
||||||
.getEntity()
|
tableName = superEntityBinding.getPrimaryTableName();
|
||||||
.getClassName();
|
// Configure discriminator if present
|
||||||
return bindingContexts.peek().getNamingStrategy().classToTableName( name );
|
final String discriminatorValue = entitySource.getDiscriminatorMatchValue() != null ?
|
||||||
}
|
entitySource.getDiscriminatorMatchValue()
|
||||||
|
: entitySource.getEntityName();
|
||||||
|
entityBinding.setDiscriminatorMatchValue( discriminatorValue );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
table = createTable(
|
||||||
|
entitySource.getPrimaryTable(), new DefaultNamingStrategy() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String defaultName() {
|
||||||
|
String name = StringHelper.isNotEmpty( entityBinding.getJpaEntityName() ) ? entityBinding.getJpaEntityName() : entityBinding
|
||||||
|
.getEntity()
|
||||||
|
.getClassName();
|
||||||
|
return bindingContexts.peek().getNamingStrategy().classToTableName( name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
tableName = table.getLogicalName().getText();
|
||||||
}
|
}
|
||||||
);
|
|
||||||
entityBinding.setPrimaryTable( table );
|
entityBinding.setPrimaryTable( table );
|
||||||
entityBinding.setPrimaryTableName( table.getLogicalName().getText() );
|
entityBinding.setPrimaryTableName( tableName );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindSecondaryTables( final EntityBinding entityBinding, final EntitySource entitySource ) {
|
private void bindSecondaryTables( final EntityBinding entityBinding, final EntitySource entitySource ) {
|
||||||
|
@ -1727,7 +1818,7 @@ public class Binder {
|
||||||
|
|
||||||
private void bindSubEntities( final EntityBinding entityBinding, final EntitySource entitySource ) {
|
private void bindSubEntities( final EntityBinding entityBinding, final EntitySource entitySource ) {
|
||||||
for ( final SubclassEntitySource subEntitySource : entitySource.subclassEntitySources() ) {
|
for ( final SubclassEntitySource subEntitySource : entitySource.subclassEntitySources() ) {
|
||||||
bindEntity( subEntitySource, entityBinding );
|
bindSubEntity( subEntitySource, entityBinding );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1954,6 +2045,7 @@ public class Binder {
|
||||||
entityClassName,
|
entityClassName,
|
||||||
bindingContext.makeClassReference( entityClassName ),
|
bindingContext.makeClassReference( entityClassName ),
|
||||||
superEntityBinding == null ? null : superEntityBinding.getEntity() ) );
|
superEntityBinding == null ? null : superEntityBinding.getEntity() ) );
|
||||||
|
|
||||||
entityBinding.setEntityName( entitySource.getEntityName() );
|
entityBinding.setEntityName( entitySource.getEntityName() );
|
||||||
entityBinding.setJpaEntityName( entitySource.getJpaEntityName() ); //must before creating primary table
|
entityBinding.setJpaEntityName( entitySource.getJpaEntityName() ); //must before creating primary table
|
||||||
entityBinding.setDynamicUpdate( entitySource.isDynamicUpdate() );
|
entityBinding.setDynamicUpdate( entitySource.isDynamicUpdate() );
|
||||||
|
@ -1961,39 +2053,11 @@ public class Binder {
|
||||||
entityBinding.setBatchSize( entitySource.getBatchSize() );
|
entityBinding.setBatchSize( entitySource.getBatchSize() );
|
||||||
entityBinding.setSelectBeforeUpdate( entitySource.isSelectBeforeUpdate() );
|
entityBinding.setSelectBeforeUpdate( entitySource.isSelectBeforeUpdate() );
|
||||||
entityBinding.setAbstract( entitySource.isAbstract() );
|
entityBinding.setAbstract( entitySource.isAbstract() );
|
||||||
|
|
||||||
entityBinding.setCustomLoaderName( entitySource.getCustomLoaderName() );
|
entityBinding.setCustomLoaderName( entitySource.getCustomLoaderName() );
|
||||||
entityBinding.setCustomInsert( entitySource.getCustomSqlInsert() );
|
entityBinding.setCustomInsert( entitySource.getCustomSqlInsert() );
|
||||||
entityBinding.setCustomUpdate( entitySource.getCustomSqlUpdate() );
|
entityBinding.setCustomUpdate( entitySource.getCustomSqlUpdate() );
|
||||||
entityBinding.setCustomDelete( entitySource.getCustomSqlDelete() );
|
entityBinding.setCustomDelete( entitySource.getCustomSqlDelete() );
|
||||||
entityBinding.setJpaCallbackClasses( entitySource.getJpaCallbackClasses() );
|
entityBinding.setJpaCallbackClasses( entitySource.getJpaCallbackClasses() );
|
||||||
// Create relational table
|
|
||||||
if ( superEntityBinding != null && inheritanceType == InheritanceType.SINGLE_TABLE ) {
|
|
||||||
entityBinding.setPrimaryTable( superEntityBinding.getPrimaryTable() );
|
|
||||||
entityBinding.setPrimaryTableName( superEntityBinding.getPrimaryTableName() );
|
|
||||||
// Configure discriminator if present
|
|
||||||
final String discriminatorValue = entitySource.getDiscriminatorMatchValue();
|
|
||||||
if ( discriminatorValue != null ) {
|
|
||||||
entityBinding.setDiscriminatorMatchValue( discriminatorValue );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
entityBinding.setDiscriminatorMatchValue( entitySource.getEntityName() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bindPrimaryTable( entityBinding, entitySource );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( inheritanceType == InheritanceType.JOINED && superEntityBinding != null ) {
|
|
||||||
ForeignKey fk = entityBinding.getPrimaryTable().createForeignKey(
|
|
||||||
superEntityBinding.getPrimaryTable(),
|
|
||||||
( (SubclassEntitySource) entitySource ).getJoinedForeignKeyName()
|
|
||||||
);
|
|
||||||
// explicitly maps to target table pk
|
|
||||||
for ( Column column : entityBinding.getPrimaryTable().getPrimaryKey().getColumns() ) {
|
|
||||||
fk.addColumn( column );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: deal with joined and unioned subclass bindings
|
// todo: deal with joined and unioned subclass bindings
|
||||||
// todo: bind fetch profiles
|
// todo: bind fetch profiles
|
||||||
|
@ -2313,27 +2377,33 @@ public class Binder {
|
||||||
:referencedEntityBinding.locateAttributeBinding( resolutionDelegate.getJoinColumns( resolutionContext ) );
|
:referencedEntityBinding.locateAttributeBinding( resolutionDelegate.getJoinColumns( resolutionContext ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private EntityBinding entityBinding( final String entityName ) {
|
/**
|
||||||
|
*
|
||||||
|
* @param entityName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private EntityBinding findOrBindingEntityBinding(final String entityName) {
|
||||||
// Check if binding has already been created
|
// Check if binding has already been created
|
||||||
EntityBinding entityBinding = metadata.getEntityBinding( entityName );
|
EntityBinding entityBinding = metadata.getEntityBinding( entityName );
|
||||||
if ( entityBinding == null ) {
|
if ( entityBinding == null ) {
|
||||||
// Find appropriate source to create binding
|
// Find appropriate source to create binding
|
||||||
final EntitySource entitySource = entitySourcesByName.get( entityName );
|
final EntitySource entitySource = entitySourcesByName.get( entityName );
|
||||||
if(entitySource == null) {
|
if ( entitySource == null ) {
|
||||||
String msg = log.missingEntitySource( entityName );
|
String msg = log.missingEntitySource( entityName );
|
||||||
bindingContext().makeMappingException( msg );
|
bindingContext().makeMappingException( msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get super entity binding (creating it if necessary using recursive call to this method)
|
// Get super entity binding (creating it if necessary using recursive call to this method)
|
||||||
final EntityBinding superEntityBinding =
|
if ( SubclassEntitySource.class.isInstance( entitySource ) ) {
|
||||||
SubclassEntitySource.class.isInstance( entitySource )
|
String superEntityName = ( (SubclassEntitySource) entitySource ).superclassEntitySource()
|
||||||
? entityBinding( ( ( SubclassEntitySource ) entitySource ).superclassEntitySource().getEntityName() )
|
.getEntityName();
|
||||||
: null;
|
EntityBinding superEntityBinding = findOrBindingEntityBinding( superEntityName );
|
||||||
// Create entity binding
|
entityBinding = bindSubEntity( entitySource, superEntityBinding );
|
||||||
entityBinding =
|
}
|
||||||
superEntityBinding == null
|
else {
|
||||||
? bindEntities( entityHierarchiesByRootEntitySource.get( entitySource ) )
|
EntityHierarchy entityHierarchy = entityHierarchiesByRootEntitySource.get( entitySource );
|
||||||
: bindEntity( entitySource, superEntityBinding );
|
entityBinding = bindEntityHierarchy( entityHierarchy );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return entityBinding;
|
return entityBinding;
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,7 +211,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
|
||||||
}
|
}
|
||||||
final HbmMetadataSourceProcessorImpl processor = new HbmMetadataSourceProcessorImpl( this, jaxbRoots );
|
final HbmMetadataSourceProcessorImpl processor = new HbmMetadataSourceProcessorImpl( this, jaxbRoots );
|
||||||
final Binder binder = new Binder( this, identifierGeneratorFactory );
|
final Binder binder = new Binder( this, identifierGeneratorFactory );
|
||||||
binder.bindEntities( processor.extractEntityHierarchies() );
|
binder.bindEntityHierarchies( processor.extractEntityHierarchies() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -350,7 +350,7 @@ public class MetadataImpl implements MetadataImplementor, Serializable {
|
||||||
private void processMappings(MetadataSourceProcessor[] metadataSourceProcessors) {
|
private void processMappings(MetadataSourceProcessor[] metadataSourceProcessors) {
|
||||||
final Binder binder = new Binder( this, identifierGeneratorFactory );
|
final Binder binder = new Binder( this, identifierGeneratorFactory );
|
||||||
for ( MetadataSourceProcessor processor : metadataSourceProcessors ) {
|
for ( MetadataSourceProcessor processor : metadataSourceProcessors ) {
|
||||||
binder.bindEntities( processor.extractEntityHierarchies() );
|
binder.bindEntityHierarchies( processor.extractEntityHierarchies() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -473,7 +473,8 @@ public class AssociationAttribute extends MappedAttribute {
|
||||||
if ( joinTableAnnotation != null ) {
|
if ( joinTableAnnotation != null ) {
|
||||||
if ( JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_ONE ) == null
|
if ( JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_ONE ) == null
|
||||||
&& JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_MANY ) == null
|
&& JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_MANY ) == null
|
||||||
&& JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_MANY ) == null ) {
|
&& JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_MANY ) == null
|
||||||
|
&& JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_ONE ) == null ) {
|
||||||
String msg = coreLogger.joinTableForNonAssociationAttribute(
|
String msg = coreLogger.joinTableForNonAssociationAttribute(
|
||||||
getContext().getOrigin().getName(),
|
getContext().getOrigin().getName(),
|
||||||
getName()
|
getName()
|
||||||
|
|
|
@ -262,7 +262,7 @@ public class EntityClass extends ConfiguredClass {
|
||||||
return JandexHelper.getValue( jpaEntityAnnotation, "name", String.class );
|
return JandexHelper.getValue( jpaEntityAnnotation, "name", String.class );
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<PrimaryKeyJoinColumnSource> determinPrimaryKeyJoinColumns() {
|
protected List<PrimaryKeyJoinColumnSource> determinPrimaryKeyJoinColumns() {
|
||||||
if ( inheritanceType != InheritanceType.JOINED ) {
|
if ( inheritanceType != InheritanceType.JOINED ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,12 @@ import javax.persistence.DiscriminatorType;
|
||||||
import org.jboss.jandex.AnnotationInstance;
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
import org.jboss.jandex.ClassInfo;
|
import org.jboss.jandex.ClassInfo;
|
||||||
import org.jboss.jandex.DotName;
|
import org.jboss.jandex.DotName;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.hibernate.AnnotationException;
|
import org.hibernate.AnnotationException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||||
import org.hibernate.metamodel.internal.source.annotations.AnnotationBindingContext;
|
import org.hibernate.metamodel.internal.source.annotations.AnnotationBindingContext;
|
||||||
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.Column;
|
import org.hibernate.metamodel.internal.source.annotations.attribute.Column;
|
||||||
|
@ -43,6 +46,7 @@ import org.hibernate.metamodel.internal.source.annotations.util.HibernateDotName
|
||||||
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.InheritanceType;
|
import org.hibernate.metamodel.spi.binding.InheritanceType;
|
||||||
|
import org.hibernate.metamodel.spi.source.PrimaryKeyJoinColumnSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an root entity configured via annotations/orm-xml.
|
* Represents an root entity configured via annotations/orm-xml.
|
||||||
|
@ -51,6 +55,10 @@ import org.hibernate.metamodel.spi.binding.InheritanceType;
|
||||||
* @author Brett Meyer
|
* @author Brett Meyer
|
||||||
*/
|
*/
|
||||||
public class RootEntityClass extends EntityClass {
|
public class RootEntityClass extends EntityClass {
|
||||||
|
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||||
|
CoreMessageLogger.class,
|
||||||
|
RootEntityClass.class.getName()
|
||||||
|
);
|
||||||
|
|
||||||
private final IdType idType;
|
private final IdType idType;
|
||||||
private final List<MappedSuperclass> mappedSuperclasses;
|
private final List<MappedSuperclass> mappedSuperclasses;
|
||||||
|
@ -132,6 +140,14 @@ public class RootEntityClass extends EntityClass {
|
||||||
return isDiscriminatorIncludedInSql;
|
return isDiscriminatorIncludedInSql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected List<PrimaryKeyJoinColumnSource> determinPrimaryKeyJoinColumns() {
|
||||||
|
List<PrimaryKeyJoinColumnSource> results = super.determinPrimaryKeyJoinColumns();
|
||||||
|
if ( CollectionHelper.isNotEmpty( results ) ) {
|
||||||
|
LOG.invalidPrimaryKeyJoinColumnAnnotation();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<BasicAttribute> getSimpleAttributes() {
|
public Collection<BasicAttribute> getSimpleAttributes() {
|
||||||
List<BasicAttribute> attributes = new ArrayList<BasicAttribute>();
|
List<BasicAttribute> attributes = new ArrayList<BasicAttribute>();
|
||||||
|
|
|
@ -153,9 +153,9 @@ public interface JPADotNames {
|
||||||
DotName GENERATED_VALUE = DotName.createSimple( GeneratedValue.class.getName() );
|
DotName GENERATED_VALUE = DotName.createSimple( GeneratedValue.class.getName() );
|
||||||
DotName ID = DotName.createSimple( Id.class.getName() );
|
DotName ID = DotName.createSimple( Id.class.getName() );
|
||||||
DotName ID_CLASS = DotName.createSimple( IdClass.class.getName() );
|
DotName ID_CLASS = DotName.createSimple( IdClass.class.getName() );
|
||||||
|
DotName INHERITANCE = DotName.createSimple( Inheritance.class.getName() );
|
||||||
DotName INHERITANCE_TYPE = DotName.createSimple( InheritanceType.class.getName() );
|
DotName INHERITANCE_TYPE = DotName.createSimple( InheritanceType.class.getName() );
|
||||||
DotName JOIN_COLUMN = DotName.createSimple( JoinColumn.class.getName() );
|
DotName JOIN_COLUMN = DotName.createSimple( JoinColumn.class.getName() );
|
||||||
DotName INHERITANCE = DotName.createSimple( Inheritance.class.getName() );
|
|
||||||
DotName JOIN_COLUMNS = DotName.createSimple( JoinColumns.class.getName() );
|
DotName JOIN_COLUMNS = DotName.createSimple( JoinColumns.class.getName() );
|
||||||
DotName JOIN_TABLE = DotName.createSimple( JoinTable.class.getName() );
|
DotName JOIN_TABLE = DotName.createSimple( JoinTable.class.getName() );
|
||||||
DotName LOB = DotName.createSimple( Lob.class.getName() );
|
DotName LOB = DotName.createSimple( Lob.class.getName() );
|
||||||
|
|
|
@ -26,6 +26,7 @@ package org.hibernate.metamodel.spi.binding;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -35,6 +36,9 @@ import org.hibernate.EntityMode;
|
||||||
import org.hibernate.engine.spi.FilterDefinition;
|
import org.hibernate.engine.spi.FilterDefinition;
|
||||||
import org.hibernate.internal.util.ValueHolder;
|
import org.hibernate.internal.util.ValueHolder;
|
||||||
import org.hibernate.internal.util.collections.JoinedIterable;
|
import org.hibernate.internal.util.collections.JoinedIterable;
|
||||||
|
import org.hibernate.internal.util.collections.JoinedIterator;
|
||||||
|
import org.hibernate.internal.util.collections.SingletonIterator;
|
||||||
|
import org.hibernate.mapping.PropertyGeneration;
|
||||||
import org.hibernate.metamodel.spi.domain.AttributeContainer;
|
import org.hibernate.metamodel.spi.domain.AttributeContainer;
|
||||||
import org.hibernate.metamodel.spi.domain.Entity;
|
import org.hibernate.metamodel.spi.domain.Entity;
|
||||||
import org.hibernate.metamodel.spi.domain.SingularAttribute;
|
import org.hibernate.metamodel.spi.domain.SingularAttribute;
|
||||||
|
@ -102,7 +106,8 @@ public class EntityBinding extends AbstractAttributeBindingContainer {
|
||||||
private Map<String, AttributeBinding> attributeBindingMap = new HashMap<String, AttributeBinding>();
|
private Map<String, AttributeBinding> attributeBindingMap = new HashMap<String, AttributeBinding>();
|
||||||
|
|
||||||
private List<JpaCallbackSource> jpaCallbackClasses = new ArrayList<JpaCallbackSource>();
|
private List<JpaCallbackSource> jpaCallbackClasses = new ArrayList<JpaCallbackSource>();
|
||||||
|
private final int subEntityBindingId;
|
||||||
|
private int nextSubEntityBindingId = 0;
|
||||||
/**
|
/**
|
||||||
* Used to instantiate the EntityBinding for an entity that is the root of an inheritance hierarchy
|
* Used to instantiate the EntityBinding for an entity that is the root of an inheritance hierarchy
|
||||||
*
|
*
|
||||||
|
@ -112,6 +117,7 @@ public class EntityBinding extends AbstractAttributeBindingContainer {
|
||||||
public EntityBinding(InheritanceType inheritanceType, EntityMode entityMode) {
|
public EntityBinding(InheritanceType inheritanceType, EntityMode entityMode) {
|
||||||
this.superEntityBinding = null;
|
this.superEntityBinding = null;
|
||||||
this.hierarchyDetails = new HierarchyDetails( this, inheritanceType, entityMode );
|
this.hierarchyDetails = new HierarchyDetails( this, inheritanceType, entityMode );
|
||||||
|
this.subEntityBindingId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,6 +129,11 @@ public class EntityBinding extends AbstractAttributeBindingContainer {
|
||||||
this.superEntityBinding = superEntityBinding;
|
this.superEntityBinding = superEntityBinding;
|
||||||
this.superEntityBinding.subEntityBindings.add( this );
|
this.superEntityBinding.subEntityBindings.add( this );
|
||||||
this.hierarchyDetails = superEntityBinding.getHierarchyDetails();
|
this.hierarchyDetails = superEntityBinding.getHierarchyDetails();
|
||||||
|
this.subEntityBindingId = superEntityBinding.nextSubEntityBindingId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int nextSubEntityBindingId(){
|
||||||
|
return ++nextSubEntityBindingId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HierarchyDetails getHierarchyDetails() {
|
public HierarchyDetails getHierarchyDetails() {
|
||||||
|
@ -133,6 +144,10 @@ public class EntityBinding extends AbstractAttributeBindingContainer {
|
||||||
return superEntityBinding;
|
return superEntityBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getSubEntityBindingId() {
|
||||||
|
return subEntityBindingId;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isRoot() {
|
public boolean isRoot() {
|
||||||
return superEntityBinding == null;
|
return superEntityBinding == null;
|
||||||
}
|
}
|
||||||
|
@ -578,6 +593,21 @@ public class EntityBinding extends AbstractAttributeBindingContainer {
|
||||||
return new JoinedIterable<AttributeBinding>( iterables );
|
return new JoinedIterable<AttributeBinding>( iterables );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Iterator<TableSpecification> getTableClosureIterator() {
|
||||||
|
if ( superEntityBinding == null ) {
|
||||||
|
return new SingletonIterator<TableSpecification>( getPrimaryTable() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new JoinedIterator<TableSpecification>(
|
||||||
|
superEntityBinding.getTableClosureIterator(),
|
||||||
|
new SingletonIterator<TableSpecification>( getPrimaryTable() )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Iterator getKeyClosureIterator(){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public void setJpaCallbackClasses(List<JpaCallbackSource> jpaCallbackClasses) {
|
public void setJpaCallbackClasses(List<JpaCallbackSource> jpaCallbackClasses) {
|
||||||
this.jpaCallbackClasses = jpaCallbackClasses;
|
this.jpaCallbackClasses = jpaCallbackClasses;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,9 @@ package org.hibernate.metamodel.spi.relational;
|
||||||
|
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.dialect.function.SQLFunctionRegistry;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
import org.hibernate.sql.Template;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Models a physical column
|
* Models a physical column
|
||||||
|
@ -128,6 +130,25 @@ public class Column extends AbstractValue {
|
||||||
this.comment = comment;
|
this.comment = comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTemplate(Dialect dialect, SQLFunctionRegistry functionRegistry) {
|
||||||
|
return hasCustomRead()
|
||||||
|
? Template.renderWhereStringTemplate( readFragment, dialect, functionRegistry )
|
||||||
|
: Template.TEMPLATE + '.' + getColumnName().getText( dialect );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasCustomRead() {
|
||||||
|
return StringHelper.isNotEmpty( readFragment );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReadExpr(Dialect dialect) {
|
||||||
|
return hasCustomRead() ? readFragment : getColumnName().getText( dialect );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWriteExpr() {
|
||||||
|
return StringHelper.isNotEmpty( writeFragment ) ? writeFragment : "?";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Size getSize() {
|
public Size getSize() {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2140,7 +2140,7 @@ public abstract class AbstractCollectionPersister
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public int getSize(Serializable key, SessionImplementor session) {
|
public int getSize(Serializable key, SessionImplementor session) {
|
||||||
try {
|
try {
|
||||||
PreparedStatement st = session.getTransactionCoordinator()
|
PreparedStatement st = session.getTransactionCoordinator()
|
||||||
|
|
|
@ -186,16 +186,16 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
|
||||||
|
|
||||||
return delete.toStatementString();
|
return delete.toStatementString();
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public boolean consumesEntityAlias() {
|
public boolean consumesEntityAlias() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public boolean consumesCollectionAlias() {
|
public boolean consumesCollectionAlias() {
|
||||||
// return !isOneToMany();
|
// return !isOneToMany();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public boolean isOneToMany() {
|
public boolean isOneToMany() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -210,8 +210,10 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
|
||||||
@Override
|
@Override
|
||||||
protected int doUpdateRows(Serializable id, PersistentCollection collection, SessionImplementor session)
|
protected int doUpdateRows(Serializable id, PersistentCollection collection, SessionImplementor session)
|
||||||
throws HibernateException {
|
throws HibernateException {
|
||||||
|
|
||||||
if ( ArrayHelper.isAllFalse(elementColumnIsSettable) ) return 0;
|
if ( ArrayHelper.isAllFalse( elementColumnIsSettable ) ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
PreparedStatement st = null;
|
PreparedStatement st = null;
|
||||||
|
@ -342,11 +344,11 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
|
||||||
throws MappingException {
|
throws MappingException {
|
||||||
return BatchingCollectionInitializer.createBatchingCollectionInitializer( this, batchSize, getFactory(), loadQueryInfluencers );
|
return BatchingCollectionInitializer.createBatchingCollectionInitializer( this, batchSize, getFactory(), loadQueryInfluencers );
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) {
|
public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public String whereJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) {
|
public String whereJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -507,8 +507,8 @@ public abstract class AbstractEntityPersister
|
||||||
this.naturalIdRegionAccessStrategy = naturalIdRegionAccessStrategy;
|
this.naturalIdRegionAccessStrategy = naturalIdRegionAccessStrategy;
|
||||||
isLazyPropertiesCacheable = persistentClass.isLazyPropertiesCacheable();
|
isLazyPropertiesCacheable = persistentClass.isLazyPropertiesCacheable();
|
||||||
this.cacheEntryStructure = factory.getSettings().isStructuredCacheEntriesEnabled() ?
|
this.cacheEntryStructure = factory.getSettings().isStructuredCacheEntriesEnabled() ?
|
||||||
(CacheEntryStructure) new StructuredCacheEntry(this) :
|
new StructuredCacheEntry(this) :
|
||||||
(CacheEntryStructure) new UnstructuredCacheEntry();
|
new UnstructuredCacheEntry();
|
||||||
|
|
||||||
this.entityMetamodel = new EntityMetamodel( persistentClass, factory );
|
this.entityMetamodel = new EntityMetamodel( persistentClass, factory );
|
||||||
this.entityTuplizer = this.entityMetamodel.getTuplizer();
|
this.entityTuplizer = this.entityMetamodel.getTuplizer();
|
||||||
|
|
|
@ -53,6 +53,8 @@ import org.hibernate.mapping.Table;
|
||||||
import org.hibernate.metamodel.spi.binding.EntityBinding;
|
import org.hibernate.metamodel.spi.binding.EntityBinding;
|
||||||
import org.hibernate.metamodel.spi.binding.EntityDiscriminator;
|
import org.hibernate.metamodel.spi.binding.EntityDiscriminator;
|
||||||
import org.hibernate.metamodel.spi.relational.DerivedValue;
|
import org.hibernate.metamodel.spi.relational.DerivedValue;
|
||||||
|
import org.hibernate.metamodel.spi.relational.PrimaryKey;
|
||||||
|
import org.hibernate.metamodel.spi.relational.TableSpecification;
|
||||||
import org.hibernate.sql.CaseFragment;
|
import org.hibernate.sql.CaseFragment;
|
||||||
import org.hibernate.sql.SelectFragment;
|
import org.hibernate.sql.SelectFragment;
|
||||||
import org.hibernate.type.*;
|
import org.hibernate.type.*;
|
||||||
|
@ -517,20 +519,10 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
super( entityBinding, cacheAccessStrategy, naturalIdRegionAccessStrategy, factory );
|
super( entityBinding, cacheAccessStrategy, naturalIdRegionAccessStrategy, factory );
|
||||||
// DISCRIMINATOR
|
// DISCRIMINATOR
|
||||||
if ( entityBinding.isPolymorphic() ) {
|
if ( entityBinding.isPolymorphic() ) {
|
||||||
EntityDiscriminator discriminator = entityBinding.getHierarchyDetails().getEntityDiscriminator();
|
try{
|
||||||
discriminator.getRelationalValue();
|
discriminatorValue = entityBinding.getSubEntityBindingId();
|
||||||
Type discriminatorType = discriminator
|
discriminatorSQLString = discriminatorValue.toString();
|
||||||
.getExplicitHibernateTypeDescriptor()
|
} catch ( Exception e ){
|
||||||
.getResolvedTypeMapping();
|
|
||||||
try {
|
|
||||||
org.hibernate.type.DiscriminatorType dtype = (org.hibernate.type.DiscriminatorType) discriminatorType;
|
|
||||||
discriminatorValue = dtype.stringToObject( entityBinding.getDiscriminatorMatchValue() );
|
|
||||||
discriminatorSQLString = dtype.objectToSQLString( discriminatorValue, factory.getDialect() );
|
|
||||||
}
|
|
||||||
catch ( ClassCastException cce ) {
|
|
||||||
throw new MappingException( "Illegal discriminator type: " + discriminatorType.getName() );
|
|
||||||
}
|
|
||||||
catch ( Exception e ) {
|
|
||||||
throw new MappingException( "Could not format discriminator value to SQL string", e );
|
throw new MappingException( "Could not format discriminator value to SQL string", e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -546,27 +538,54 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
|
|
||||||
final int idColumnSpan = getIdentifierColumnSpan();
|
final int idColumnSpan = getIdentifierColumnSpan();
|
||||||
|
|
||||||
ArrayList tables = new ArrayList();
|
ArrayList<String> tables = new ArrayList<String>();
|
||||||
ArrayList keyColumns = new ArrayList();
|
ArrayList keyColumns = new ArrayList();
|
||||||
ArrayList keyColumnReaders = new ArrayList();
|
ArrayList keyColumnReaders = new ArrayList();
|
||||||
ArrayList keyColumnReaderTemplates = new ArrayList();
|
ArrayList keyColumnReaderTemplates = new ArrayList();
|
||||||
ArrayList cascadeDeletes = new ArrayList();
|
ArrayList cascadeDeletes = new ArrayList();
|
||||||
// Iterator titer = persistentClass.getTableClosureIterator();
|
Iterator<TableSpecification> titer = entityBinding.getTableClosureIterator();
|
||||||
// Iterator kiter = persistentClass.getKeyClosureIterator();
|
while ( titer.hasNext() ){
|
||||||
|
TableSpecification table = titer.next();
|
||||||
|
String tableName = table.getLogicalName().getText(factory.getDialect());
|
||||||
|
tables.add( tableName );
|
||||||
|
String[] keyCols = new String[idColumnSpan];
|
||||||
|
String[] keyColReaders = new String[idColumnSpan];
|
||||||
|
String[] keyColReaderTemplates = new String[idColumnSpan];
|
||||||
|
PrimaryKey primaryKey= table.getPrimaryKey();
|
||||||
|
for ( int k = 0; k < idColumnSpan; k++ ) {
|
||||||
|
org.hibernate.metamodel.spi.relational.Column column = primaryKey.getColumns().get( k );
|
||||||
|
keyCols[k] = column.getColumnName().getText(factory.getDialect());
|
||||||
|
keyColReaders[k] = column.getReadExpr( factory.getDialect() );
|
||||||
|
keyColReaderTemplates[k] = column.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
|
||||||
|
}
|
||||||
|
keyColumns.add( keyCols );
|
||||||
|
keyColumnReaders.add( keyColReaders );
|
||||||
|
keyColumnReaderTemplates.add( keyColReaderTemplates );
|
||||||
|
cascadeDeletes.add( false && factory.getDialect().supportsCascadeDelete() ); //todo add @OnDelete support
|
||||||
|
}
|
||||||
|
|
||||||
|
//Span of the tables directly mapped by this entity and super-classes, if any
|
||||||
|
coreTableSpan = tables.size();
|
||||||
|
//todo secondary table
|
||||||
|
isNullableTable = new boolean[]{true};
|
||||||
|
naturalOrderTableNames = ArrayHelper.toStringArray( tables );
|
||||||
|
naturalOrderTableKeyColumns = ArrayHelper.to2DStringArray( keyColumns );
|
||||||
|
naturalOrderTableKeyColumnReaders = ArrayHelper.to2DStringArray( keyColumnReaders );
|
||||||
|
naturalOrderTableKeyColumnReaderTemplates = ArrayHelper.to2DStringArray( keyColumnReaderTemplates );
|
||||||
|
naturalOrderCascadeDeleteEnabled = ArrayHelper.toBooleanArray( cascadeDeletes );
|
||||||
|
ArrayList subtables = new ArrayList();
|
||||||
|
ArrayList isConcretes = new ArrayList();
|
||||||
|
ArrayList isDeferreds = new ArrayList();
|
||||||
|
ArrayList isLazies = new ArrayList();
|
||||||
|
keyColumns = new ArrayList();
|
||||||
|
//todo add sub class tables here
|
||||||
//----------------------------------------------
|
//----------------------------------------------
|
||||||
|
|
||||||
tableSpan = -1;
|
tableSpan = -1;
|
||||||
tableNames = null;
|
tableNames = null;
|
||||||
naturalOrderTableNames = null;
|
|
||||||
tableKeyColumns = null;
|
tableKeyColumns = null;
|
||||||
tableKeyColumnReaders = null;
|
tableKeyColumnReaders = null;
|
||||||
tableKeyColumnReaderTemplates = null;
|
tableKeyColumnReaderTemplates = null;
|
||||||
naturalOrderTableKeyColumns = null;
|
|
||||||
naturalOrderTableKeyColumnReaders = null;
|
|
||||||
naturalOrderTableKeyColumnReaderTemplates = null;
|
|
||||||
naturalOrderCascadeDeleteEnabled = null;
|
|
||||||
spaces = null;
|
spaces = null;
|
||||||
subclassClosure = null;
|
subclassClosure = null;
|
||||||
subclassTableNameClosure = null;
|
subclassTableNameClosure = null;
|
||||||
|
@ -584,8 +603,6 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
notNullColumnTableNumbers = null;
|
notNullColumnTableNumbers = null;
|
||||||
constraintOrderedTableNames = null;
|
constraintOrderedTableNames = null;
|
||||||
constraintOrderedKeyColumnNames = null;
|
constraintOrderedKeyColumnNames = null;
|
||||||
coreTableSpan = -1;
|
|
||||||
isNullableTable = null;
|
|
||||||
//-----------------------------
|
//-----------------------------
|
||||||
initLockers();
|
initLockers();
|
||||||
initSubclassPropertyAliasesMap( entityBinding );
|
initSubclassPropertyAliasesMap( entityBinding );
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
private final String[] subclassSpaces;
|
private final String[] subclassSpaces;
|
||||||
private final Object discriminatorValue;
|
private final Object discriminatorValue;
|
||||||
private final String discriminatorSQLValue;
|
private final String discriminatorSQLValue;
|
||||||
private final Map subclassByDiscriminatorValue = new HashMap();
|
private final Map<Integer,String> subclassByDiscriminatorValue = new HashMap<Integer,String>();
|
||||||
|
|
||||||
private final String[] constraintOrderedTableNames;
|
private final String[] constraintOrderedTableNames;
|
||||||
private final String[][] constraintOrderedKeyColumnNames;
|
private final String[][] constraintOrderedKeyColumnNames;
|
||||||
|
@ -185,7 +185,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
spaces[i] = (String) iter.next();
|
spaces[i] = (String) iter.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
HashSet subclassTables = new HashSet();
|
HashSet<String> subclassTables = new HashSet<String>();
|
||||||
iter = persistentClass.getSubclassTableClosureIterator();
|
iter = persistentClass.getSubclassTableClosureIterator();
|
||||||
while ( iter.hasNext() ) {
|
while ( iter.hasNext() ) {
|
||||||
Table table = (Table) iter.next();
|
Table table = (Table) iter.next();
|
||||||
|
@ -251,7 +251,7 @@ public class UnionSubclassEntityPersister extends AbstractEntityPersister {
|
||||||
super(entityBinding, cacheAccessStrategy, naturalIdRegionAccessStrategy, factory );
|
super(entityBinding, cacheAccessStrategy, naturalIdRegionAccessStrategy, factory );
|
||||||
// TODO: implement!!! initializing final fields to null to make compiler happy.
|
// TODO: implement!!! initializing final fields to null to make compiler happy.
|
||||||
subquery = null;
|
subquery = null;
|
||||||
tableName = null;
|
tableName = entityBinding.getPrimaryTable().getQualifiedName( factory.getDialect() );
|
||||||
subclassClosure = null;
|
subclassClosure = null;
|
||||||
spaces = null;
|
spaces = null;
|
||||||
subclassSpaces = null;
|
subclassSpaces = null;
|
||||||
|
|
Loading…
Reference in New Issue