KickJava   Java API By Example, From Geeks To Geeks.

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


1 // $Id: MultiTableUpdateExecutor.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.ArrayList JavaDoc;
7 import java.util.Iterator JavaDoc;
8 import java.util.List JavaDoc;
9
10 import org.hibernate.HibernateException;
11 import org.hibernate.engine.QueryParameters;
12 import org.hibernate.engine.SessionImplementor;
13 import org.hibernate.exception.JDBCExceptionHelper;
14 import org.hibernate.hql.ast.HqlSqlWalker;
15 import org.hibernate.hql.ast.tree.AssignmentSpecification;
16 import org.hibernate.hql.ast.tree.FromElement;
17 import org.hibernate.hql.ast.tree.UpdateStatement;
18 import org.hibernate.param.ParameterSpecification;
19 import org.hibernate.persister.entity.Queryable;
20 import org.hibernate.sql.Update;
21 import org.hibernate.util.StringHelper;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25
26 /**
27  * Implementation of MultiTableUpdateExecutor.
28  *
29  * @author Steve Ebersole
30  */

31 public class MultiTableUpdateExecutor extends AbstractStatementExecutor {
32     private static final Log log = LogFactory.getLog( MultiTableUpdateExecutor.class );
33
34     private final UpdateStatement updateStatement;
35     private final Queryable persister;
36     private final String JavaDoc idInsertSelect;
37     private final String JavaDoc[] updates;
38     private final ParameterSpecification[][] hqlParameters;
39
40     public MultiTableUpdateExecutor(HqlSqlWalker walker) {
41         super( walker, log );
42
43         this.updateStatement = ( UpdateStatement ) walker.getAST();
44         FromElement fromElement = updateStatement.getFromClause().getFromElement();
45         this.persister = fromElement.getQueryable();
46
47         this.idInsertSelect = generateIdInsertSelect( persister, updateStatement.getWhereClause() );
48         log.trace( "Generated ID-INSERT-SELECT SQL (multi-table update) : " + idInsertSelect );
49
50         String JavaDoc[] tableNames = persister.getConstraintOrderedTableNameClosure();
51         String JavaDoc[][] columnNames = persister.getContraintOrderedTableKeyColumnClosure();
52
53         String JavaDoc idSubselect = generateIdSubselect( persister );
54         List JavaDoc assignmentSpecifications = walker.getAssignmentSpecifications();
55
56         Iterator JavaDoc itr = null;
57         updates = new String JavaDoc[tableNames.length];
58         hqlParameters = new ParameterSpecification[tableNames.length][];
59         for ( int tableIndex = 0; tableIndex < tableNames.length; tableIndex++ ) {
60             boolean affected = false;
61             List JavaDoc parameterList = new ArrayList JavaDoc();
62             Update update = new Update()
63                     .setTableName( tableNames[tableIndex] )
64                     .setWhere( "(" + StringHelper.join( ", ", columnNames[tableIndex] ) + ") IN (" + idSubselect + ")" );
65             if ( getFactory().getSettings().isCommentsEnabled() && getFactory().getDialect().supportsCommentOn() ) {
66                 update.setComment( "bulk update" );
67             }
68             itr = assignmentSpecifications.iterator();
69             while ( itr.hasNext() ) {
70                 final AssignmentSpecification specification = ( AssignmentSpecification ) itr.next();
71                 if ( specification.affectsTable( tableNames[tableIndex] ) ) {
72                     affected = true;
73                     update.appendAssignmentFragment( specification.getSqlAssignmentFragment() );
74                     if ( specification.getParameters() != null ) {
75                         for ( int paramIndex = 0; paramIndex < specification.getParameters().length; paramIndex++ ) {
76                             parameterList.add( specification.getParameters()[paramIndex] );
77                         }
78                     }
79                 }
80             }
81             if ( affected ) {
82                 updates[tableIndex] = update.toStatementString();
83                 hqlParameters[tableIndex] = ( ParameterSpecification[] ) parameterList.toArray( new ParameterSpecification[0] );
84             }
85         }
86     }
87
88     public Queryable getAffectedQueryable() {
89         return persister;
90     }
91
92     public int execute(QueryParameters parameters, SessionImplementor session) throws HibernateException {
93         coordinateSharedCacheCleanup( session );
94
95         createTemporaryTableIfNecessary( persister, session );
96
97         try {
98             // First, save off the pertinent ids, as the return value
99
PreparedStatement JavaDoc ps = null;
100             int resultCount = 0;
101             try {
102                 try {
103                     ps = session.getBatcher().prepareStatement( idInsertSelect );
104                     int parameterStart = getWalker().getNumberOfParametersInSetClause();
105                     List JavaDoc allParams = getWalker().getParameters();
106                     Iterator JavaDoc whereParams = allParams.subList( parameterStart, allParams.size() ).iterator();
107                     int sum = 1; // jdbc params are 1-based
108
while ( whereParams.hasNext() ) {
109                         sum += ( ( ParameterSpecification ) whereParams.next() ).bind( ps, parameters, session, sum );
110                     }
111                     resultCount = ps.executeUpdate();
112                 }
113                 finally {
114                     if ( ps != null ) {
115                         session.getBatcher().closeStatement( ps );
116                     }
117                 }
118             }
119             catch( SQLException JavaDoc e ) {
120                 throw JDBCExceptionHelper.convert(
121                         getFactory().getSQLExceptionConverter(),
122                         e,
123                         "could not insert/select ids for bulk update",
124                         idInsertSelect
125                     );
126             }
127
128             // Start performing the updates
129
for ( int i = 0; i < updates.length; i++ ) {
130                 if ( updates[i] == null ) {
131                     continue;
132                 }
133                 try {
134                     try {
135                         ps = session.getBatcher().prepareStatement( updates[i] );
136                         if ( hqlParameters[i] != null ) {
137                             int position = 1; // jdbc params are 1-based
138
for ( int x = 0; x < hqlParameters[i].length; x++ ) {
139                                 position += hqlParameters[i][x].bind( ps, parameters, session, position );
140                             }
141                         }
142                         ps.executeUpdate();
143                     }
144                     finally {
145                         if ( ps != null ) {
146                             session.getBatcher().closeStatement( ps );
147                         }
148                     }
149                 }
150                 catch( SQLException JavaDoc e ) {
151                     throw JDBCExceptionHelper.convert(
152                             getFactory().getSQLExceptionConverter(),
153                             e,
154                             "error performing bulk update",
155                             updates[i]
156                         );
157                 }
158             }
159
160             return resultCount;
161         }
162         finally {
163             dropTemporaryTableIfNecessary( persister, session );
164         }
165     }
166
167     protected Queryable[] getAffectedQueryables() {
168         return new Queryable[] { persister };
169     }
170 }
171
Popular Tags