Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » mapping » [javadoc | source]
    1   /*
    2    * Hibernate, Relational Persistence for Idiomatic Java
    3    *
    4    * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
    5    * indicated by the @author tags or express copyright attribution
    6    * statements applied by the authors.  All third-party contributions are
    7    * distributed under license by Red Hat Middleware LLC.
    8    *
    9    * This copyrighted material is made available to anyone wishing to use, modify,
   10    * copy, or redistribute it subject to the terms and conditions of the GNU
   11    * Lesser General Public License, as published by the Free Software Foundation.
   12    *
   13    * This program is distributed in the hope that it will be useful,
   14    * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   15    * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   16    * for more details.
   17    *
   18    * You should have received a copy of the GNU Lesser General Public License
   19    * along with this distribution; if not, write to:
   20    * Free Software Foundation, Inc.
   21    * 51 Franklin Street, Fifth Floor
   22    * Boston, MA  02110-1301  USA
   23    *
   24    */
   25   package org.hibernate.mapping;
   26   
   27   import java.io.Serializable;
   28   import java.util;
   29   import java.util.Set;
   30   
   31   import org.hibernate.MappingException;
   32   import org.hibernate.EntityMode;
   33   import org.hibernate.dialect.Dialect;
   34   import org.hibernate.engine.Mapping;
   35   import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
   36   import org.hibernate.sql.Alias;
   37   import org.hibernate.util.EmptyIterator;
   38   import org.hibernate.util.JoinedIterator;
   39   import org.hibernate.util.ReflectHelper;
   40   import org.hibernate.util.SingletonIterator;
   41   import org.hibernate.util.StringHelper;
   42   
   43   /**
   44    * Mapping for an entity.
   45    *
   46    * @author Gavin King
   47    */
   48   public abstract class PersistentClass implements Serializable, Filterable, MetaAttributable {
   49   
   50   	private static final Alias PK_ALIAS = new Alias(15, "PK");
   51   
   52   	public static final String NULL_DISCRIMINATOR_MAPPING = "null";
   53   	public static final String NOT_NULL_DISCRIMINATOR_MAPPING = "not null";
   54   
   55   	private String entityName;
   56   
   57   	private String className;
   58   	private String proxyInterfaceName;
   59   	
   60   	private String nodeName;
   61   
   62   	private String discriminatorValue;
   63   	private boolean lazy;
   64   	private ArrayList properties = new ArrayList();
   65   	private final ArrayList subclasses = new ArrayList();
   66   	private final ArrayList subclassProperties = new ArrayList();
   67   	private final ArrayList subclassTables = new ArrayList();
   68   	private boolean dynamicInsert;
   69   	private boolean dynamicUpdate;
   70   	private int batchSize=-1;
   71   	private boolean selectBeforeUpdate;
   72   	private java.util.Map metaAttributes;
   73   	private ArrayList joins = new ArrayList();
   74   	private final ArrayList subclassJoins = new ArrayList();
   75   	private final java.util.Map filters = new HashMap();
   76   	protected final java.util.Set synchronizedTables = new HashSet();
   77   	private String loaderName;
   78   	private Boolean isAbstract;
   79   	private boolean hasSubselectLoadableCollections;
   80   	private Component identifierMapper;
   81   
   82   	// Custom SQL
   83   	private String customSQLInsert;
   84   	private boolean customInsertCallable;
   85   	private ExecuteUpdateResultCheckStyle insertCheckStyle;
   86   	private String customSQLUpdate;
   87   	private boolean customUpdateCallable;
   88   	private ExecuteUpdateResultCheckStyle updateCheckStyle;
   89   	private String customSQLDelete;
   90   	private boolean customDeleteCallable;
   91   	private ExecuteUpdateResultCheckStyle deleteCheckStyle;
   92   
   93   	private String temporaryIdTableName;
   94   	private String temporaryIdTableDDL;
   95   
   96   	private java.util.Map tuplizerImpls;
   97   
   98   	protected int optimisticLockMode;
   99   
  100   	public String getClassName() {
  101   		return className;
  102   	}
  103   
  104   	public void setClassName(String className) {
  105   		this.className = className==null ? null : className.intern();
  106   	}
  107   
  108   	public String getProxyInterfaceName() {
  109   		return proxyInterfaceName;
  110   	}
  111   
  112   	public void setProxyInterfaceName(String proxyInterfaceName) {
  113   		this.proxyInterfaceName = proxyInterfaceName;
  114   	}
  115   
  116   	public Class getMappedClass() throws MappingException {
  117   		if (className==null) return null;
  118   		try {
  119   			return ReflectHelper.classForName(className);
  120   		}
  121   		catch (ClassNotFoundException cnfe) {
  122   			throw new MappingException("entity class not found: " + className, cnfe);
  123   		}
  124   	}
  125   
  126   	public Class getProxyInterface() {
  127   		if (proxyInterfaceName==null) return null;
  128   		try {
  129   			return ReflectHelper.classForName(proxyInterfaceName);
  130   		}
  131   		catch (ClassNotFoundException cnfe) {
  132   			throw new MappingException("proxy class not found: " + proxyInterfaceName, cnfe);
  133   		}
  134   	}
  135   	public boolean useDynamicInsert() {
  136   		return dynamicInsert;
  137   	}
  138   
  139   	abstract int nextSubclassId();
  140   	public abstract int getSubclassId();
  141   	
  142   	public boolean useDynamicUpdate() {
  143   		return dynamicUpdate;
  144   	}
  145   
  146   	public void setDynamicInsert(boolean dynamicInsert) {
  147   		this.dynamicInsert = dynamicInsert;
  148   	}
  149   
  150   	public void setDynamicUpdate(boolean dynamicUpdate) {
  151   		this.dynamicUpdate = dynamicUpdate;
  152   	}
  153   
  154   
  155   	public String getDiscriminatorValue() {
  156   		return discriminatorValue;
  157   	}
  158   
  159   	public void addSubclass(Subclass subclass) throws MappingException {
  160   		// inheritance cycle detection (paranoid check)
  161   		PersistentClass superclass = getSuperclass();
  162   		while (superclass!=null) {
  163   			if( subclass.getEntityName().equals( superclass.getEntityName() ) ) {
  164   				throw new MappingException(
  165   					"Circular inheritance mapping detected: " +
  166   					subclass.getEntityName() +
  167   					" will have it self as superclass when extending " +
  168   					getEntityName()
  169   				);
  170   			}
  171   			superclass = superclass.getSuperclass();
  172   		}
  173   		subclasses.add(subclass);
  174   	}
  175   
  176   	public boolean hasSubclasses() {
  177   		return subclasses.size() > 0;
  178   	}
  179   
  180   	public int getSubclassSpan() {
  181   		int n = subclasses.size();
  182   		Iterator iter = subclasses.iterator();
  183   		while ( iter.hasNext() ) {
  184   			n += ( (Subclass) iter.next() ).getSubclassSpan();
  185   		}
  186   		return n;
  187   	}
  188   	/**
  189   	 * Iterate over subclasses in a special 'order', most derived subclasses
  190   	 * first.
  191   	 */
  192   	public Iterator getSubclassIterator() {
  193   		Iterator[] iters = new Iterator[ subclasses.size() + 1 ];
  194   		Iterator iter = subclasses.iterator();
  195   		int i=0;
  196   		while ( iter.hasNext() ) {
  197   			iters[i++] = ( (Subclass) iter.next() ).getSubclassIterator();
  198   		}
  199   		iters[i] = subclasses.iterator();
  200   		return new JoinedIterator(iters);
  201   	}
  202   
  203   	public Iterator getSubclassClosureIterator() {
  204   		ArrayList iters = new ArrayList();
  205   		iters.add( new SingletonIterator(this) );
  206   		Iterator iter = getSubclassIterator();
  207   		while ( iter.hasNext() ) {
  208   			PersistentClass clazz = (PersistentClass)  iter.next();
  209   			iters.add( clazz.getSubclassClosureIterator() );
  210   		}
  211   		return new JoinedIterator(iters);
  212   	}
  213   	
  214   	public Table getIdentityTable() {
  215   		return getRootTable();
  216   	}
  217   	
  218   	public Iterator getDirectSubclasses() {
  219   		return subclasses.iterator();
  220   	}
  221   
  222   	public void addProperty(Property p) {
  223   		properties.add(p);
  224   		p.setPersistentClass(this);
  225   	}
  226   
  227   	public abstract Table getTable();
  228   
  229   	public String getEntityName() {
  230   		return entityName;
  231   	}
  232   
  233   	public abstract boolean isMutable();
  234   	public abstract boolean hasIdentifierProperty();
  235   	public abstract Property getIdentifierProperty();
  236   	public abstract KeyValue getIdentifier();
  237   	public abstract Property getVersion();
  238   	public abstract Value getDiscriminator();
  239   	public abstract boolean isInherited();
  240   	public abstract boolean isPolymorphic();
  241   	public abstract boolean isVersioned();
  242   	public abstract String getCacheConcurrencyStrategy();
  243   	public abstract PersistentClass getSuperclass();
  244   	public abstract boolean isExplicitPolymorphism();
  245   	public abstract boolean isDiscriminatorInsertable();
  246   
  247   	public abstract Iterator getPropertyClosureIterator();
  248   	public abstract Iterator getTableClosureIterator();
  249   	public abstract Iterator getKeyClosureIterator();
  250   
  251   	protected void addSubclassProperty(Property prop) {
  252   		subclassProperties.add(prop);
  253   	}
  254   	protected void addSubclassJoin(Join join) {
  255   		subclassJoins.add(join);
  256   	}
  257   	protected void addSubclassTable(Table subclassTable) {
  258   		subclassTables.add(subclassTable);
  259   	}
  260   	public Iterator getSubclassPropertyClosureIterator() {
  261   		ArrayList iters = new ArrayList();
  262   		iters.add( getPropertyClosureIterator() );
  263   		iters.add( subclassProperties.iterator() );
  264   		for ( int i=0; i<subclassJoins.size(); i++ ) {
  265   			Join join = (Join) subclassJoins.get(i);
  266   			iters.add( join.getPropertyIterator() );
  267   		}
  268   		return new JoinedIterator(iters);
  269   	}
  270   	public Iterator getSubclassJoinClosureIterator() {
  271   		return new JoinedIterator( getJoinClosureIterator(), subclassJoins.iterator() );
  272   	}
  273   	public Iterator getSubclassTableClosureIterator() {
  274   		return new JoinedIterator( getTableClosureIterator(), subclassTables.iterator() );
  275   	}
  276   
  277   	public boolean isClassOrSuperclassJoin(Join join) {
  278   		return joins.contains(join);
  279   	}
  280   
  281   	public boolean isClassOrSuperclassTable(Table closureTable) {
  282   		return getTable()==closureTable;
  283   	}
  284   
  285   	public boolean isLazy() {
  286   		return lazy;
  287   	}
  288   
  289   	public void setLazy(boolean lazy) {
  290   		this.lazy = lazy;
  291   	}
  292   
  293   	public abstract boolean hasEmbeddedIdentifier();
  294   	public abstract Class getEntityPersisterClass();
  295   	public abstract void setEntityPersisterClass(Class classPersisterClass);
  296   	public abstract Table getRootTable();
  297   	public abstract RootClass getRootClass();
  298   	public abstract KeyValue getKey();
  299   
  300   	public void setDiscriminatorValue(String discriminatorValue) {
  301   		this.discriminatorValue = discriminatorValue;
  302   	}
  303   
  304   	public void setEntityName(String entityName) {
  305   		this.entityName = entityName==null ? null : entityName.intern();
  306   	}
  307   
  308   	public void createPrimaryKey() {
  309   		//Primary key constraint
  310   		PrimaryKey pk = new PrimaryKey();
  311   		Table table = getTable();
  312   		pk.setTable(table);
  313   		pk.setName( PK_ALIAS.toAliasString( table.getName() ) );
  314   		table.setPrimaryKey(pk);
  315   
  316   		pk.addColumns( getKey().getColumnIterator() );
  317   	}
  318   
  319   	public abstract String getWhere();
  320   
  321   	public int getBatchSize() {
  322   		return batchSize;
  323   	}
  324   
  325   	public void setBatchSize(int batchSize) {
  326   		this.batchSize = batchSize;
  327   	}
  328   
  329   	public boolean hasSelectBeforeUpdate() {
  330   		return selectBeforeUpdate;
  331   	}
  332   
  333   	public void setSelectBeforeUpdate(boolean selectBeforeUpdate) {
  334   		this.selectBeforeUpdate = selectBeforeUpdate;
  335   	}
  336   
  337   	/**
  338   	 * Build an iterator of properties which are "referenceable".
  339   	 *
  340   	 * @see #getReferencedProperty for a discussion of "referenceable"
  341   	 * @return The property iterator.
  342   	 */
  343   	public Iterator getReferenceablePropertyIterator() {
  344   		return getPropertyClosureIterator();
  345   	}
  346   
  347   	/**
  348   	 * Given a property path, locate the appropriate referenceable property reference.
  349   	 * <p/>
  350   	 * A referenceable property is a property  which can be a target of a foreign-key
  351   	 * mapping (an identifier or explcitly named in a property-ref).
  352   	 *
  353   	 * @param propertyPath The property path to resolve into a property reference.
  354   	 * @return The property reference (never null).
  355   	 * @throws MappingException If the property could not be found.
  356   	 */
  357   	public Property getReferencedProperty(String propertyPath) throws MappingException {
  358   		try {
  359   			return getRecursiveProperty( propertyPath, getReferenceablePropertyIterator() );
  360   		}
  361   		catch ( MappingException e ) {
  362   			throw new MappingException(
  363   					"property-ref [" + propertyPath + "] not found on entity [" + getEntityName() + "]", e
  364   			);
  365   		}
  366   	}
  367   
  368   	public Property getRecursiveProperty(String propertyPath) throws MappingException {
  369   		try {
  370   			return getRecursiveProperty( propertyPath, getPropertyIterator() );
  371   		}
  372   		catch ( MappingException e ) {
  373   			throw new MappingException(
  374   					"property [" + propertyPath + "] not found on entity [" + getEntityName() + "]", e
  375   			);
  376   		}
  377   	}
  378   
  379   	private Property getRecursiveProperty(String propertyPath, Iterator iter) throws MappingException {
  380   		Property property = null;
  381   		StringTokenizer st = new StringTokenizer( propertyPath, ".", false );
  382   		try {
  383   			while ( st.hasMoreElements() ) {
  384   				final String element = ( String ) st.nextElement();
  385   				if ( property == null ) {
  386   					Property identifierProperty = getIdentifierProperty();
  387   					if ( identifierProperty != null && identifierProperty.getName().equals( element ) ) {
  388   						// we have a mapped identifier property and the root of
  389   						// the incoming property path matched that identifier
  390   						// property
  391   						property = identifierProperty;
  392   					}
  393   					else if ( identifierProperty == null && getIdentifierMapper() != null ) {
  394   						// we have an embedded composite identifier
  395   						try {
  396   							identifierProperty = getProperty( element, getIdentifierMapper().getPropertyIterator() );
  397   							if ( identifierProperty != null ) {
  398   								// the root of the incoming property path matched one
  399   								// of the embedded composite identifier properties
  400   								property = identifierProperty;
  401   							}
  402   						}
  403   						catch( MappingException ignore ) {
  404   							// ignore it...
  405   						}
  406   					}
  407   
  408   					if ( property == null ) {
  409   						property = getProperty( element, iter );
  410   					}
  411   				}
  412   				else {
  413   					//flat recursive algorithm
  414   					property = ( ( Component ) property.getValue() ).getProperty( element );
  415   				}
  416   			}
  417   		}
  418   		catch ( MappingException e ) {
  419   			throw new MappingException( "property [" + propertyPath + "] not found on entity [" + getEntityName() + "]" );
  420   		}
  421   
  422   		return property;
  423   	}
  424   
  425   	private Property getProperty(String propertyName, Iterator iterator) throws MappingException {
  426   		while ( iterator.hasNext() ) {
  427   			Property prop = (Property) iterator.next();
  428   			if ( prop.getName().equals( StringHelper.root(propertyName) ) ) {
  429   				return prop;
  430   			}
  431   		}
  432   		throw new MappingException( "property [" + propertyName + "] not found on entity [" + getEntityName() + "]" );
  433   	}
  434   
  435   	public Property getProperty(String propertyName) throws MappingException {
  436   		Iterator iter = getPropertyClosureIterator();
  437   		Property identifierProperty = getIdentifierProperty();
  438   		if ( identifierProperty != null
  439   				&& identifierProperty.getName().equals( StringHelper.root(propertyName) )
  440   				) {
  441   			return identifierProperty;
  442   		}
  443   		else {
  444   			return getProperty( propertyName, iter );
  445   		}
  446   	}
  447   
  448   	abstract public int getOptimisticLockMode();
  449   
  450   	public void setOptimisticLockMode(int optimisticLockMode) {
  451   		this.optimisticLockMode = optimisticLockMode;
  452   	}
  453   
  454   	public void validate(Mapping mapping) throws MappingException {
  455   		Iterator iter = getPropertyIterator();
  456   		while ( iter.hasNext() ) {
  457   			Property prop = (Property) iter.next();
  458   			if ( !prop.isValid(mapping) ) {
  459   				throw new MappingException(
  460   						"property mapping has wrong number of columns: " +
  461   						StringHelper.qualify( getEntityName(), prop.getName() ) +
  462   						" type: " +
  463   						prop.getType().getName()
  464   					);
  465   			}
  466   		}
  467   		checkPropertyDuplication();
  468   		checkColumnDuplication();
  469   	}
  470   	
  471   	private void checkPropertyDuplication() throws MappingException {
  472   		HashSet names = new HashSet();
  473   		Iterator iter = getPropertyIterator();
  474   		while ( iter.hasNext() ) {
  475   			Property prop = (Property) iter.next();
  476   			if ( !names.add( prop.getName() ) ) {
  477   				throw new MappingException( "Duplicate property mapping of " + prop.getName() + " found in " + getEntityName());
  478   			}
  479   		}
  480   	}
  481   
  482   	public boolean isDiscriminatorValueNotNull() {
  483   		return NOT_NULL_DISCRIMINATOR_MAPPING.equals( getDiscriminatorValue() );
  484   	}
  485   	public boolean isDiscriminatorValueNull() {
  486   		return NULL_DISCRIMINATOR_MAPPING.equals( getDiscriminatorValue() );
  487   	}
  488   
  489   	public java.util.Map getMetaAttributes() {
  490   		return metaAttributes;
  491   	}
  492   
  493   	public void setMetaAttributes(java.util.Map metas) {
  494   		this.metaAttributes = metas;
  495   	}
  496   
  497   	public MetaAttribute getMetaAttribute(String name) {
  498   		return metaAttributes==null?null:(MetaAttribute) metaAttributes.get(name);
  499   	}
  500   
  501   	public String toString() {
  502   		return getClass().getName() + '(' + getEntityName() + ')';
  503   	}
  504   	
  505   	public Iterator getJoinIterator() {
  506   		return joins.iterator();
  507   	}
  508   
  509   	public Iterator getJoinClosureIterator() {
  510   		return joins.iterator();
  511   	}
  512   
  513   	public void addJoin(Join join) {
  514   		joins.add(join);
  515   		join.setPersistentClass(this);
  516   	}
  517   
  518   	public int getJoinClosureSpan() {
  519   		return joins.size();
  520   	}
  521   
  522   	public int getPropertyClosureSpan() {
  523   		int span = properties.size();
  524   		for ( int i=0; i<joins.size(); i++ ) {
  525   			Join join = (Join) joins.get(i);
  526   			span += join.getPropertySpan();
  527   		}
  528   		return span;
  529   	}
  530   
  531   	public int getJoinNumber(Property prop) {
  532   		int result=1;
  533   		Iterator iter = getSubclassJoinClosureIterator();
  534   		while ( iter.hasNext() ) {
  535   			Join join = (Join) iter.next();
  536   			if ( join.containsProperty(prop) ) return result;
  537   			result++;
  538   		}
  539   		return 0;
  540   	}
  541   
  542   	/**
  543   	 * Build an iterator over the properties defined on this class.  The returned
  544   	 * iterator only accounts for "normal" properties (i.e. non-identifier
  545   	 * properties).
  546   	 * <p/>
  547   	 * Differs from {@link #getUnjoinedPropertyIterator} in that the iterator
  548   	 * we return here will include properties defined as part of a join.
  549   	 *
  550   	 * @return An iterator over the "normal" properties.
  551   	 */
  552   	public Iterator getPropertyIterator() {
  553   		ArrayList iterators = new ArrayList();
  554   		iterators.add( properties.iterator() );
  555   		for ( int i = 0; i < joins.size(); i++ ) {
  556   			Join join = ( Join ) joins.get( i );
  557   			iterators.add( join.getPropertyIterator() );
  558   		}
  559   		return new JoinedIterator( iterators );
  560   	}
  561   
  562   	/**
  563   	 * Build an iterator over the properties defined on this class <b>which
  564   	 * are not defined as part of a join</b>.  As with {@link #getPropertyIterator},
  565   	 * the returned iterator only accounts for non-identifier properties.
  566   	 *
  567   	 * @return An iterator over the non-joined "normal" properties.
  568   	 */
  569   	public Iterator getUnjoinedPropertyIterator() {
  570   		return properties.iterator();
  571   	}
  572   
  573   	public void setCustomSQLInsert(String customSQLInsert, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
  574   		this.customSQLInsert = customSQLInsert;
  575   		this.customInsertCallable = callable;
  576   		this.insertCheckStyle = checkStyle;
  577   	}
  578   
  579   	public String getCustomSQLInsert() {
  580   		return customSQLInsert;
  581   	}
  582   
  583   	public boolean isCustomInsertCallable() {
  584   		return customInsertCallable;
  585   	}
  586   
  587   	public ExecuteUpdateResultCheckStyle getCustomSQLInsertCheckStyle() {
  588   		return insertCheckStyle;
  589   	}
  590   
  591   	public void setCustomSQLUpdate(String customSQLUpdate, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
  592   		this.customSQLUpdate = customSQLUpdate;
  593   		this.customUpdateCallable = callable;
  594   		this.updateCheckStyle = checkStyle;
  595   	}
  596   
  597   	public String getCustomSQLUpdate() {
  598   		return customSQLUpdate;
  599   	}
  600   
  601   	public boolean isCustomUpdateCallable() {
  602   		return customUpdateCallable;
  603   	}
  604   
  605   	public ExecuteUpdateResultCheckStyle getCustomSQLUpdateCheckStyle() {
  606   		return updateCheckStyle;
  607   	}
  608   
  609   	public void setCustomSQLDelete(String customSQLDelete, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
  610   		this.customSQLDelete = customSQLDelete;
  611   		this.customDeleteCallable = callable;
  612   		this.deleteCheckStyle = checkStyle;
  613   	}
  614   
  615   	public String getCustomSQLDelete() {
  616   		return customSQLDelete;
  617   	}
  618   
  619   	public boolean isCustomDeleteCallable() {
  620   		return customDeleteCallable;
  621   	}
  622   
  623   	public ExecuteUpdateResultCheckStyle getCustomSQLDeleteCheckStyle() {
  624   		return deleteCheckStyle;
  625   	}
  626   
  627   	public void addFilter(String name, String condition) {
  628   		filters.put(name, condition);
  629   	}
  630   
  631   	public java.util.Map getFilterMap() {
  632   		return filters;
  633   	}
  634   
  635   	public boolean isForceDiscriminator() {
  636   		return false;
  637   	}
  638   
  639   	public abstract boolean isJoinedSubclass();
  640   
  641   	public String getLoaderName() {
  642   		return loaderName;
  643   	}
  644   
  645   	public void setLoaderName(String loaderName) {
  646   		this.loaderName = loaderName==null ? null : loaderName.intern();
  647   	}
  648   
  649   	public abstract java.util.Set getSynchronizedTables();
  650   	
  651   	public void addSynchronizedTable(String table) {
  652   		synchronizedTables.add(table);
  653   	}
  654   
  655   	public Boolean isAbstract() {
  656   		return isAbstract;
  657   	}
  658   
  659   	public void setAbstract(Boolean isAbstract) {
  660   		this.isAbstract = isAbstract;
  661   	}
  662   
  663   	protected void checkColumnDuplication(Set distinctColumns, Iterator columns) 
  664   	throws MappingException {
  665   		while ( columns.hasNext() ) {
  666   			Selectable columnOrFormula = (Selectable) columns.next();
  667   			if ( !columnOrFormula.isFormula() ) {
  668   				Column col = (Column) columnOrFormula;
  669   				if ( !distinctColumns.add( col.getName() ) ) {
  670   					throw new MappingException( 
  671   							"Repeated column in mapping for entity: " +
  672   							getEntityName() +
  673   							" column: " +
  674   							col.getName() + 
  675   							" (should be mapped with insert=\"false\" update=\"false\")"
  676   						);
  677   				}
  678   			}
  679   		}
  680   	}
  681   	
  682   	protected void checkPropertyColumnDuplication(Set distinctColumns, Iterator properties) 
  683   	throws MappingException {
  684   		while ( properties.hasNext() ) {
  685   			Property prop = (Property) properties.next();
  686   			if ( prop.getValue() instanceof Component ) { //TODO: remove use of instanceof!
  687   				Component component = (Component) prop.getValue();
  688   				checkPropertyColumnDuplication( distinctColumns, component.getPropertyIterator() );
  689   			}
  690   			else {
  691   				if ( prop.isUpdateable() || prop.isInsertable() ) {
  692   					checkColumnDuplication( distinctColumns, prop.getColumnIterator() );
  693   				}
  694   			}
  695   		}
  696   	}
  697   	
  698   	protected Iterator getNonDuplicatedPropertyIterator() {
  699   		return getUnjoinedPropertyIterator();
  700   	}
  701   	
  702   	protected Iterator getDiscriminatorColumnIterator() {
  703   		return EmptyIterator.INSTANCE;
  704   	}
  705   	
  706   	protected void checkColumnDuplication() {
  707   		HashSet cols = new HashSet();
  708   		if (getIdentifierMapper() == null ) {
  709   			//an identifier mapper => getKey will be included in the getNonDuplicatedPropertyIterator()
  710   			//and checked later, so it needs to be excluded
  711   			checkColumnDuplication( cols, getKey().getColumnIterator() );
  712   		}
  713   		checkColumnDuplication( cols, getDiscriminatorColumnIterator() );
  714   		checkPropertyColumnDuplication( cols, getNonDuplicatedPropertyIterator() );
  715   		Iterator iter = getJoinIterator();
  716   		while ( iter.hasNext() ) {
  717   			cols.clear();
  718   			Join join = (Join) iter.next();
  719   			checkColumnDuplication( cols, join.getKey().getColumnIterator() );
  720   			checkPropertyColumnDuplication( cols, join.getPropertyIterator() );
  721   		}
  722   	}
  723   	
  724   	public abstract Object accept(PersistentClassVisitor mv);
  725   	
  726   	public String getNodeName() {
  727   		return nodeName;
  728   	}
  729   	
  730   	public void setNodeName(String nodeName) {
  731   		this.nodeName = nodeName;
  732   	}
  733   	
  734   	public boolean hasPojoRepresentation() {
  735   		return getClassName()!=null;
  736   	}
  737   
  738   	public boolean hasDom4jRepresentation() {
  739   		return getNodeName()!=null;
  740   	}
  741   
  742   	public boolean hasSubselectLoadableCollections() {
  743   		return hasSubselectLoadableCollections;
  744   	}
  745   	
  746   	public void setSubselectLoadableCollections(boolean hasSubselectCollections) {
  747   		this.hasSubselectLoadableCollections = hasSubselectCollections;
  748   	}
  749   
  750   	public void prepareTemporaryTables(Mapping mapping, Dialect dialect) {
  751   		if ( dialect.supportsTemporaryTables() ) {
  752   			temporaryIdTableName = dialect.generateTemporaryTableName( getTable().getName() );
  753   			Table table = new Table();
  754   			table.setName( temporaryIdTableName );
  755   			Iterator itr = getTable().getPrimaryKey().getColumnIterator();
  756   			while( itr.hasNext() ) {
  757   				Column column = (Column) itr.next();
  758   				table.addColumn( (Column) column.clone()  );
  759   			}
  760   			temporaryIdTableDDL = table.sqlTemporaryTableCreateString( dialect, mapping );
  761   		}
  762   	}
  763   
  764   	public String getTemporaryIdTableName() {
  765   		return temporaryIdTableName;
  766   	}
  767   
  768   	public String getTemporaryIdTableDDL() {
  769   		return temporaryIdTableDDL;
  770   	}
  771   
  772   	public Component getIdentifierMapper() {
  773   		return identifierMapper;
  774   	}
  775   
  776   	public boolean hasIdentifierMapper() {
  777   		return identifierMapper != null;
  778   	}
  779   
  780   	public void setIdentifierMapper(Component handle) {
  781   		this.identifierMapper = handle;
  782   	}
  783   
  784   	public void addTuplizer(EntityMode entityMode, String implClassName) {
  785   		if ( tuplizerImpls == null ) {
  786   			tuplizerImpls = new HashMap();
  787   		}
  788   		tuplizerImpls.put( entityMode, implClassName );
  789   	}
  790   
  791   	public String getTuplizerImplClassName(EntityMode mode) {
  792   		if ( tuplizerImpls == null ) return null;
  793   		return ( String ) tuplizerImpls.get( mode );
  794   	}
  795   
  796   	public java.util.Map getTuplizerMap() {
  797   		if ( tuplizerImpls == null ) {
  798   			return null;
  799   		}
  800   		return java.util.Collections.unmodifiableMap( tuplizerImpls );
  801   	}
  802   
  803   	public boolean hasNaturalId() {
  804   		Iterator props = getRootClass().getPropertyIterator();
  805   		while ( props.hasNext() ) {
  806   			if ( ( (Property) props.next() ).isNaturalIdentifier() ) {
  807   				return true;
  808   			}
  809   		}
  810   		return false;
  811   	}
  812   
  813   	public abstract boolean isLazyPropertiesCacheable();
  814   }

Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » mapping » [javadoc | source]