/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.mapping;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.collections.SingletonIterator;
import org.jboss.logging.Logger;
The root class of an inheritance hierarchy
Author: Gavin King
/**
* The root class of an inheritance hierarchy
* @author Gavin King
*/
public class RootClass extends PersistentClass implements TableOwner {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, RootClass.class.getName());
public static final String DEFAULT_IDENTIFIER_COLUMN_NAME = "id";
public static final String DEFAULT_DISCRIMINATOR_COLUMN_NAME = "class";
private Property identifierProperty;
private KeyValue identifier;
private Property version;
private boolean polymorphic;
private String cacheConcurrencyStrategy;
private String cacheRegionName;
private String naturalIdCacheRegionName;
private boolean lazyPropertiesCacheable = true;
private Value discriminator;
private boolean mutable = true;
private boolean embeddedIdentifier;
private boolean explicitPolymorphism;
private Class entityPersisterClass;
private boolean forceDiscriminator;
private String where;
private Table table;
private boolean discriminatorInsertable = true;
private int nextSubclassId;
private Property declaredIdentifierProperty;
private Property declaredVersion;
@Override
int nextSubclassId() {
return ++nextSubclassId;
}
@Override
public int getSubclassId() {
return 0;
}
public void setTable(Table table) {
this.table=table;
}
@Override
public Table getTable() {
return table;
}
@Override
public Property getIdentifierProperty() {
return identifierProperty;
}
@Override
public Property getDeclaredIdentifierProperty() {
return declaredIdentifierProperty;
}
public void setDeclaredIdentifierProperty(Property declaredIdentifierProperty) {
this.declaredIdentifierProperty = declaredIdentifierProperty;
}
@Override
public KeyValue getIdentifier() {
return identifier;
}
@Override
public boolean hasIdentifierProperty() {
return identifierProperty!=null;
}
@Override
public Value getDiscriminator() {
return discriminator;
}
@Override
public boolean isInherited() {
return false;
}
@Override
public boolean isPolymorphic() {
return polymorphic;
}
public void setPolymorphic(boolean polymorphic) {
this.polymorphic = polymorphic;
}
@Override
public RootClass getRootClass() {
return this;
}
@Override
public Iterator getPropertyClosureIterator() {
return getPropertyIterator();
}
@Override
public Iterator getTableClosureIterator() {
return new SingletonIterator( getTable() );
}
@Override
public Iterator getKeyClosureIterator() {
return new SingletonIterator( getKey() );
}
@Override
public void addSubclass(Subclass subclass) throws MappingException {
super.addSubclass(subclass);
setPolymorphic(true);
}
@Override
public boolean isExplicitPolymorphism() {
return explicitPolymorphism;
}
@Override
public Property getVersion() {
return version;
}
@Override
public Property getDeclaredVersion() {
return declaredVersion;
}
public void setDeclaredVersion(Property declaredVersion) {
this.declaredVersion = declaredVersion;
}
public void setVersion(Property version) {
this.version = version;
}
@Override
public boolean isVersioned() {
return version!=null;
}
@Override
public boolean isMutable() {
return mutable;
}
@Override
public boolean hasEmbeddedIdentifier() {
return embeddedIdentifier;
}
@Override
public Class getEntityPersisterClass() {
return entityPersisterClass;
}
@Override
public Table getRootTable() {
return getTable();
}
@Override
public void setEntityPersisterClass(Class persister) {
this.entityPersisterClass = persister;
}
@Override
public PersistentClass getSuperclass() {
return null;
}
@Override
public KeyValue getKey() {
return getIdentifier();
}
public void setDiscriminator(Value discriminator) {
this.discriminator = discriminator;
}
public void setEmbeddedIdentifier(boolean embeddedIdentifier) {
this.embeddedIdentifier = embeddedIdentifier;
}
public void setExplicitPolymorphism(boolean explicitPolymorphism) {
this.explicitPolymorphism = explicitPolymorphism;
}
public void setIdentifier(KeyValue identifier) {
this.identifier = identifier;
}
public void setIdentifierProperty(Property identifierProperty) {
this.identifierProperty = identifierProperty;
identifierProperty.setPersistentClass(this);
}
public void setMutable(boolean mutable) {
this.mutable = mutable;
}
@Override
public boolean isDiscriminatorInsertable() {
return discriminatorInsertable;
}
public void setDiscriminatorInsertable(boolean insertable) {
this.discriminatorInsertable = insertable;
}
@Override
public boolean isForceDiscriminator() {
return forceDiscriminator;
}
public void setForceDiscriminator(boolean forceDiscriminator) {
this.forceDiscriminator = forceDiscriminator;
}
@Override
public String getWhere() {
return where;
}
public void setWhere(String string) {
where = string;
}
@Override
public void validate(Mapping mapping) throws MappingException {
super.validate(mapping);
if ( !getIdentifier().isValid(mapping) ) {
throw new MappingException(
"identifier mapping has wrong number of columns: " +
getEntityName() +
" type: " +
getIdentifier().getType().getName()
);
}
checkCompositeIdentifier();
}
private void checkCompositeIdentifier() {
if ( getIdentifier() instanceof Component ) {
Component id = (Component) getIdentifier();
if ( !id.isDynamic() ) {
final Class idClass = id.getComponentClass();
final String idComponendClassName = idClass.getName();
if (idClass != null && !ReflectHelper.overridesEquals(idClass)) LOG.compositeIdClassDoesNotOverrideEquals( idComponendClassName );
if (!ReflectHelper.overridesHashCode(idClass)) LOG.compositeIdClassDoesNotOverrideHashCode( idComponendClassName );
if (!Serializable.class.isAssignableFrom(idClass)) throw new MappingException(
"Composite-id class must implement Serializable: "
+ idComponendClassName);
}
}
}
@Override
public String getCacheConcurrencyStrategy() {
return cacheConcurrencyStrategy;
}
public void setCacheConcurrencyStrategy(String cacheConcurrencyStrategy) {
this.cacheConcurrencyStrategy = cacheConcurrencyStrategy;
}
public String getCacheRegionName() {
return cacheRegionName==null ? getEntityName() : cacheRegionName;
}
public void setCacheRegionName(String cacheRegionName) {
this.cacheRegionName = cacheRegionName;
}
@Override
public String getNaturalIdCacheRegionName() {
return naturalIdCacheRegionName;
}
public void setNaturalIdCacheRegionName(String naturalIdCacheRegionName) {
this.naturalIdCacheRegionName = naturalIdCacheRegionName;
}
@Override
public boolean isLazyPropertiesCacheable() {
return lazyPropertiesCacheable;
}
public void setLazyPropertiesCacheable(boolean lazyPropertiesCacheable) {
this.lazyPropertiesCacheable = lazyPropertiesCacheable;
}
@Override
public boolean isJoinedSubclass() {
return false;
}
@Override
public java.util.Set getSynchronizedTables() {
return synchronizedTables;
}
public Set getIdentityTables() {
Set tables = new HashSet();
Iterator iter = getSubclassClosureIterator();
while ( iter.hasNext() ) {
PersistentClass clazz = (PersistentClass) iter.next();
if ( clazz.isAbstract() == null || !clazz.isAbstract().booleanValue() ) tables.add( clazz.getIdentityTable() );
}
return tables;
}
@Override
public Object accept(PersistentClassVisitor mv) {
return mv.accept(this);
}
}