package org.jboss.ejb.plugins.cmp.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import javax.ejb.EJBException;
import org.jboss.ejb.EntityEnterpriseContext;
import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCEntityBridge;
import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMPFieldBridge;
import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCFieldBridge;
import org.jboss.logging.Logger;
public final class JDBCStoreEntityCommand
{
private final JDBCEntityBridge entity;
private final JDBCFieldBridge[] primaryKeyFields;
private final Logger log;
public JDBCStoreEntityCommand(JDBCStoreManager manager)
{
entity = (JDBCEntityBridge) manager.getEntityBridge();
primaryKeyFields = entity.getPrimaryKeyFields();
log = Logger.getLogger(
this.getClass().getName() +
"." +
manager.getMetaData().getName());
}
public void execute(EntityEnterpriseContext ctx)
{
JDBCEntityBridge.FieldIterator dirtyIterator = entity.getDirtyIterator(ctx);
if(!dirtyIterator.hasNext() || entity.isScheduledForBatchCascadeDelete(ctx))
{
if(log.isTraceEnabled())
{
log.trace("Store command NOT executed. Entity is not dirty "
+ " or scheduled for *batch* cascade delete: pk=" + ctx.getId());
}
return;
}
StringBuffer sql = new StringBuffer(200);
sql.append(SQLUtil.UPDATE)
.append(entity.getQualifiedTableName())
.append(SQLUtil.SET);
SQLUtil.getSetClause(dirtyIterator, sql)
.append(SQLUtil.WHERE);
SQLUtil.getWhereClause(primaryKeyFields, sql);
boolean hasLockedFields = entity.hasLockedFields(ctx);
JDBCEntityBridge.FieldIterator lockedIterator = null;
if(hasLockedFields)
{
lockedIterator = entity.getLockedIterator(ctx);
while(lockedIterator.hasNext())
{
sql.append(SQLUtil.AND);
JDBCCMPFieldBridge field = lockedIterator.next();
if(field.getLockedValue(ctx) == null)
{
SQLUtil.getIsNullClause(false, field, "", sql);
lockedIterator.remove();
}
else
{
SQLUtil.getWhereClause(field, sql);
}
}
}
Connection con = null;
PreparedStatement ps = null;
int rowsAffected = 0;
try
{
if(log.isDebugEnabled())
{
log.debug("Executing SQL: " + sql);
}
con = entity.getDataSource().getConnection();
ps = con.prepareStatement(sql.toString());
int index = 1;
dirtyIterator.reset();
while(dirtyIterator.hasNext())
{
index = dirtyIterator.next().setInstanceParameters(ps, index, ctx);
}
index = entity.setPrimaryKeyParameters(ps, index, ctx.getId());
if(hasLockedFields)
{
lockedIterator.reset();
while(lockedIterator.hasNext())
{
JDBCCMPFieldBridge field = lockedIterator.next();
Object value = field.getLockedValue(ctx);
index = field.setArgumentParameters(ps, index, value);
}
}
rowsAffected = ps.executeUpdate();
}
catch(EJBException e)
{
throw e;
}
catch(Exception e)
{
throw new EJBException("Store failed", e);
}
finally
{
JDBCUtil.safeClose(ps);
JDBCUtil.safeClose(con);
}
if(rowsAffected != 1)
{
throw new EJBException("Update failed. Expected one affected row: rowsAffected=" +
rowsAffected + ", id=" + ctx.getId());
}
dirtyIterator.reset();
while(dirtyIterator.hasNext())
{
dirtyIterator.next().setClean(ctx);
}
}
}