1 22 package org.jboss.ejb.plugins.cmp.jdbc; 23 24 import java.sql.Connection ; 25 import java.sql.PreparedStatement ; 26 import java.sql.ResultSet ; 27 import java.util.List ; 28 import javax.ejb.EJBException ; 29 import javax.ejb.NoSuchEntityException ; 30 31 import org.jboss.ejb.EntityEnterpriseContext; 32 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCFieldBridge; 33 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMPFieldBridge; 34 import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCEntityBridge; 35 import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCFunctionMappingMetaData; 36 import org.jboss.logging.Logger; 37 import org.jboss.deployment.DeploymentException; 38 39 56 public final class JDBCLoadEntityCommand 57 { 58 private final JDBCStoreManager manager; 59 private final JDBCEntityBridge entity; 60 private final Logger log; 61 private final JDBCFunctionMappingMetaData rowLockingTemplate; 62 63 public JDBCLoadEntityCommand(JDBCStoreManager manager) throws DeploymentException 64 { 65 this.manager = manager; 66 entity = (JDBCEntityBridge) manager.getEntityBridge(); 67 boolean rowLocking = entity.getMetaData().hasRowLocking(); 68 rowLockingTemplate = rowLocking ? entity.getMetaData().getTypeMapping().getRowLockingTemplate() : null; 69 70 log = Logger.getLogger( 72 this.getClass().getName() + 73 "." + 74 manager.getMetaData().getName()); 75 } 76 77 86 public boolean execute(EntityEnterpriseContext ctx, boolean failIfNotFound) 87 { 88 return execute(null, ctx, failIfNotFound); 89 } 90 91 96 public void execute(JDBCCMPFieldBridge requiredField, EntityEnterpriseContext ctx) 97 { 98 execute(requiredField, ctx, true); 99 } 100 101 102 113 private boolean execute(JDBCCMPFieldBridge requiredField, 114 EntityEnterpriseContext ctx, 115 boolean failIfNotFound) 116 { 117 Object id = ctx.getId(); 119 entity.injectPrimaryKeyIntoInstance(ctx, id); 121 122 ReadAheadCache readAheadCache = manager.getReadAheadCache(); 124 125 if(readAheadCache.load(ctx)) 127 { 128 if(requiredField == null || (requiredField != null && requiredField.isLoaded(ctx))) 129 { 130 return true; 131 } 132 } 133 134 ReadAheadCache.EntityReadAheadInfo info = readAheadCache.getEntityReadAheadInfo(id); 136 137 JDBCEntityBridge.FieldIterator loadIter = entity.getLoadIterator(requiredField, info.getReadAhead(), ctx); 139 if(!loadIter.hasNext()) 140 return true; 141 142 List loadKeys = info.getLoadKeys(); 144 145 String sql = (rowLockingTemplate != null ? getRawLockingSQL(loadIter, loadKeys.size()) : getSQL(loadIter, loadKeys.size())); 147 148 Connection con = null; 149 PreparedStatement ps = null; 150 ResultSet rs = null; 151 try 152 { 153 if (log.isDebugEnabled()) 155 { 156 log.debug("Executing SQL: " + sql); 157 } 158 159 con = entity.getDataSource().getConnection(); 161 ps = con.prepareStatement(sql); 162 163 if (entity.getFetchSize() > 0) 165 { 166 ps.setFetchSize(entity.getFetchSize()); 167 } 168 169 int paramIndex = 1; 171 for (int i = 0; i < loadKeys.size(); i++) 172 { 173 paramIndex = entity.setPrimaryKeyParameters(ps, paramIndex, loadKeys.get(i)); 174 } 175 176 rs = ps.executeQuery(); 178 179 boolean mainEntityLoaded = false; 181 Object [] ref = new Object [1]; 182 while (rs.next()) 183 { 184 int index = 1; 186 187 ref[0] = null; 189 190 Object pk = null; 192 if (loadKeys.size() > 1) 193 { 194 index = entity.loadPrimaryKeyResults(rs, index, ref); 196 pk = ref[0]; 197 } 198 199 if (loadKeys.size() == 1 || pk.equals(id)) 201 { 202 loadIter.reset(); 204 while(loadIter.hasNext()) 205 { 206 JDBCCMPFieldBridge field = loadIter.next(); 207 index = field.loadInstanceResults(rs, index, ctx); 208 field.setClean(ctx); 209 } 210 mainEntityLoaded = true; 211 } 212 else 213 { 214 loadIter.reset(); 216 while(loadIter.hasNext()) 217 { 218 JDBCCMPFieldBridge field = loadIter.next(); 219 ref[0] = null; 221 222 index = field.loadArgumentResults(rs, index, ref); 224 225 readAheadCache.addPreloadData(pk, field, ref[0]); 227 } 228 } 229 } 230 231 loadIter.removeAll(); 233 234 if (!mainEntityLoaded) 236 { 237 if (failIfNotFound) 238 throw new NoSuchEntityException ("Entity not found: primaryKey=" + ctx.getId()); 239 else 240 return false; 241 } 242 else 243 return true; 244 } 245 catch (EJBException e) 246 { 247 throw e; 248 } 249 catch (Exception e) 250 { 251 throw new EJBException ("Load failed", e); 252 } 253 finally 254 { 255 JDBCUtil.safeClose(rs); 256 JDBCUtil.safeClose(ps); 257 JDBCUtil.safeClose(con); 258 } 259 } 260 261 private String getSQL(JDBCEntityBridge.FieldIterator loadIter, int keyCount) 262 { 263 StringBuffer sql = new StringBuffer (250); 264 sql.append(SQLUtil.SELECT); 265 266 JDBCFieldBridge[] primaryKeyFields = entity.getPrimaryKeyFields(); 269 if (keyCount > 1) 270 { 271 SQLUtil.getColumnNamesClause(primaryKeyFields, sql); 272 sql.append(SQLUtil.COMMA); 273 } 274 SQLUtil.getColumnNamesClause(loadIter, sql); 275 sql.append(SQLUtil.FROM) 276 .append(entity.getQualifiedTableName()) 277 .append(SQLUtil.WHERE); 278 279 String pkWhere = SQLUtil.getWhereClause(primaryKeyFields, new StringBuffer (50)).toString(); 282 sql.append('(').append(pkWhere).append(')'); 283 for (int i = 1; i < keyCount; i++) 284 { 285 sql.append(SQLUtil.OR).append('(').append(pkWhere).append(')'); 286 } 287 288 return sql.toString(); 289 } 290 291 private String getRawLockingSQL(JDBCEntityBridge.FieldIterator loadIter, int keyCount) 292 { 293 StringBuffer columnNamesClause = new StringBuffer (250); 296 if (keyCount > 1) 300 { 301 SQLUtil.getColumnNamesClause(entity.getPrimaryKeyFields(), columnNamesClause); 302 columnNamesClause.append(SQLUtil.COMMA); 303 } 304 305 SQLUtil.getColumnNamesClause(loadIter, columnNamesClause); 306 307 String tableName = entity.getQualifiedTableName(); 310 311 String whereClause = SQLUtil. 314 getWhereClause(entity.getPrimaryKeyFields(), new StringBuffer (50)).toString(); 315 if (keyCount > 0) 316 { 317 StringBuffer sb = new StringBuffer ((whereClause.length() + 6) * keyCount + 4); 318 for (int i = 0; i < keyCount; i++) 319 { 320 if (i > 0) 321 sb.append(SQLUtil.OR); 322 sb.append('(').append(whereClause).append(')'); 323 } 324 whereClause = sb.toString(); 325 } 326 327 String [] args = new String []{ 328 columnNamesClause.toString(), 329 tableName, 330 whereClause, 331 null }; 333 return rowLockingTemplate.getFunctionSql(args, new StringBuffer (300)).toString(); 334 } 335 } 336 | Popular Tags |