1 package org.hibernate.hql.ast.exec; 3 4 import java.sql.PreparedStatement ; 5 6 import org.hibernate.HibernateException; 7 import org.hibernate.action.BulkOperationCleanupAction; 8 import org.hibernate.engine.SessionFactoryImplementor; 9 import org.hibernate.engine.SessionImplementor; 10 import org.hibernate.event.EventSource; 11 import org.hibernate.hql.ast.HqlSqlWalker; 12 import org.hibernate.hql.ast.SqlGenerator; 13 import org.hibernate.persister.entity.Queryable; 14 import org.hibernate.sql.InsertSelect; 15 import org.hibernate.sql.Select; 16 import org.hibernate.sql.SelectFragment; 17 import org.hibernate.util.StringHelper; 18 19 import antlr.RecognitionException; 20 import antlr.collections.AST; 21 22 import org.apache.commons.logging.Log; 23 24 29 public abstract class AbstractStatementExecutor implements StatementExecutor { 30 31 private final Log log; 32 private final HqlSqlWalker walker; 33 34 public AbstractStatementExecutor(HqlSqlWalker walker, Log log) { 35 this.walker = walker; 36 this.log = log; 37 } 38 39 protected HqlSqlWalker getWalker() { 40 return walker; 41 } 42 43 protected SessionFactoryImplementor getFactory() { 44 return walker.getSessionFactoryHelper().getFactory(); 45 } 46 47 protected abstract Queryable[] getAffectedQueryables(); 48 49 protected String generateIdInsertSelect(Queryable persister, AST whereClause) { 50 Select select = new Select( getFactory().getDialect() ); 51 String tableAlias = "del"; 52 SelectFragment selectFragment = new SelectFragment() 53 .addColumns( tableAlias, persister.getIdentifierColumnNames(), persister.getIdentifierColumnNames() ); 54 select.setSelectClause( selectFragment.toFragmentString().substring( 2 ) ); 55 56 select.setFromClause( persister.getTableName() + ' ' + tableAlias + persister.fromJoinFragment( tableAlias, true, false ) ); 57 58 String userWhereClause = ""; 59 if ( whereClause.getNumberOfChildren() != 0 ) { 60 try { 63 SqlGenerator sqlGenerator = new SqlGenerator( getFactory() ); 64 sqlGenerator.whereClause( whereClause ); 65 userWhereClause = sqlGenerator.getSQL().substring( 7 ); } 67 catch ( RecognitionException e ) { 68 throw new HibernateException( "Unable to generate id select for DML operation", e ); 69 } 70 } 71 select.setWhereClause( persister.whereJoinFragment(tableAlias, true, false ) + userWhereClause ); 72 73 InsertSelect insert = new InsertSelect( getFactory().getDialect() ); 74 if ( getFactory().getSettings().isCommentsEnabled() && getFactory().getDialect().supportsCommentOn() ) { 75 insert.setComment( "insert-select for " + persister.getEntityName() + " ids" ); 76 } 77 insert.setTableName( persister.getTemporaryIdTableName() ); 78 insert.setSelect( select ); 79 return insert.toStatementString(); 80 } 81 82 protected String generateIdSubselect(Queryable persister) { 83 return "select " + StringHelper.join( ", ", persister.getIdentifierColumnNames() ) + 84 " from " + persister.getTemporaryIdTableName(); 85 } 86 87 protected void createTemporaryTableIfNecessary(Queryable persister, SessionImplementor session) { 88 PreparedStatement ps = null; 91 try { 92 ps = session.getBatcher().prepareStatement( persister.getTemporaryIdTableDDL() ); 93 ps.executeUpdate(); 94 } 95 catch( Throwable t ) { 96 log.debug( "unable to create temporary id table [" + t.getMessage() + "]" ); 97 } 98 finally { 99 if ( ps != null ) { 100 try { 101 session.getBatcher().closeStatement( ps ); 102 } 103 catch( Throwable ignore ) { 104 } 105 } 106 } 107 } 108 109 protected void dropTemporaryTableIfNecessary(Queryable persister, SessionImplementor session) { 110 if ( getFactory().getDialect().dropTemporaryTableAfterUse() ) { 111 PreparedStatement ps = null; 112 try { 113 ps = session.getBatcher().prepareStatement( "drop table " + persister.getTemporaryIdTableName() ); 114 ps.executeUpdate(); 115 } 116 catch( Throwable t ) { 117 log.warn( "unable to drop temporary id table after use", t ); 118 } 119 finally { 120 if ( ps != null ) { 121 try { 122 session.getBatcher().closeStatement( ps ); 123 } 124 catch( Throwable ignore ) { 125 } 126 } 127 } 128 } 129 } 130 131 protected void coordinateSharedCacheCleanup(SessionImplementor session) { 132 BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, getAffectedQueryables() ); 133 134 action.init(); 135 136 if ( session.isEventSource() ) { 137 ( ( EventSource ) session ).getActionQueue().addAction( action ); 138 } 139 } 140 } 141 | Popular Tags |