KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > persister > collection > BasicCollectionPersister


1 //$Id: BasicCollectionPersister.java,v 1.16 2005/06/22 04:19:33 oneovthafew Exp $
2
package org.hibernate.persister.collection;
3
4 import java.io.Serializable JavaDoc;
5 import java.sql.CallableStatement JavaDoc;
6 import java.sql.PreparedStatement JavaDoc;
7 import java.sql.SQLException JavaDoc;
8 import java.sql.Types JavaDoc;
9 import java.util.Iterator JavaDoc;
10
11 import org.hibernate.HibernateException;
12 import org.hibernate.MappingException;
13 import org.hibernate.type.AssociationType;
14 import org.hibernate.persister.entity.Joinable;
15 import org.hibernate.cache.CacheConcurrencyStrategy;
16 import org.hibernate.cache.CacheException;
17 import org.hibernate.cfg.Configuration;
18 import org.hibernate.collection.PersistentCollection;
19 import org.hibernate.engine.SessionFactoryImplementor;
20 import org.hibernate.engine.SessionImplementor;
21 import org.hibernate.engine.SubselectFetch;
22 import org.hibernate.exception.JDBCExceptionHelper;
23 import org.hibernate.loader.collection.BatchingCollectionInitializer;
24 import org.hibernate.loader.collection.CollectionInitializer;
25 import org.hibernate.loader.collection.SubselectCollectionLoader;
26 import org.hibernate.mapping.Collection;
27 import org.hibernate.pretty.MessageHelper;
28 import org.hibernate.sql.Delete;
29 import org.hibernate.sql.Insert;
30 import org.hibernate.sql.Update;
31 import org.hibernate.sql.SelectFragment;
32 import org.hibernate.util.ArrayHelper;
33
34 /**
35  * Collection persister for collections of values and many-to-many associations.
36  *
37  * @author Gavin King
38  */

39 public class BasicCollectionPersister extends AbstractCollectionPersister {
40
41     public boolean isCascadeDeleteEnabled() {
42         return false;
43     }
44
45     public BasicCollectionPersister(Collection collection,
46                                     CacheConcurrencyStrategy cache,
47                                     Configuration cfg,
48                                     SessionFactoryImplementor factory)
49             throws MappingException, CacheException {
50         super( collection, cache, cfg, factory );
51     }
52
53     /**
54      * Generate the SQL DELETE that deletes all rows
55      */

56     protected String JavaDoc generateDeleteString() {
57         
58         Delete delete = new Delete()
59                 .setTableName( qualifiedTableName )
60                 .setPrimaryKeyColumnNames( keyColumnNames );
61         
62         if ( hasWhere ) delete.setWhere( sqlWhereString );
63         
64         if ( getFactory().getSettings().isCommentsEnabled() ) {
65             delete.setComment( "delete collection " + getRole() );
66         }
67         
68         return delete.toStatementString();
69     }
70
71     /**
72      * Generate the SQL INSERT that creates a new row
73      */

74     protected String JavaDoc generateInsertRowString() {
75         
76         Insert insert = new Insert( null )
77                 .setTableName( qualifiedTableName )
78                 .addColumns( keyColumnNames );
79         
80         if ( hasIdentifier) insert.addColumn( identifierColumnName );
81         
82         if ( hasIndex /*&& !indexIsFormula*/ ) {
83             insert.addColumns( indexColumnNames, indexColumnIsSettable );
84         }
85         
86         if ( getFactory().getSettings().isCommentsEnabled() ) {
87             insert.setComment( "insert collection row " + getRole() );
88         }
89         
90         //if ( !elementIsFormula ) {
91
insert.addColumns( elementColumnNames, elementColumnIsSettable );
92         //}
93

94         return insert.toStatementString();
95     }
96
97     /**
98      * Generate the SQL UPDATE that updates a row
99      */

100     protected String JavaDoc generateUpdateRowString() {
101         
102         Update update = new Update()
103             .setTableName( qualifiedTableName );
104         
105         //if ( !elementIsFormula ) {
106
update.addColumns( elementColumnNames, elementColumnIsSettable );
107         //}
108

109         if ( hasIdentifier ) {
110             update.setPrimaryKeyColumnNames( new String JavaDoc[]{ identifierColumnName } );
111         }
112         else if ( hasIndex && !indexContainsFormula ) {
113             update.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, indexColumnNames ) );
114         }
115         else {
116             update.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, elementColumnNames, elementColumnIsInPrimaryKey ) );
117         }
118         
119         if ( getFactory().getSettings().isCommentsEnabled() ) {
120             update.setComment( "update collection row " + getRole() );
121         }
122         
123         return update.toStatementString();
124     }
125
126     /**
127      * Generate the SQL DELETE that deletes a particular row
128      */

129     protected String JavaDoc generateDeleteRowString() {
130         
131         Delete delete = new Delete()
132             .setTableName( qualifiedTableName );
133         
134         if ( hasIdentifier ) {
135             delete.setPrimaryKeyColumnNames( new String JavaDoc[]{ identifierColumnName } );
136         }
137         else if ( hasIndex && !indexContainsFormula ) {
138             delete.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, indexColumnNames ) );
139         }
140         else {
141             delete.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, elementColumnNames, elementColumnIsInPrimaryKey ) );
142         }
143         
144         if ( getFactory().getSettings().isCommentsEnabled() ) {
145             delete.setComment( "delete collection row " + getRole() );
146         }
147         
148         return delete.toStatementString();
149     }
150
151     public boolean consumesEntityAlias() {
152         return false;
153     }
154
155     public boolean consumesCollectionAlias() {
156 // return !isOneToMany();
157
return true;
158     }
159
160     public boolean isOneToMany() {
161         return false;
162     }
163
164     public boolean isManyToMany() {
165         return elementType.isEntityType(); //instanceof AssociationType;
166
}
167
168     protected int doUpdateRows(Serializable JavaDoc id, PersistentCollection collection, SessionImplementor session)
169             throws HibernateException {
170         
171         if ( ArrayHelper.isAllFalse(elementColumnIsSettable) ) return 0;
172
173         try {
174             PreparedStatement JavaDoc st = null;
175             boolean callable = isUpdateCallable();
176             Iterator JavaDoc entries = collection.entries(this);
177             try {
178                 int i = 0;
179                 int count = 0;
180                 while ( entries.hasNext() ) {
181                     int offset = 1;
182                     Object JavaDoc entry = entries.next();
183                     if ( collection.needsUpdating( entry, i, elementType ) ) {
184                         if ( st == null ) {
185                             if ( callable ) {
186                                 CallableStatement JavaDoc callstatement = session.getBatcher()
187                                         .prepareBatchCallableStatement( getSQLUpdateRowString() );
188                                 callstatement.registerOutParameter( offset++, Types.NUMERIC ); // TODO: should we require users to return number of update rows ? (we cant make it return this without changing collectionpersister interface)
189
st = callstatement;
190                             }
191                             else {
192                                 st = session.getBatcher().prepareBatchStatement( getSQLUpdateRowString() );
193                             }
194                         }
195                         
196                         int loc = writeElement(st, collection.getElement(entry), offset, session );
197                         if ( hasIdentifier ) {
198                             loc = writeIdentifier(st, collection.getIdentifier(entry, i), loc, session);
199                         }
200                         else {
201                             loc = writeKey( st, id, loc, session );
202                             if ( hasIndex && !indexContainsFormula ) {
203                                 loc = writeIndexToWhere( st, collection.getIndex(entry, i, this), loc, session );
204                             }
205                             else {
206                                 loc = writeElementToWhere( st, collection.getSnapshotElement(entry, i), loc, session );
207                             }
208                         }
209                         session.getBatcher().addToBatch( 1 );
210                         count++;
211                     }
212                     i++;
213                 }
214                 return count;
215             }
216             catch ( SQLException JavaDoc sqle ) {
217                 session.getBatcher().abortBatch( sqle );
218                 throw sqle;
219             }
220         }
221         catch ( SQLException JavaDoc sqle ) {
222             throw JDBCExceptionHelper.convert(
223                     getSQLExceptionConverter(),
224                     sqle,
225                     "could not update collection rows: " + MessageHelper.collectionInfoString( this, id, getFactory() ),
226                     getSQLUpdateRowString()
227                 );
228         }
229     }
230
231     public String JavaDoc selectFragment(
232             Joinable rhs,
233             String JavaDoc rhsAlias,
234             String JavaDoc lhsAlias,
235             String JavaDoc entitySuffix,
236             String JavaDoc collectionSuffix,
237             boolean includeCollectionColumns) {
238         // we need to determine the best way to know that two joinables
239
// represent a single many-to-many...
240
if ( rhs != null && isManyToMany() && !rhs.isCollection() ) {
241             AssociationType elementType = ( ( AssociationType ) getElementType() );
242             if ( rhs.equals( elementType.getAssociatedJoinable( getFactory() ) ) ) {
243                 return manyToManySelectFragment( rhs, rhsAlias, lhsAlias, collectionSuffix );
244             }
245         }
246         return includeCollectionColumns ? selectFragment( lhsAlias, collectionSuffix ) : "";
247     }
248
249     private String JavaDoc manyToManySelectFragment(
250             Joinable rhs,
251             String JavaDoc rhsAlias,
252             String JavaDoc lhsAlias,
253             String JavaDoc collectionSuffix) {
254         SelectFragment frag = generateSelectFragment( lhsAlias, collectionSuffix );
255
256         String JavaDoc[] elementColumnNames = rhs.getKeyColumnNames();
257         frag.addColumns( rhsAlias, elementColumnNames, elementColumnAliases );
258         appendIndexColumns( frag, lhsAlias );
259         appendIdentifierColumns( frag, lhsAlias );
260
261         return frag.toFragmentString()
262                 .substring( 2 ); //strip leading ','
263
}
264
265     /**
266      * Create the <tt>CollectionLoader</tt>
267      *
268      * @see org.hibernate.loader.collection.BasicCollectionLoader
269      */

270     protected CollectionInitializer createCollectionInitializer(java.util.Map JavaDoc enabledFilters)
271             throws MappingException {
272         return BatchingCollectionInitializer.createBatchingCollectionInitializer( this, batchSize, getFactory(), enabledFilters );
273     }
274
275     public String JavaDoc fromJoinFragment(String JavaDoc alias, boolean innerJoin, boolean includeSubclasses) {
276         return "";
277     }
278
279     public String JavaDoc whereJoinFragment(String JavaDoc alias, boolean innerJoin, boolean includeSubclasses) {
280         return "";
281     }
282
283     protected CollectionInitializer createSubselectInitializer(SubselectFetch subselect, SessionImplementor session) {
284         return new SubselectCollectionLoader( this,
285                 subselect.toSubselectString( getCollectionType().getLHSPropertyName() ),
286                 subselect.getResult(),
287                 subselect.getQueryParameters(),
288                 session.getFactory(),
289                 session.getEnabledFilters() );
290     }
291
292 }
293
Popular Tags