HHH-14526 validate table repetition in JOINED hierarchies
and automatically force the discriminator when necessary
This commit is contained in:
parent
0f29c15461
commit
01d608ca84
|
@ -32,8 +32,8 @@ public class JoinedSubclass extends Subclass implements TableOwner {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTable(Table table) {
|
public void setTable(Table table) {
|
||||||
this.table=table;
|
this.table = table;
|
||||||
getSuperclass().addSubclassTable(table);
|
getSuperclass().addSubclassTable( table );
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyValue getKey() {
|
public KeyValue getKey() {
|
||||||
|
|
|
@ -37,6 +37,10 @@ import org.hibernate.service.ServiceRegistry;
|
||||||
import org.hibernate.sql.Alias;
|
import org.hibernate.sql.Alias;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
|
import static java.util.Collections.unmodifiableList;
|
||||||
|
import static org.hibernate.internal.util.StringHelper.root;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mapping model object that represents an {@linkplain jakarta.persistence.Entity entity class}.
|
* A mapping model object that represents an {@linkplain jakarta.persistence.Entity entity class}.
|
||||||
*
|
*
|
||||||
|
@ -239,8 +243,7 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
List<Subclass>[] subclassLists = new List[subclasses.size() + 1];
|
List<Subclass>[] subclassLists = new List[subclasses.size() + 1];
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < subclasses.size(); j++) {
|
for (j = 0; j < subclasses.size(); j++) {
|
||||||
Subclass subclass = subclasses.get(j);
|
subclassLists[j] = subclasses.get(j).getSubclasses();
|
||||||
subclassLists[j] = subclass.getSubclasses();
|
|
||||||
}
|
}
|
||||||
subclassLists[j] = subclasses;
|
subclassLists[j] = subclasses;
|
||||||
return new JoinedList<>( subclassLists );
|
return new JoinedList<>( subclassLists );
|
||||||
|
@ -254,14 +257,14 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
@Deprecated(since = "6.0") @Remove
|
@Deprecated(since = "6.0") @Remove
|
||||||
public Iterator<Subclass> getSubclassIterator() {
|
public Iterator<Subclass> getSubclassIterator() {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final Iterator<Subclass>[] iters = new Iterator[subclasses.size() + 1];
|
final Iterator<Subclass>[] iterators = new Iterator[subclasses.size() + 1];
|
||||||
final Iterator<Subclass> iter = subclasses.iterator();
|
final Iterator<Subclass> iterator = subclasses.iterator();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while ( iter.hasNext() ) {
|
while ( iterator.hasNext() ) {
|
||||||
iters[i++] = iter.next().getSubclassIterator();
|
iterators[i++] = iterator.next().getSubclassIterator();
|
||||||
}
|
}
|
||||||
iters[i] = subclasses.iterator();
|
iterators[i] = subclasses.iterator();
|
||||||
return new JoinedIterator<>( iters );
|
return new JoinedIterator<>( iterators );
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PersistentClass> getSubclassClosure() {
|
public List<PersistentClass> getSubclassClosure() {
|
||||||
|
@ -275,12 +278,12 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
|
|
||||||
@Deprecated(since = "6.0") @Remove
|
@Deprecated(since = "6.0") @Remove
|
||||||
public Iterator<PersistentClass> getSubclassClosureIterator() {
|
public Iterator<PersistentClass> getSubclassClosureIterator() {
|
||||||
final ArrayList<Iterator<PersistentClass>> iters = new ArrayList<>();
|
final ArrayList<Iterator<PersistentClass>> iterators = new ArrayList<>();
|
||||||
iters.add( new SingletonIterator<>( this ) );
|
iterators.add( new SingletonIterator<>( this ) );
|
||||||
for ( Subclass subclass : getSubclasses() ) {
|
for ( Subclass subclass : getSubclasses() ) {
|
||||||
iters.add( subclass.getSubclassClosureIterator() );
|
iterators.add( subclass.getSubclassClosureIterator() );
|
||||||
}
|
}
|
||||||
return new JoinedIterator<>( iters );
|
return new JoinedIterator<>( iterators );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Table getIdentityTable() {
|
public Table getIdentityTable() {
|
||||||
|
@ -403,7 +406,7 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
final ArrayList<List<Property>> lists = new ArrayList<>();
|
final ArrayList<List<Property>> lists = new ArrayList<>();
|
||||||
lists.add( getPropertyClosure() );
|
lists.add( getPropertyClosure() );
|
||||||
lists.add( subclassProperties );
|
lists.add( subclassProperties );
|
||||||
for (Join join : subclassJoins) {
|
for ( Join join : subclassJoins ) {
|
||||||
lists.add( join.getProperties() );
|
lists.add( join.getProperties() );
|
||||||
}
|
}
|
||||||
return new JoinedList<>( lists );
|
return new JoinedList<>( lists );
|
||||||
|
@ -537,7 +540,7 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
try {
|
try {
|
||||||
return getRecursiveProperty( propertyPath, getReferenceableProperties() );
|
return getRecursiveProperty( propertyPath, getReferenceableProperties() );
|
||||||
}
|
}
|
||||||
catch (MappingException e) {
|
catch ( MappingException e ) {
|
||||||
throw new MappingException(
|
throw new MappingException(
|
||||||
"property-ref [" + propertyPath + "] not found on entity [" + getEntityName() + "]", e
|
"property-ref [" + propertyPath + "] not found on entity [" + getEntityName() + "]", e
|
||||||
);
|
);
|
||||||
|
@ -548,7 +551,7 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
try {
|
try {
|
||||||
return getRecursiveProperty( propertyPath, getPropertyClosure() );
|
return getRecursiveProperty( propertyPath, getPropertyClosure() );
|
||||||
}
|
}
|
||||||
catch (MappingException e) {
|
catch ( MappingException e ) {
|
||||||
throw new MappingException(
|
throw new MappingException(
|
||||||
"property [" + propertyPath + "] not found on entity [" + getEntityName() + "]", e
|
"property [" + propertyPath + "] not found on entity [" + getEntityName() + "]", e
|
||||||
);
|
);
|
||||||
|
@ -577,7 +580,7 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
// of the embedded composite identifier properties
|
// of the embedded composite identifier properties
|
||||||
property = identifierProperty;
|
property = identifierProperty;
|
||||||
}
|
}
|
||||||
catch (MappingException ignore) {
|
catch ( MappingException ignore ) {
|
||||||
// ignore it...
|
// ignore it...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -592,7 +595,7 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (MappingException e) {
|
catch ( MappingException e ) {
|
||||||
throw new MappingException( "property [" + propertyPath + "] not found on entity [" + getEntityName() + "]" );
|
throw new MappingException( "property [" + propertyPath + "] not found on entity [" + getEntityName() + "]" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,7 +603,7 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
}
|
}
|
||||||
|
|
||||||
private Property getProperty(String propertyName, List<Property> properties) throws MappingException {
|
private Property getProperty(String propertyName, List<Property> properties) throws MappingException {
|
||||||
String root = StringHelper.root( propertyName );
|
String root = root( propertyName );
|
||||||
for ( Property prop : properties ) {
|
for ( Property prop : properties ) {
|
||||||
if ( prop.getName().equals( root )
|
if ( prop.getName().equals( root )
|
||||||
|| ( prop instanceof Backref || prop instanceof IndexBackref )
|
|| ( prop instanceof Backref || prop instanceof IndexBackref )
|
||||||
|
@ -614,7 +617,7 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
public Property getProperty(String propertyName) throws MappingException {
|
public Property getProperty(String propertyName) throws MappingException {
|
||||||
Property identifierProperty = getIdentifierProperty();
|
Property identifierProperty = getIdentifierProperty();
|
||||||
if ( identifierProperty != null
|
if ( identifierProperty != null
|
||||||
&& identifierProperty.getName().equals( StringHelper.root( propertyName ) ) ) {
|
&& identifierProperty.getName().equals( root( propertyName ) ) ) {
|
||||||
return identifierProperty;
|
return identifierProperty;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -628,17 +631,16 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
}
|
}
|
||||||
|
|
||||||
public Property getSubclassProperty(String propertyName) throws MappingException {
|
public Property getSubclassProperty(String propertyName) throws MappingException {
|
||||||
Property identifierProperty = getIdentifierProperty();
|
final Property identifierProperty = getIdentifierProperty();
|
||||||
if ( identifierProperty != null
|
if ( identifierProperty != null
|
||||||
&& identifierProperty.getName().equals( StringHelper.root( propertyName ) ) ) {
|
&& identifierProperty.getName().equals( root( propertyName ) ) ) {
|
||||||
return identifierProperty;
|
return identifierProperty;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
List<Property> closure = getSubclassPropertyClosure();
|
final Component identifierMapper = getIdentifierMapper();
|
||||||
Component identifierMapper = getIdentifierMapper();
|
final List<Property> closure = identifierMapper != null
|
||||||
if ( identifierMapper != null ) {
|
? new JoinedList<>( identifierMapper.getProperties(), getSubclassPropertyClosure() )
|
||||||
closure = new JoinedList<>( identifierMapper.getProperties(), closure );
|
: getSubclassPropertyClosure();
|
||||||
}
|
|
||||||
return getProperty( propertyName, closure );
|
return getProperty( propertyName, closure );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -657,7 +659,7 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( Property property : getPropertyClosure() ) {
|
for ( Property property : getPropertyClosure() ) {
|
||||||
if (property.getName().equals(name)) {
|
if ( property.getName().equals(name) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -691,7 +693,7 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
public boolean isPropertyDefinedInHierarchy(String name) {
|
public boolean isPropertyDefinedInHierarchy(String name) {
|
||||||
return hasProperty( name )
|
return hasProperty( name )
|
||||||
|| getSuperMappedSuperclass() != null && getSuperMappedSuperclass().isPropertyDefinedInHierarchy( name )
|
|| getSuperMappedSuperclass() != null && getSuperMappedSuperclass().isPropertyDefinedInHierarchy( name )
|
||||||
||getSuperclass() != null && getSuperclass().isPropertyDefinedInHierarchy(name);
|
|| getSuperclass() != null && getSuperclass().isPropertyDefinedInHierarchy( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -721,9 +723,9 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
public void validate(Metadata mapping) throws MappingException {
|
public void validate(Metadata mapping) throws MappingException {
|
||||||
for ( Property prop : getProperties() ) {
|
for ( Property prop : getProperties() ) {
|
||||||
if ( !prop.isValid( mapping ) ) {
|
if ( !prop.isValid( mapping ) ) {
|
||||||
Type type = prop.getType();
|
final Type type = prop.getType();
|
||||||
int actualColumns = prop.getColumnSpan();
|
final int actualColumns = prop.getColumnSpan();
|
||||||
int requiredColumns = type.getColumnSpan(mapping);
|
final int requiredColumns = type.getColumnSpan(mapping);
|
||||||
throw new MappingException(
|
throw new MappingException(
|
||||||
"Property '" + StringHelper.qualify( getEntityName(), prop.getName() )
|
"Property '" + StringHelper.qualify( getEntityName(), prop.getName() )
|
||||||
+ "' maps to " + actualColumns + " columns but " + requiredColumns
|
+ "' maps to " + actualColumns + " columns but " + requiredColumns
|
||||||
|
@ -835,7 +837,7 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
public Iterator<Property> getPropertyIterator() {
|
public Iterator<Property> getPropertyIterator() {
|
||||||
final ArrayList<Iterator<Property>> iterators = new ArrayList<>();
|
final ArrayList<Iterator<Property>> iterators = new ArrayList<>();
|
||||||
iterators.add( properties.iterator() );
|
iterators.add( properties.iterator() );
|
||||||
for (Join join : joins) {
|
for ( Join join : joins ) {
|
||||||
iterators.add( join.getPropertyIterator() );
|
iterators.add( join.getPropertyIterator() );
|
||||||
}
|
}
|
||||||
return new JoinedIterator<>( iterators );
|
return new JoinedIterator<>( iterators );
|
||||||
|
@ -857,7 +859,7 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
public List<Property> getProperties() {
|
public List<Property> getProperties() {
|
||||||
final ArrayList<List<Property>> list = new ArrayList<>();
|
final ArrayList<List<Property>> list = new ArrayList<>();
|
||||||
list.add( properties );
|
list.add( properties );
|
||||||
for (Join join : joins) {
|
for ( Join join : joins ) {
|
||||||
list.add( join.getProperties() );
|
list.add( join.getProperties() );
|
||||||
}
|
}
|
||||||
return new JoinedList<>( list );
|
return new JoinedList<>( list );
|
||||||
|
@ -1043,10 +1045,10 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
protected void checkPropertyColumnDuplication(Set<String> distinctColumns, List<Property> properties)
|
protected void checkPropertyColumnDuplication(Set<String> distinctColumns, List<Property> properties)
|
||||||
throws MappingException {
|
throws MappingException {
|
||||||
for ( Property prop : properties ) {
|
for ( Property prop : properties ) {
|
||||||
Value value = prop.getValue();
|
final Value value = prop.getValue();
|
||||||
if ( value instanceof Component ) {
|
if ( value instanceof Component ) {
|
||||||
Component component = (Component) value;
|
final Component component = (Component) value;
|
||||||
AggregateColumn aggregateColumn = component.getAggregateColumn();
|
final AggregateColumn aggregateColumn = component.getAggregateColumn();
|
||||||
if ( aggregateColumn == null ) {
|
if ( aggregateColumn == null ) {
|
||||||
checkPropertyColumnDuplication( distinctColumns, component.getProperties() );
|
checkPropertyColumnDuplication( distinctColumns, component.getProperties() );
|
||||||
}
|
}
|
||||||
|
@ -1155,10 +1157,7 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
}
|
}
|
||||||
|
|
||||||
public java.util.List<CallbackDefinition> getCallbackDefinitions() {
|
public java.util.List<CallbackDefinition> getCallbackDefinitions() {
|
||||||
if ( callbackDefinitions == null ) {
|
return callbackDefinitions == null ? emptyList() : unmodifiableList( callbackDefinitions );
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
return Collections.unmodifiableList( callbackDefinitions );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIdentifierMapper(Component handle) {
|
public void setIdentifierMapper(Component handle) {
|
||||||
|
@ -1186,9 +1185,9 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
|
|
||||||
// The following methods are added to support @MappedSuperclass in the metamodel
|
// The following methods are added to support @MappedSuperclass in the metamodel
|
||||||
public List<Property> getDeclaredProperties() {
|
public List<Property> getDeclaredProperties() {
|
||||||
ArrayList<List<Property>> lists = new ArrayList<>();
|
final ArrayList<List<Property>> lists = new ArrayList<>();
|
||||||
lists.add( declaredProperties );
|
lists.add( declaredProperties );
|
||||||
for (Join join : joins) {
|
for ( Join join : joins ) {
|
||||||
lists.add( join.getDeclaredProperties() );
|
lists.add( join.getDeclaredProperties() );
|
||||||
}
|
}
|
||||||
return new JoinedList<>( lists );
|
return new JoinedList<>( lists );
|
||||||
|
@ -1196,9 +1195,9 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
|
||||||
|
|
||||||
@Deprecated(since = "6.0")
|
@Deprecated(since = "6.0")
|
||||||
public Iterator<Property> getDeclaredPropertyIterator() {
|
public Iterator<Property> getDeclaredPropertyIterator() {
|
||||||
ArrayList<Iterator<Property>> iterators = new ArrayList<>();
|
final ArrayList<Iterator<Property>> iterators = new ArrayList<>();
|
||||||
iterators.add( declaredProperties.iterator() );
|
iterators.add( declaredProperties.iterator() );
|
||||||
for (Join join : joins) {
|
for ( Join join : joins ) {
|
||||||
iterators.add( join.getDeclaredPropertyIterator() );
|
iterators.add( join.getDeclaredPropertyIterator() );
|
||||||
}
|
}
|
||||||
return new JoinedIterator<>( iterators );
|
return new JoinedIterator<>( iterators );
|
||||||
|
|
|
@ -18,10 +18,11 @@ import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
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.collections.SingletonIterator;
|
import org.hibernate.internal.util.collections.SingletonIterator;
|
||||||
import org.hibernate.persister.entity.EntityPersister;
|
import org.hibernate.persister.entity.EntityPersister;
|
||||||
|
|
||||||
|
import static org.hibernate.internal.util.StringHelper.nullIfEmpty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mapping model object that represents the root class in an entity class
|
* A mapping model object that represents the root class in an entity class
|
||||||
* {@linkplain jakarta.persistence.Inheritance inheritance} hierarchy.
|
* {@linkplain jakarta.persistence.Inheritance inheritance} hierarchy.
|
||||||
|
@ -294,11 +295,38 @@ public class RootClass extends PersistentClass implements TableOwner {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
checkCompositeIdentifier();
|
checkCompositeIdentifier();
|
||||||
|
checkTableDuplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkTableDuplication() {
|
||||||
|
if ( hasSubclasses() ) {
|
||||||
|
final Set<Table> tables = new HashSet<>();
|
||||||
|
tables.add( getTable() );
|
||||||
|
for ( Subclass subclass : getSubclasses() ) {
|
||||||
|
if ( !(subclass instanceof SingleTableSubclass) ) {
|
||||||
|
final Table table = subclass.getTable();
|
||||||
|
if ( !tables.add( table ) ) {
|
||||||
|
if ( getDiscriminator() == null ) {
|
||||||
|
throw new MappingException( "Two different subclasses of '" + getEntityName()
|
||||||
|
+ "' map to the table '" + table.getName()
|
||||||
|
+ "' and the hierarchy has no discriminator column" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// This is arguably not the right place to do this.
|
||||||
|
// Perhaps it's an issue better dealt with later on
|
||||||
|
// by the persisters.
|
||||||
|
forceDiscriminator = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkCompositeIdentifier() {
|
private void checkCompositeIdentifier() {
|
||||||
if ( getIdentifier() instanceof Component ) {
|
if ( getIdentifier() instanceof Component ) {
|
||||||
Component id = (Component) getIdentifier();
|
final Component id = (Component) getIdentifier();
|
||||||
if ( !id.isDynamic() ) {
|
if ( !id.isDynamic() ) {
|
||||||
final Class<?> idClass = id.getComponentClass();
|
final Class<?> idClass = id.getComponentClass();
|
||||||
if ( idClass != null ) {
|
if ( idClass != null ) {
|
||||||
|
@ -328,7 +356,7 @@ public class RootClass extends PersistentClass implements TableOwner {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCacheRegionName(String cacheRegionName) {
|
public void setCacheRegionName(String cacheRegionName) {
|
||||||
this.cacheRegionName = StringHelper.nullIfEmpty( cacheRegionName );
|
this.cacheRegionName = nullIfEmpty( cacheRegionName );
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLazyPropertiesCacheable() {
|
public boolean isLazyPropertiesCacheable() {
|
||||||
|
@ -359,7 +387,7 @@ public class RootClass extends PersistentClass implements TableOwner {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Table> getIdentityTables() {
|
public Set<Table> getIdentityTables() {
|
||||||
Set<Table> tables = new HashSet<>();
|
final Set<Table> tables = new HashSet<>();
|
||||||
for ( PersistentClass clazz : getSubclassClosure() ) {
|
for ( PersistentClass clazz : getSubclassClosure() ) {
|
||||||
if ( clazz.isAbstract() == null || !clazz.isAbstract() ) {
|
if ( clazz.isAbstract() == null || !clazz.isAbstract() ) {
|
||||||
tables.add( clazz.getIdentityTable() );
|
tables.add( clazz.getIdentityTable() );
|
||||||
|
|
|
@ -282,12 +282,14 @@ public class Subclass extends PersistentClass {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isClassOrSuperclassJoin(Join join) {
|
public boolean isClassOrSuperclassJoin(Join join) {
|
||||||
return super.isClassOrSuperclassJoin(join) || getSuperclass().isClassOrSuperclassJoin(join);
|
return super.isClassOrSuperclassJoin( join )
|
||||||
|
|| getSuperclass().isClassOrSuperclassJoin( join );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isClassOrSuperclassTable(Table table) {
|
public boolean isClassOrSuperclassTable(Table table) {
|
||||||
return super.isClassOrSuperclassTable(table) || getSuperclass().isClassOrSuperclassTable(table);
|
return super.isClassOrSuperclassTable( table )
|
||||||
|
|| getSuperclass().isClassOrSuperclassTable( table );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -307,8 +309,8 @@ public class Subclass extends PersistentClass {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public java.util.Set<String> getSynchronizedTables() {
|
public java.util.Set<String> getSynchronizedTables() {
|
||||||
HashSet<String> result = new HashSet<>();
|
final HashSet<String> result = new HashSet<>();
|
||||||
result.addAll(synchronizedTables);
|
result.addAll( synchronizedTables );
|
||||||
result.addAll( getSuperclass().getSynchronizedTables() );
|
result.addAll( getSuperclass().getSynchronizedTables() );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -320,15 +322,15 @@ public class Subclass extends PersistentClass {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public java.util.List<FilterConfiguration> getFilters() {
|
public java.util.List<FilterConfiguration> getFilters() {
|
||||||
java.util.List<FilterConfiguration> filters = new ArrayList<>(super.getFilters());
|
final ArrayList<FilterConfiguration> filters = new ArrayList<>( super.getFilters() );
|
||||||
filters.addAll(getSuperclass().getFilters());
|
filters.addAll( getSuperclass().getFilters() );
|
||||||
return filters;
|
return filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSubselectLoadableCollections() {
|
public boolean hasSubselectLoadableCollections() {
|
||||||
return super.hasSubselectLoadableCollections() ||
|
return super.hasSubselectLoadableCollections()
|
||||||
getSuperclass().hasSubselectLoadableCollections();
|
|| getSuperclass().hasSubselectLoadableCollections();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -7,9 +7,11 @@
|
||||||
package org.hibernate.mapping;
|
package org.hibernate.mapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Additional, optional contract as part pf the {@link PersistentClass}
|
* Optional contract implemented by some subtypes of {@link PersistentClass}.
|
||||||
* hierarchy used to differentiate entity bindings for entities that map to their own table
|
* <p>
|
||||||
* (root, union-subclass, joined-subclass) versus those that do not (discriminator-subclass).
|
* Differentiates entity types that map to their own table ({@link RootClass},
|
||||||
|
* {@link UnionSubclass}, and {@link JoinedSubclass}) from those which do not
|
||||||
|
* ({@link SingleTableSubclass}).
|
||||||
*
|
*
|
||||||
* @author Emmanuel Bernard
|
* @author Emmanuel Bernard
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class UnionSubclass extends Subclass implements TableOwner {
|
||||||
|
|
||||||
public void setTable(Table table) {
|
public void setTable(Table table) {
|
||||||
this.table = table;
|
this.table = table;
|
||||||
getSuperclass().addSubclassTable(table);
|
getSuperclass().addSubclassTable( table );
|
||||||
}
|
}
|
||||||
|
|
||||||
public java.util.Set<String> getSynchronizedTables() {
|
public java.util.Set<String> getSynchronizedTables() {
|
||||||
|
|
|
@ -14,7 +14,6 @@ import jakarta.persistence.PrimaryKeyJoinColumn;
|
||||||
import jakarta.persistence.Table;
|
import jakarta.persistence.Table;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.Transaction;
|
import org.hibernate.Transaction;
|
||||||
import org.hibernate.annotations.DiscriminatorOptions;
|
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -110,7 +109,6 @@ public class RepeatedSubclassTableTest extends BaseCoreFunctionalTestCase {
|
||||||
@Table(name = "DATA_TYPE")
|
@Table(name = "DATA_TYPE")
|
||||||
@Inheritance(strategy = JOINED)
|
@Inheritance(strategy = JOINED)
|
||||||
@DiscriminatorColumn(name = "supertype_id")
|
@DiscriminatorColumn(name = "supertype_id")
|
||||||
@DiscriminatorOptions(force = true)
|
|
||||||
public static abstract class DataType {
|
public static abstract class DataType {
|
||||||
|
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
|
@ -2,7 +2,6 @@ package org.hibernate.orm.test.inheritance.repeatedtable;
|
||||||
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.Transaction;
|
import org.hibernate.Transaction;
|
||||||
import org.hibernate.annotations.DiscriminatorOptions;
|
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
@ -101,7 +100,6 @@ public class RepeatedTableTest extends BaseCoreFunctionalTestCase {
|
||||||
@Table(name = "DATA_TYPE")
|
@Table(name = "DATA_TYPE")
|
||||||
@Inheritance(strategy = JOINED)
|
@Inheritance(strategy = JOINED)
|
||||||
@DiscriminatorColumn(name = "supertype_id")
|
@DiscriminatorColumn(name = "supertype_id")
|
||||||
@DiscriminatorOptions(force = true)
|
|
||||||
public static abstract class DataType {
|
public static abstract class DataType {
|
||||||
|
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
Loading…
Reference in New Issue