KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hibernate > hql > ast > exec > MultiTableDeleteExecutor


1 // $Id: MultiTableDeleteExecutor.java,v 1.1 2005/07/12 20:27:16 steveebersole Exp $
2
package org.hibernate.hql.ast.exec;
3
4 import java.sql.PreparedStatement JavaDoc;
5 import java.sql.SQLException JavaDoc;
6 import java.util.Iterator JavaDoc;
7
8 import org.hibernate.HibernateException;
9 import org.hibernate.engine.QueryParameters;
10 import org.hibernate.engine.SessionImplementor;
11 import org.hibernate.exception.JDBCExceptionHelper;
12 import org.hibernate.hql.ast.HqlSqlWalker;
13 import org.hibernate.hql.ast.tree.DeleteStatement;
14 import org.hibernate.hql.ast.tree.FromElement;
15 import org.hibernate.param.ParameterSpecification;
16 import org.hibernate.persister.entity.Queryable;
17 import org.hibernate.sql.Delete;
18 import org.hibernate.util.StringHelper;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22
23 /**
24  * Implementation of MultiTableDeleteExecutor.
25  *
26  * @author Steve Ebersole
27  */

28 public class MultiTableDeleteExecutor extends AbstractStatementExecutor {
29     private static final Log log = LogFactory.getLog( MultiTableDeleteExecutor.class );
30
31     private final DeleteStatement deleteStatement;
32     private final Queryable persister;
33     private final String JavaDoc idInsertSelect;
34     private final String JavaDoc[] deletes;
35
36     public MultiTableDeleteExecutor(HqlSqlWalker walker) {
37         super( walker, log );
38
39         this.deleteStatement = ( DeleteStatement ) walker.getAST();
40
41         FromElement fromElement = deleteStatement.getFromClause().getFromElement();
42         this.persister = fromElement.getQueryable();
43
44         this.idInsertSelect = generateIdInsertSelect( persister, ( ( DeleteStatement ) walker.getAST() ).getWhereClause() );
45         log.trace( "Generated ID-INSERT-SELECT SQL (multi-table delete) : " + idInsertSelect );
46
47         String JavaDoc[] tableNames = persister.getConstraintOrderedTableNameClosure();
48         String JavaDoc[][] columnNames = persister.getContraintOrderedTableKeyColumnClosure();
49         String JavaDoc idSubselect = generateIdSubselect( persister );
50
51         deletes = new String JavaDoc[tableNames.length];
52         for ( int i = tableNames.length - 1; i >= 0; i-- ) {
53             // TODO : an optimization here would be to consider cascade deletes and not gen those delete statements;
54
// the difficulty is the ordering of the tables here vs the cascade attributes on the persisters ->
55
// the table info gotten here should really be self-contained (i.e., a class representation
56
// defining all the needed attributes), then we could then get an array of those
57
final Delete delete = new Delete()
58                     .setTableName( tableNames[i] )
59                     .setWhere( "(" + StringHelper.join( ", ", columnNames[i] ) + ") IN (" + idSubselect + ")" );
60             if ( getFactory().getSettings().isCommentsEnabled() && getFactory().getDialect().supportsCommentOn() ) {
61                 delete.setComment( "bulk delete" );
62             }
63
64             deletes[i] = delete.toStatementString();
65         }
66     }
67
68     public int execute(QueryParameters parameters, SessionImplementor session) throws HibernateException {
69         coordinateSharedCacheCleanup( session );
70
71         createTemporaryTableIfNecessary( persister, session );
72
73         try {
74             // First, save off the pertinent ids, saving the number of pertinent ids for return
75
PreparedStatement JavaDoc ps = null;
76             int resultCount = 0;
77             try {
78                 try {
79                     ps = session.getBatcher().prepareStatement( idInsertSelect );
80                     Iterator JavaDoc paramSpecifications = getWalker().getParameters().iterator();
81                     int pos = 1;
82                     while ( paramSpecifications.hasNext() ) {
83                         final ParameterSpecification paramSpec = ( ParameterSpecification ) paramSpecifications.next();
84                         pos += paramSpec.bind( ps, parameters, session, pos );
85                     }
86                     resultCount = ps.executeUpdate();
87                 }
88                 finally {
89                     if ( ps != null ) {
90                         session.getBatcher().closeStatement( ps );
91                     }
92                 }
93             }
94             catch( SQLException JavaDoc e ) {
95                 throw JDBCExceptionHelper.convert(
96                         getFactory().getSQLExceptionConverter(),
97                         e,
98                         "could not insert/select ids for bulk delete",
99                         idInsertSelect
100                     );
101             }
102
103             // Start performing the deletes
104
for ( int i = 0; i < deletes.length; i++ ) {
105                 try {
106                     try {
107                         ps = session.getBatcher().prepareStatement( deletes[i] );
108                         ps.executeUpdate();
109                     }
110                     finally {
111                         if ( ps != null ) {
112                             session.getBatcher().closeStatement( ps );
113                         }
114                     }
115                 }
116                 catch( SQLException JavaDoc e ) {
117                     throw JDBCExceptionHelper.convert(
118                             getFactory().getSQLExceptionConverter(),
119                             e,
120                             "error performing bulk delete",
121                             deletes[i]
122                         );
123                 }
124             }
125
126             return resultCount;
127         }
128         finally {
129             dropTemporaryTableIfNecessary( persister, session );
130         }
131     }
132
133     protected Queryable[] getAffectedQueryables() {
134         return new Queryable[] { persister };
135     }
136 }
137
Popular Tags