001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb.plugins.cmp.jdbc;
023:
024: import java.sql.Connection;
025: import java.sql.PreparedStatement;
026: import java.util.Map;
027: import java.rmi.RemoteException;
028: import javax.ejb.RemoveException;
029:
030: import org.jboss.ejb.EntityEnterpriseContext;
031: import org.jboss.ejb.EntityContainer;
032: import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge;
033: import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCEntityBridge;
034: import org.jboss.logging.Logger;
035: import org.jboss.metadata.ConfigurationMetaData;
036: import org.jboss.deployment.DeploymentException;
037:
038: /**
039: * JDBCRemoveEntityCommand executes a DELETE FROM table WHERE command.
040: *
041: * @author <a href="mailto:dain@daingroup.com">Dain Sundstrom</a>
042: * @author <a href="mailto:rickard.oberg@telkel.com">Rickard Öberg</a>
043: * @author <a href="mailto:marc.fleury@telkel.com">Marc Fleury</a>
044: * @author <a href="mailto:shevlandj@kpi.com.au">Joe Shevland</a>
045: * @author <a href="mailto:justin@j-m-f.demon.co.uk">Justin Forder</a>
046: * @author <a href="mailto:alex@jboss.org">Alexey Loubyansky</a>
047: * @version $Revision: 57209 $
048: */
049: public final class JDBCRemoveEntityCommand {
050: private final JDBCStoreManager manager;
051: private final JDBCEntityBridge entity;
052: private final Logger log;
053: private final String removeEntitySQL;
054: private final boolean syncOnCommitOnly;
055: private boolean batchCascadeDelete;
056:
057: public JDBCRemoveEntityCommand(JDBCStoreManager manager)
058: throws DeploymentException {
059: this .manager = manager;
060: entity = (JDBCEntityBridge) manager.getEntityBridge();
061:
062: // Create the Log
063: log = Logger.getLogger(this .getClass().getName() + "."
064: + manager.getMetaData().getName());
065:
066: StringBuffer sql = new StringBuffer();
067: sql.append(SQLUtil.DELETE_FROM).append(
068: entity.getQualifiedTableName()).append(SQLUtil.WHERE);
069: SQLUtil.getWhereClause(entity.getPrimaryKeyFields(), sql);
070:
071: removeEntitySQL = sql.toString();
072: if (log.isDebugEnabled())
073: log.debug("Remove SQL: " + removeEntitySQL);
074:
075: ConfigurationMetaData containerConfig = manager.getContainer()
076: .getBeanMetaData().getContainerConfiguration();
077: syncOnCommitOnly = containerConfig.getSyncOnCommitOnly();
078:
079: JDBCCMRFieldBridge[] cmrFields = (JDBCCMRFieldBridge[]) entity
080: .getCMRFields();
081: for (int i = 0; i < cmrFields.length; ++i) {
082: if (cmrFields[i].isBatchCascadeDelete()) {
083: batchCascadeDelete = true;
084: break;
085: }
086: }
087: }
088:
089: public void execute(EntityEnterpriseContext ctx)
090: throws RemoveException, RemoteException {
091: if (entity.isRemoved(ctx)) {
092: throw new IllegalStateException(
093: "Instance was already removed: id=" + ctx.getId());
094: }
095:
096: entity.setIsBeingRemoved(ctx);
097:
098: // remove entity from all relations
099: Object[] oldRelationsRef = new Object[1];
100: boolean needsSync = entity.removeFromRelations(ctx,
101: oldRelationsRef);
102:
103: // update the related entities (stores the removal from relationships)
104: // if one of the store fails an EJBException will be thrown
105: if (!syncOnCommitOnly && needsSync) {
106: EntityContainer.synchronizeEntitiesWithinTransaction(ctx
107: .getTransaction());
108: }
109:
110: if (!batchCascadeDelete) {
111: if (!entity.isScheduledForBatchCascadeDelete(ctx)) {
112: executeDeleteSQL(ctx);
113: } else {
114: if (log.isTraceEnabled())
115: log
116: .trace("Instance is scheduled for cascade delete. id="
117: + ctx.getId());
118: }
119: }
120:
121: // cascate-delete to old relations, if relation uses cascade.
122: if (oldRelationsRef[0] != null) {
123: Map oldRelations = (Map) oldRelationsRef[0];
124: entity.cascadeDelete(ctx, oldRelations);
125: }
126:
127: if (batchCascadeDelete) {
128: if (!entity.isScheduledForBatchCascadeDelete(ctx)) {
129: executeDeleteSQL(ctx);
130: } else {
131: if (log.isTraceEnabled())
132: log
133: .debug("Instance is scheduled for cascade delete. id="
134: + ctx.getId());
135: }
136: }
137:
138: entity.setRemoved(ctx);
139: manager.getReadAheadCache().removeCachedData(ctx.getId());
140: }
141:
142: private void executeDeleteSQL(EntityEnterpriseContext ctx)
143: throws RemoveException {
144: Object key = ctx.getId();
145: Connection con = null;
146: PreparedStatement ps = null;
147: int rowsAffected = 0;
148: try {
149: if (log.isDebugEnabled())
150: log.debug("Executing SQL: " + removeEntitySQL);
151:
152: // get the connection
153: con = entity.getDataSource().getConnection();
154: ps = con.prepareStatement(removeEntitySQL);
155:
156: // set the parameters
157: entity.setPrimaryKeyParameters(ps, 1, key);
158:
159: // execute statement
160: rowsAffected = ps.executeUpdate();
161: } catch (Exception e) {
162: log.error("Could not remove " + key, e);
163: throw new RemoveException("Could not remove " + key + ": "
164: + e.getMessage());
165: } finally {
166: JDBCUtil.safeClose(ps);
167: JDBCUtil.safeClose(con);
168: }
169:
170: // check results
171: if (rowsAffected == 0) {
172: log.error("Could not remove entity " + key);
173: throw new RemoveException("Could not remove entity");
174: }
175:
176: if (log.isTraceEnabled())
177: log.trace("Remove: Rows affected = " + rowsAffected);
178: }
179: }
|