Update of /cvsroot/hibernate/Hibernate/cirrus/hibernate/persister In directory usw-pr-cvs1:/tmp/cvs-serv27523/hibernate/persister Modified Files: EntityPersister.java Loadable.java MultiTableEntityPersister.java Queryable.java Log Message: outerjoin fetching for normalized mappings Index: EntityPersister.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/persister/EntityPersister.java,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** EntityPersister.java 4 Nov 2002 08:10:51 -0000 1.35 --- EntityPersister.java 5 Nov 2002 03:44:01 -0000 1.36 *************** *** 25,28 **** --- 25,29 ---- import java.util.ArrayList; import java.util.HashMap; + import java.util.HashSet; import java.util.Iterator; import java.util.Map; *************** *** 70,73 **** --- 71,75 ---- private transient final int[] propertyColumnSpans; + private transient final boolean[] definedOnSubclass; private transient final String[][] propertyColumnNames; private transient final String[][] subclassPropertyColumnNameClosure; *************** *** 159,162 **** --- 161,168 ---- } + public boolean isDefinedOnSubclass(int i) { + return definedOnSubclass[i]; + } + public String[] getIdentifierColumnNames() { return identifierColumnNames; *************** *** 773,777 **** if ( model.isPolymorphic() ) { ! discriminatorColumnName = ( (Column) model.getDiscriminator().getColumnIterator().next() ).getName(); try { discriminatorType = (DiscriminatorType) model.getDiscriminator().getType(); --- 779,785 ---- if ( model.isPolymorphic() ) { ! Value d = model.getDiscriminator(); ! if (d==null) throw new MappingException("discriminator mapping required for polymorphic persistence"); ! discriminatorColumnName = ( (Column) d.getColumnIterator().next() ).getName(); try { discriminatorType = (DiscriminatorType) model.getDiscriminator().getType(); *************** *** 798,801 **** --- 806,810 ---- propertyColumnSpans = new int[hydrateSpan]; ArrayList columns = new ArrayList(); + HashSet thisClassProperties = new HashSet(); iter = model.getPropertyClosureIterator(); *************** *** 805,808 **** --- 814,818 ---- Property prop = (Property) iter.next(); propertyColumnSpans[i] = prop.getColumnSpan(); + thisClassProperties.add(prop); String[] colNames = new String[ propertyColumnSpans[i] ]; *************** *** 831,838 **** --- 841,850 ---- ArrayList propColumns = new ArrayList(); ArrayList joinedFetchesList = new ArrayList(); + ArrayList definedBySubclass = new ArrayList(); iter = model.getSubclassPropertyClosureIterator(); while ( iter.hasNext() ) { Property prop = (Property) iter.next(); + definedBySubclass.add( new Boolean( !thisClassProperties.contains(prop) ) ); Iterator colIter = prop.getColumnIterator(); String[] cols = new String[ prop.getColumnSpan() ]; *************** *** 852,859 **** --- 864,876 ---- subclassPropertyTypeClosure = (Type[]) types.toArray(TYPE_ARRAY); subclassPropertyColumnNameClosure = (String[][]) propColumns.toArray( new String[ propColumns.size() ][] ); + joinedFetch = new int[ joinedFetchesList.size() ]; iter = joinedFetchesList.iterator(); int j=0; while ( iter.hasNext() ) joinedFetch[j++] = ( (Integer) iter.next() ).intValue(); + definedOnSubclass = new boolean[ definedBySubclass.size() ]; + iter = definedBySubclass.iterator(); + j=0; + while ( iter.hasNext() ) definedOnSubclass[j++] = ( (Boolean) iter.next() ).booleanValue(); deleteString = generateDeleteString(); *************** *** 952,955 **** --- 969,976 ---- } + public String fromClauseFragment(String name, String on) { + return fromClauseFragment(name) + ' ' + on; + } + public String getQueryWhereClause(String name) throws MappingException { *************** *** 994,997 **** --- 1015,1022 ---- return StringHelper.prefix(cols, name + '.'); + } + + public String[] toColumns(String name, int i) { + return StringHelper.prefix( subclassPropertyColumnNameClosure[i], name + '.' ); } Index: Loadable.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/persister/Loadable.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** Loadable.java 4 Nov 2002 08:10:51 -0000 1.10 --- Loadable.java 5 Nov 2002 03:44:01 -0000 1.11 *************** *** 1,5 **** package cirrus.hibernate.persister; - import cirrus.hibernate.QueryException; import cirrus.hibernate.type.DiscriminatorType; import cirrus.hibernate.type.Type; --- 1,5 ---- + //$Id$ package cirrus.hibernate.persister; import cirrus.hibernate.type.DiscriminatorType; import cirrus.hibernate.type.Type; *************** *** 41,45 **** /** ! * Get the column names for the numbered property of this class */ public String[] getPropertyColumnNames(int i); --- 41,45 ---- /** ! * Get the column names for the numbered property of <em>this</em> class */ public String[] getPropertyColumnNames(int i); *************** *** 65,68 **** --- 65,73 ---- /** + * Is this property defined on a subclass of the mapped class? + */ + public boolean isDefinedOnSubclass(int i); + + /** * Get an array of the types of all properties of all subclasses * (optional operation) *************** *** 76,79 **** --- 81,89 ---- */ public String[] getSubclassPropertyColumnNames(int i); + /** + * Given the number of a property of a subclass, and a table alias, + * return the aliased column names + */ + public String[] toColumns(String name, int i); /** *************** *** 87,94 **** public String fromClauseFragment(String name); /** ! * Given a query alias and a property path, return the qualified ! * column name */ ! public String[] toColumns(String name, String property) throws QueryException; } --- 97,103 ---- public String fromClauseFragment(String name); /** ! * Get the from clause fragment, given a query alias and an ON clause */ ! public String fromClauseFragment(String name, String on); } Index: MultiTableEntityPersister.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/persister/MultiTableEntityPersister.java,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** MultiTableEntityPersister.java 4 Nov 2002 08:10:51 -0000 1.25 --- MultiTableEntityPersister.java 5 Nov 2002 03:44:01 -0000 1.26 *************** *** 24,27 **** --- 24,28 ---- import java.util.ArrayList; import java.util.HashMap; + import java.util.HashSet; import java.util.Iterator; import java.util.Map; *************** *** 80,84 **** --- 81,87 ---- private transient final String[][] propertyColumnNames; private transient final String[][] propertyColumnNameAliases; + private transient final boolean[] definedOnSubclass; private transient final String[][] subclassPropertyColumnNameClosure; + private transient final int[] subclassPropertyTableNumberClosure; private transient final String discriminatorColumnName; *************** *** 176,179 **** --- 179,186 ---- + public boolean isDefinedOnSubclass(int i) { + return definedOnSubclass[i]; + } + public String[] getIdentifierColumnNames() { return identifierColumnNames; *************** *** 684,688 **** if ( isVersioned() ) getVersionType().nullSafeSet( statements[0], version, identifierColumnNames.length + 1, session ); ! for ( int i=0; i<tableNames.length; i++ ) { // Do the key. The key is immutable so we can use the _current_ object state - not necessarily --- 691,695 ---- if ( isVersioned() ) getVersionType().nullSafeSet( statements[0], version, identifierColumnNames.length + 1, session ); ! for ( int i=tableNames.length-1; i>=0; i-- ) { // Do the key. The key is immutable so we can use the _current_ object state - not necessarily *************** *** 921,924 **** --- 928,932 ---- ArrayList columns = new ArrayList(); + HashSet thisClassProperties = new HashSet(); iter = model.getPropertyClosureIterator(); *************** *** 927,930 **** --- 935,939 ---- while( iter.hasNext() ) { Property prop = (Property) iter.next(); + thisClassProperties.add(prop); String tabname = prop.getValue().getTable().getQualifiedName( factory.getDefaultSchema() ); propertyTables[i] = getTableId(tabname, tableNames); *************** *** 962,978 **** ArrayList joinedFetchesList = new ArrayList(); ArrayList aliases = new ArrayList(); iter = model.getSubclassPropertyClosureIterator(); while ( iter.hasNext() ) { Property prop = (Property) iter.next(); Iterator colIter = prop.getColumnIterator(); String tabname = prop.getValue().getTable().getQualifiedName( factory.getDefaultSchema() ); String[] cols = new String[ prop.getColumnSpan() ]; types.add( prop.getType() ); int l=0; while ( colIter.hasNext() ) { Column col = (Column) colIter.next(); columns.add( col.getName() ); ! coltables.add( new Integer( getTableId(tabname, subclassTableNameClosure) ) ); cols[l++]=col.getName(); aliases.add( columnAlias(col) ); --- 971,992 ---- ArrayList joinedFetchesList = new ArrayList(); ArrayList aliases = new ArrayList(); + ArrayList propTables = new ArrayList(); + ArrayList definedBySubclass = new ArrayList(); iter = model.getSubclassPropertyClosureIterator(); while ( iter.hasNext() ) { Property prop = (Property) iter.next(); + definedBySubclass.add( new Boolean( !thisClassProperties.contains(prop) ) ); Iterator colIter = prop.getColumnIterator(); String tabname = prop.getValue().getTable().getQualifiedName( factory.getDefaultSchema() ); String[] cols = new String[ prop.getColumnSpan() ]; types.add( prop.getType() ); + Integer tabnum = new Integer( getTableId(tabname, subclassTableNameClosure) ); + propTables.add(tabnum); int l=0; while ( colIter.hasNext() ) { Column col = (Column) colIter.next(); columns.add( col.getName() ); ! coltables.add(tabnum); cols[l++]=col.getName(); aliases.add( columnAlias(col) ); *************** *** 987,995 **** --- 1001,1016 ---- subclassColumnTableNumberClosure = ArrayHelper.toIntArray(coltables); subclassPropertyTypeClosure = (Type[]) types.toArray(TYPE_ARRAY); + subclassPropertyTableNumberClosure = ArrayHelper.toIntArray(propTables); + subclassPropertyColumnNameClosure = (String[][]) propColumns.toArray( new String[ propColumns.size() ][] ); + joinedFetch = new int[ joinedFetchesList.size() ]; iter = joinedFetchesList.iterator(); int j=0; while ( iter.hasNext() ) joinedFetch[j++] = ( (Integer) iter.next() ).intValue(); + definedOnSubclass = new boolean[ definedBySubclass.size() ]; + iter = definedBySubclass.iterator(); + j=0; + while ( iter.hasNext() ) definedOnSubclass[j++] = ( (Boolean) iter.next() ).booleanValue(); deleteStrings = generateDeleteStrings(); *************** *** 1109,1117 **** public String fromClauseFragment(String name) { String[] tables = subclassTableNameClosure; StringBuffer buf = new StringBuffer(100); buf.append( tables[0] ) .append(' ') ! .append(name); for ( int i=1; i<tables.length; i++ ) { buf.append(" left outer join ") --- 1130,1144 ---- public String fromClauseFragment(String name) { + return fromClauseFragment(name, ""); + } + + public String fromClauseFragment(String name, String on) { String[] tables = subclassTableNameClosure; StringBuffer buf = new StringBuffer(100); buf.append( tables[0] ) .append(' ') ! .append(name) ! .append(' ') ! .append(on); for ( int i=1; i<tables.length; i++ ) { buf.append(" left outer join ") *************** *** 1185,1188 **** --- 1212,1221 ---- return StringHelper.prefix( cols, name + ( (tab==0) ? "" : Integer.toString(tab) ) + '.' ); } + + public String[] toColumns(String name, int i) { + int tab = subclassPropertyTableNumberClosure[i]; + return StringHelper.prefix( subclassPropertyColumnNameClosure[i], name + ( (tab==0) ? "" : Integer.toString(tab) ) + '.' ); + } + public String propertySelectClauseFragment(String name, String suffix) { Index: Queryable.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/persister/Queryable.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Queryable.java 4 Nov 2002 08:10:52 -0000 1.5 --- Queryable.java 5 Nov 2002 03:44:02 -0000 1.6 *************** *** 3,6 **** --- 3,7 ---- import cirrus.hibernate.MappingException; + import cirrus.hibernate.QueryException; import cirrus.hibernate.type.Type; *************** *** 37,39 **** --- 38,45 ---- */ public String selectIdentifierString(String name, String suffix); + /** + * Given a query alias and a property path, return the qualified + * column name + */ + public String[] toColumns(String name, String property) throws QueryException; } |