1 package org.hibernate.persister.collection; 3 4 import java.io.Serializable ; 5 import java.sql.CallableStatement ; 6 import java.sql.PreparedStatement ; 7 import java.sql.SQLException ; 8 import java.sql.Types ; 9 import java.util.Iterator ; 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 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 56 protected String 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 74 protected String 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 ) { 83 insert.addColumns( indexColumnNames, indexColumnIsSettable ); 84 } 85 86 if ( getFactory().getSettings().isCommentsEnabled() ) { 87 insert.setComment( "insert collection row " + getRole() ); 88 } 89 90 insert.addColumns( elementColumnNames, elementColumnIsSettable ); 92 94 return insert.toStatementString(); 95 } 96 97 100 protected String generateUpdateRowString() { 101 102 Update update = new Update() 103 .setTableName( qualifiedTableName ); 104 105 update.addColumns( elementColumnNames, elementColumnIsSettable ); 107 109 if ( hasIdentifier ) { 110 update.setPrimaryKeyColumnNames( new String []{ 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 129 protected String generateDeleteRowString() { 130 131 Delete delete = new Delete() 132 .setTableName( qualifiedTableName ); 133 134 if ( hasIdentifier ) { 135 delete.setPrimaryKeyColumnNames( new String []{ 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 true; 158 } 159 160 public boolean isOneToMany() { 161 return false; 162 } 163 164 public boolean isManyToMany() { 165 return elementType.isEntityType(); } 167 168 protected int doUpdateRows(Serializable id, PersistentCollection collection, SessionImplementor session) 169 throws HibernateException { 170 171 if ( ArrayHelper.isAllFalse(elementColumnIsSettable) ) return 0; 172 173 try { 174 PreparedStatement st = null; 175 boolean callable = isUpdateCallable(); 176 Iterator entries = collection.entries(this); 177 try { 178 int i = 0; 179 int count = 0; 180 while ( entries.hasNext() ) { 181 int offset = 1; 182 Object entry = entries.next(); 183 if ( collection.needsUpdating( entry, i, elementType ) ) { 184 if ( st == null ) { 185 if ( callable ) { 186 CallableStatement callstatement = session.getBatcher() 187 .prepareBatchCallableStatement( getSQLUpdateRowString() ); 188 callstatement.registerOutParameter( offset++, Types.NUMERIC ); 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 sqle ) { 217 session.getBatcher().abortBatch( sqle ); 218 throw sqle; 219 } 220 } 221 catch ( SQLException 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 selectFragment( 232 Joinable rhs, 233 String rhsAlias, 234 String lhsAlias, 235 String entitySuffix, 236 String collectionSuffix, 237 boolean includeCollectionColumns) { 238 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 manyToManySelectFragment( 250 Joinable rhs, 251 String rhsAlias, 252 String lhsAlias, 253 String collectionSuffix) { 254 SelectFragment frag = generateSelectFragment( lhsAlias, collectionSuffix ); 255 256 String [] 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 ); } 264 265 270 protected CollectionInitializer createCollectionInitializer(java.util.Map enabledFilters) 271 throws MappingException { 272 return BatchingCollectionInitializer.createBatchingCollectionInitializer( this, batchSize, getFactory(), enabledFilters ); 273 } 274 275 public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) { 276 return ""; 277 } 278 279 public String whereJoinFragment(String 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 |