KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ofbiz > entity > datasource > GenericDAO


1 /*
2  * $Id: GenericDAO.java 6096 2005-11-09 01:41:31Z jonesde $
3  *
4  * Copyright (c) 2001-2005 The Open For Business Project - www.ofbiz.org
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  */

25 package org.ofbiz.entity.datasource;
26
27 import java.sql.ResultSet JavaDoc;
28 import java.sql.SQLException JavaDoc;
29 import java.sql.Timestamp JavaDoc;
30 import java.util.Collection JavaDoc;
31 import java.util.Collections JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Map JavaDoc;
35 import java.util.Set JavaDoc;
36 import java.util.TreeSet JavaDoc;
37 import java.util.LinkedList JavaDoc;
38
39 import javolution.util.FastList;
40 import javolution.util.FastMap;
41 import javolution.util.FastSet;
42
43 import org.ofbiz.base.util.Debug;
44 import org.ofbiz.base.util.UtilValidate;
45 import org.ofbiz.entity.EntityLockedException;
46 import org.ofbiz.entity.GenericDataSourceException;
47 import org.ofbiz.entity.GenericDelegator;
48 import org.ofbiz.entity.GenericEntity;
49 import org.ofbiz.entity.GenericEntityException;
50 import org.ofbiz.entity.GenericEntityNotFoundException;
51 import org.ofbiz.entity.GenericModelException;
52 import org.ofbiz.entity.GenericNotImplementedException;
53 import org.ofbiz.entity.GenericValue;
54 import org.ofbiz.entity.condition.EntityCondition;
55 import org.ofbiz.entity.condition.EntityConditionParam;
56 import org.ofbiz.entity.condition.EntityFieldMap;
57 import org.ofbiz.entity.condition.EntityOperator;
58 import org.ofbiz.entity.config.DatasourceInfo;
59 import org.ofbiz.entity.config.EntityConfigUtil;
60 import org.ofbiz.entity.jdbc.DatabaseUtil;
61 import org.ofbiz.entity.jdbc.SQLProcessor;
62 import org.ofbiz.entity.jdbc.SqlJdbcUtil;
63 import org.ofbiz.entity.model.ModelEntity;
64 import org.ofbiz.entity.model.ModelField;
65 import org.ofbiz.entity.model.ModelFieldTypeReader;
66 import org.ofbiz.entity.model.ModelKeyMap;
67 import org.ofbiz.entity.model.ModelRelation;
68 import org.ofbiz.entity.model.ModelViewEntity;
69 import org.ofbiz.entity.transaction.TransactionUtil;
70 import org.ofbiz.entity.util.EntityFindOptions;
71 import org.ofbiz.entity.util.EntityListIterator;
72
73 /**
74  * Generic Entity Data Access Object - Handles persisntence for any defined entity.
75  *
76  * @author <a HREF="mailto:jonesde@ofbiz.org">David E. Jones</a>
77  * @author <a HREF="mailto:jaz@ofbiz.org">Andy Zeneski</a>
78  * @author <a HREF="mailto:chris_maurer@altavista.com">Chris Maurer</a>
79  * @author <a HREF="mailto:jdonnerstag@eds.de">Juergen Donnerstag</a>
80  * @author <a HREF="mailto:gielen@aixcept.de">Rene Gielen</a>
81  * @author <a HREF="mailto:john_nutting@telluridetechnologies.com">John Nutting</a>
82  * @version $Rev: 6096 $
83  * @since 1.0
84  */

85 public class GenericDAO {
86
87     public static final String JavaDoc module = GenericDAO.class.getName();
88
89     protected static Map JavaDoc genericDAOs = FastMap.newInstance();
90     protected String JavaDoc helperName;
91     protected ModelFieldTypeReader modelFieldTypeReader = null;
92     protected DatasourceInfo datasourceInfo;
93
94     public static GenericDAO getGenericDAO(String JavaDoc helperName) {
95         GenericDAO newGenericDAO = (GenericDAO) genericDAOs.get(helperName);
96
97         if (newGenericDAO == null) { // don't want to block here
98
synchronized (GenericDAO.class) {
99                 newGenericDAO = (GenericDAO) genericDAOs.get(helperName);
100                 if (newGenericDAO == null) {
101                     newGenericDAO = new GenericDAO(helperName);
102                     genericDAOs.put(helperName, newGenericDAO);
103                 }
104             }
105         }
106         return newGenericDAO;
107     }
108
109     public GenericDAO(String JavaDoc helperName) {
110         this.helperName = helperName;
111         this.modelFieldTypeReader = ModelFieldTypeReader.getModelFieldTypeReader(helperName);
112         this.datasourceInfo = EntityConfigUtil.getDatasourceInfo(helperName);
113     }
114
115     private void addFieldIfMissing(List JavaDoc fieldsToSave, String JavaDoc fieldName, ModelEntity modelEntity) {
116         Iterator JavaDoc fieldsToSaveIter = fieldsToSave.iterator();
117         while (fieldsToSaveIter.hasNext()) {
118             ModelField fieldToSave = (ModelField) fieldsToSaveIter.next();
119             if (fieldName.equals(fieldToSave.getName())) {
120                 return;
121             }
122         }
123         // at this point we didn't find it
124
fieldsToSave.add(modelEntity.getField(fieldName));
125     }
126
127     public int insert(GenericEntity entity) throws GenericEntityException {
128         ModelEntity modelEntity = entity.getModelEntity();
129
130         if (modelEntity == null) {
131             throw new GenericModelException("Could not find ModelEntity record for entityName: " + entity.getEntityName());
132         }
133
134         SQLProcessor sqlP = new SQLProcessor(helperName);
135
136         try {
137             return singleInsert(entity, modelEntity, modelEntity.getFieldsCopy(), sqlP);
138         } catch (GenericEntityException e) {
139             sqlP.rollback();
140             throw new GenericEntityException("Exception while inserting the following entity: " + entity.toString(), e);
141         } finally {
142             sqlP.close();
143         }
144     }
145
146     private int singleInsert(GenericEntity entity, ModelEntity modelEntity, List JavaDoc fieldsToSave, SQLProcessor sqlP) throws GenericEntityException {
147         if (modelEntity instanceof ModelViewEntity) {
148             return singleUpdateView(entity, (ModelViewEntity) modelEntity, fieldsToSave, sqlP);
149         }
150
151         // if we have a STAMP_TX_FIELD or CREATE_STAMP_TX_FIELD then set it with NOW, always do this before the STAMP_FIELD
152
// NOTE: these fairly complicated if statements have a few objectives:
153
// 1. don't run the TransationUtil.getTransaction*Stamp() methods when we don't need to
154
// 2. don't set the stamp values if it is from an EntitySync (ie maintain original values), unless the stamps are null then set it anyway, ie even if it was from an EntitySync (also used for imports and such)
155
boolean stampTxIsField = modelEntity.isField(ModelEntity.STAMP_TX_FIELD);
156         boolean createStampTxIsField = modelEntity.isField(ModelEntity.CREATE_STAMP_TX_FIELD);
157         if ((stampTxIsField || createStampTxIsField) && (!entity.getIsFromEntitySync() || (stampTxIsField && entity.get(ModelEntity.STAMP_TX_FIELD) == null) || (createStampTxIsField && entity.get(ModelEntity.CREATE_STAMP_TX_FIELD) == null))) {
158             Timestamp JavaDoc txStartStamp = TransactionUtil.getTransactionStartStamp();
159             if (stampTxIsField && (!entity.getIsFromEntitySync() || entity.get(ModelEntity.STAMP_TX_FIELD) == null)) {
160                 entity.set(ModelEntity.STAMP_TX_FIELD, txStartStamp);
161                 addFieldIfMissing(fieldsToSave, ModelEntity.STAMP_TX_FIELD, modelEntity);
162             }
163             if (createStampTxIsField && (!entity.getIsFromEntitySync() || entity.get(ModelEntity.CREATE_STAMP_TX_FIELD) == null)) {
164                 entity.set(ModelEntity.CREATE_STAMP_TX_FIELD, txStartStamp);
165                 addFieldIfMissing(fieldsToSave, ModelEntity.CREATE_STAMP_TX_FIELD, modelEntity);
166             }
167         }
168
169         // if we have a STAMP_FIELD or CREATE_STAMP_FIELD then set it with NOW
170
boolean stampIsField = modelEntity.isField(ModelEntity.STAMP_FIELD);
171         boolean createStampIsField = modelEntity.isField(ModelEntity.CREATE_STAMP_FIELD);
172         if ((stampIsField || createStampIsField) && (!entity.getIsFromEntitySync() || (stampIsField && entity.get(ModelEntity.STAMP_FIELD) == null) || (createStampIsField && entity.get(ModelEntity.CREATE_STAMP_FIELD) == null))) {
173             Timestamp JavaDoc startStamp = TransactionUtil.getTransactionUniqueNowStamp();
174             if (stampIsField && (!entity.getIsFromEntitySync() || entity.get(ModelEntity.STAMP_FIELD) == null)) {
175                 entity.set(ModelEntity.STAMP_FIELD, startStamp);
176                 addFieldIfMissing(fieldsToSave, ModelEntity.STAMP_FIELD, modelEntity);
177             }
178             if (createStampIsField && (!entity.getIsFromEntitySync() || entity.get(ModelEntity.CREATE_STAMP_FIELD) == null)) {
179                 entity.set(ModelEntity.CREATE_STAMP_FIELD, startStamp);
180                 addFieldIfMissing(fieldsToSave, ModelEntity.CREATE_STAMP_FIELD, modelEntity);
181             }
182         }
183
184         String JavaDoc sql = "INSERT INTO " + modelEntity.getTableName(datasourceInfo) + " (" + modelEntity.colNameString(fieldsToSave) + ") VALUES (" +
185             modelEntity.fieldsStringList(fieldsToSave, "?", ", ") + ")";
186
187         try {
188             sqlP.prepareStatement(sql);
189             SqlJdbcUtil.setValues(sqlP, fieldsToSave, entity, modelFieldTypeReader);
190             int retVal = sqlP.executeUpdate();
191
192             entity.synchronizedWithDatasource();
193             return retVal;
194         } catch (GenericEntityException e) {
195             throw new GenericEntityException("while inserting: " + entity.toString(), e);
196         } finally {
197             sqlP.close();
198         }
199     }
200
201     public int updateAll(GenericEntity entity) throws GenericEntityException {
202         ModelEntity modelEntity = entity.getModelEntity();
203
204         if (modelEntity == null) {
205             throw new GenericModelException("Could not find ModelEntity record for entityName: " + entity.getEntityName());
206         }
207
208         return customUpdate(entity, modelEntity, modelEntity.getNopksCopy());
209     }
210
211     public int update(GenericEntity entity) throws GenericEntityException {
212         ModelEntity modelEntity = entity.getModelEntity();
213
214         if (modelEntity == null) {
215             throw new GenericModelException("Could not find ModelEntity record for entityName: " + entity.getEntityName());
216         }
217
218         // we don't want to update ALL fields, just the nonpk fields that are in the passed GenericEntity
219
List JavaDoc partialFields = FastList.newInstance();
220         Collection JavaDoc keys = entity.getAllKeys();
221
222         Iterator JavaDoc nopkIter = modelEntity.getNopksIterator();
223         while (nopkIter.hasNext()) {
224             ModelField curField = (ModelField) nopkIter.next();
225             if (keys.contains(curField.getName())) {
226                 partialFields.add(curField);
227             }
228         }
229
230         return customUpdate(entity, modelEntity, partialFields);
231     }
232
233     private int customUpdate(GenericEntity entity, ModelEntity modelEntity, List JavaDoc fieldsToSave) throws GenericEntityException {
234         SQLProcessor sqlP = new SQLProcessor(helperName);
235         try {
236             return singleUpdate(entity, modelEntity, fieldsToSave, sqlP);
237         } catch (GenericEntityException e) {
238             sqlP.rollback();
239             throw new GenericEntityException("Exception while updating the following entity: " + entity.toString(), e);
240         } finally {
241             sqlP.close();
242         }
243     }
244
245     private int singleUpdate(GenericEntity entity, ModelEntity modelEntity, List JavaDoc fieldsToSave, SQLProcessor sqlP) throws GenericEntityException {
246         if (modelEntity instanceof ModelViewEntity) {
247             return singleUpdateView(entity, (ModelViewEntity) modelEntity, fieldsToSave, sqlP);
248         }
249
250         // no non-primaryKey fields, update doesn't make sense, so don't do it
251
if (fieldsToSave.size() <= 0) {
252             if (Debug.verboseOn()) Debug.logVerbose("Trying to do an update on an entity with no non-PK fields, returning having done nothing; entity=" + entity, module);
253             // returning one because it was effectively updated, ie the same thing, so don't trigger any errors elsewhere
254
return 1;
255         }
256
257         if (modelEntity.lock()) {
258             GenericEntity entityCopy = GenericEntity.createGenericEntity(entity);
259
260             select(entityCopy, sqlP);
261             Object JavaDoc stampField = entity.get(ModelEntity.STAMP_FIELD);
262
263             if ((stampField != null) && (!stampField.equals(entityCopy.get(ModelEntity.STAMP_FIELD)))) {
264                 String JavaDoc lockedTime = entityCopy.getTimestamp(ModelEntity.STAMP_FIELD).toString();
265
266                 throw new EntityLockedException("You tried to update an old version of this data. Version locked: (" + lockedTime + ")");
267             }
268         }
269
270         // if we have a STAMP_TX_FIELD then set it with NOW, always do this before the STAMP_FIELD
271
// NOTE: these fairly complicated if statements have a few objectives:
272
// 1. don't run the TransationUtil.getTransaction*Stamp() methods when we don't need to
273
// 2. don't set the stamp values if it is from an EntitySync (ie maintain original values), unless the stamps are null then set it anyway, ie even if it was from an EntitySync (also used for imports and such)
274
if (modelEntity.isField(ModelEntity.STAMP_TX_FIELD) && (!entity.getIsFromEntitySync() || entity.get(ModelEntity.STAMP_TX_FIELD) == null)) {
275             entity.set(ModelEntity.STAMP_TX_FIELD, TransactionUtil.getTransactionStartStamp());
276             addFieldIfMissing(fieldsToSave, ModelEntity.STAMP_TX_FIELD, modelEntity);
277         }
278
279         // if we have a STAMP_FIELD then update it with NOW.
280
if (modelEntity.isField(ModelEntity.STAMP_FIELD) && (!entity.getIsFromEntitySync() || entity.get(ModelEntity.STAMP_FIELD) == null)) {
281             entity.set(ModelEntity.STAMP_FIELD, TransactionUtil.getTransactionUniqueNowStamp());
282             addFieldIfMissing(fieldsToSave, ModelEntity.STAMP_FIELD, modelEntity);
283         }
284
285         String JavaDoc sql = "UPDATE " + modelEntity.getTableName(datasourceInfo) + " SET " + modelEntity.colNameString(fieldsToSave, "=?, ", "=?", false) + " WHERE " +
286             SqlJdbcUtil.makeWhereStringFromFields(modelEntity.getPksCopy(), entity, "AND");
287
288         int retVal = 0;
289
290         try {
291             sqlP.prepareStatement(sql);
292             SqlJdbcUtil.setValues(sqlP, fieldsToSave, entity, modelFieldTypeReader);
293             SqlJdbcUtil.setPkValues(sqlP, modelEntity, entity, modelFieldTypeReader);
294             retVal = sqlP.executeUpdate();
295             entity.synchronizedWithDatasource();
296         } catch (GenericEntityException e) {
297             throw new GenericEntityException("while updating: " + entity.toString(), e);
298         } finally {
299             sqlP.close();
300         }
301
302         if (retVal == 0) {
303             throw new GenericEntityNotFoundException("Tried to update an entity that does not exist.");
304         }
305         return retVal;
306     }
307
308     public int updateByCondition(ModelEntity modelEntity, Map JavaDoc fieldsToSet, EntityCondition condition) throws GenericEntityException {
309         SQLProcessor sqlP = new SQLProcessor(helperName);
310
311         try {
312             return updateByCondition(modelEntity, fieldsToSet, condition, sqlP);
313         } catch (GenericDataSourceException e) {
314             sqlP.rollback();
315             throw new GenericDataSourceException("Generic Entity Exception occured in updateByCondition", e);
316         } finally {
317             sqlP.close();
318         }
319     }
320
321     public int updateByCondition(ModelEntity modelEntity, Map JavaDoc fieldsToSet, EntityCondition condition, SQLProcessor sqlP) throws GenericEntityException {
322         if (modelEntity == null || fieldsToSet == null || condition == null)
323             return 0;
324         if (modelEntity instanceof ModelViewEntity) {
325             throw new org.ofbiz.entity.GenericNotImplementedException("Operation updateByCondition not supported yet for view entities");
326         }
327
328         String JavaDoc sql = "UPDATE " + modelEntity.getTableName(datasourceInfo);
329         sql += " SET ";
330         Iterator JavaDoc i = fieldsToSet.keySet().iterator();
331         List JavaDoc fieldList = new LinkedList JavaDoc();
332         boolean firstField = true;
333         while (i.hasNext()) {
334             String JavaDoc name = (String JavaDoc) i.next();
335             ModelField field = modelEntity.getField(name);
336             if (field != null) {
337                 if (!firstField) {
338                     sql += ", ";
339                 } else {
340                     firstField = false;
341                 }
342                 sql += field.getColName() + " = ?";
343                 fieldList.add(field);
344             }
345         }
346         sql += " WHERE " + condition.makeWhereString(modelEntity, null);
347
348         try {
349             sqlP.prepareStatement(sql);
350             Iterator JavaDoc fi = fieldList.iterator();
351             while (fi.hasNext()) {
352                 ModelField field = (ModelField) fi.next();
353                 Object JavaDoc value = fieldsToSet.get(field.getName());
354                 SqlJdbcUtil.setValue(sqlP, field, modelEntity.getEntityName(), value, modelFieldTypeReader );
355             }
356
357             return sqlP.executeUpdate();
358         } finally {
359             sqlP.close();
360         }
361     }
362
363     /* ====================================================================== */
364
365     /* ====================================================================== */
366
367     /**
368      * Try to update the given ModelViewEntity by trying to insert/update on the entities of which the view is composed.
369      *
370      * Works fine with standard O/R mapped models, but has some restrictions meeting more complicated view entities.
371      * <li>A direct link is required, which means that one of the ModelViewLink field entries must have a value found
372      * in the given view entity, for each ModelViewLink</li>
373      * <li>For now, each member entity is updated iteratively, so if eg. the second member entity fails to update,
374      * the first is written although. See code for details. Try to use "clean" views, until code is more robust ...</li>
375      * <li>For now, aliased field names in views are not processed correctly, I guess. To be honest, I did not
376      * find out how to construct such a view - so view fieldnames must have same named fields in member entities.</li>
377      * <li>A new exception, e.g. GenericViewNotUpdatable, should be defined and thrown if the update fails</li>
378      *
379      */

380     private int singleUpdateView(GenericEntity entity, ModelViewEntity modelViewEntity, List JavaDoc fieldsToSave, SQLProcessor sqlP) throws GenericEntityException {
381         GenericDelegator delegator = entity.getDelegator();
382
383         int retVal = 0;
384         ModelEntity memberModelEntity = null;
385
386         // Construct insert/update for each model entity
387
Iterator JavaDoc meIter = modelViewEntity.getMemberModelMemberEntities().entrySet().iterator();
388         while (meIter != null && meIter.hasNext()) {
389             Map.Entry JavaDoc meMapEntry = (Map.Entry JavaDoc) meIter.next();
390             ModelViewEntity.ModelMemberEntity modelMemberEntity = (ModelViewEntity.ModelMemberEntity) meMapEntry.getValue();
391             String JavaDoc meName = modelMemberEntity.getEntityName();
392             String JavaDoc meAlias = modelMemberEntity.getEntityAlias();
393
394             if (Debug.verboseOn()) Debug.logVerbose("[singleUpdateView]: Processing MemberEntity " + meName + " with Alias " + meAlias, module);
395             try {
396                 memberModelEntity = delegator.getModelReader().getModelEntity(meName);
397             } catch (GenericEntityException e) {
398                 throw new GenericEntityException("Failed to get model entity for " + meName, e);
399             }
400
401             Map JavaDoc findByMap = FastMap.newInstance();
402
403             // Now iterate the ModelViewLinks to construct the "WHERE" part for update/insert
404
Iterator JavaDoc linkIter = modelViewEntity.getViewLinksIterator();
405
406             while (linkIter != null && linkIter.hasNext()) {
407                 ModelViewEntity.ModelViewLink modelViewLink = (ModelViewEntity.ModelViewLink) linkIter.next();
408
409                 if (modelViewLink.getEntityAlias().equals(meAlias) || modelViewLink.getRelEntityAlias().equals(meAlias)) {
410
411                     Iterator JavaDoc kmIter = modelViewLink.getKeyMapsIterator();
412
413                     while (kmIter != null && kmIter.hasNext()) {
414                         ModelKeyMap keyMap = (ModelKeyMap) kmIter.next();
415
416                         String JavaDoc fieldName = "";
417
418                         if (modelViewLink.getEntityAlias().equals(meAlias)) {
419                             fieldName = keyMap.getFieldName();
420                         } else {
421                             fieldName = keyMap.getRelFieldName();
422                         }
423
424                         if (Debug.verboseOn()) Debug.logVerbose("[singleUpdateView]: --- Found field to set: " + meAlias + "." + fieldName, module);
425                         Object JavaDoc value = null;
426
427                         if (modelViewEntity.isField(keyMap.getFieldName())) {
428                             value = entity.get(keyMap.getFieldName());
429                             if (Debug.verboseOn()) Debug.logVerbose("[singleUpdateView]: --- Found map value: " + value.toString(), module);
430                         } else if (modelViewEntity.isField(keyMap.getRelFieldName())) {
431                             value = entity.get(keyMap.getRelFieldName());
432                             if (Debug.verboseOn()) Debug.logVerbose("[singleUpdateView]: --- Found map value: " + value.toString(), module);
433                         } else {
434                             throw new GenericNotImplementedException("Update on view entities: no direct link found, unable to update");
435                         }
436
437                         findByMap.put(fieldName, value);
438                     }
439                 }
440             }
441
442             // Look what there already is in the database
443
List JavaDoc meResult = null;
444
445             try {
446                 meResult = delegator.findByAnd(meName, findByMap);
447             } catch (GenericEntityException e) {
448                 throw new GenericEntityException("Error while retrieving partial results for entity member: " + meName, e);
449             }
450             if (Debug.verboseOn()) Debug.logVerbose("[singleUpdateView]: --- Found " + meResult.size() + " results for entity member " + meName, module);
451
452             // Got results 0 -> INSERT, 1 -> UPDATE, >1 -> View is nor updatable
453
GenericValue meGenericValue = null;
454
455             if (meResult.size() == 0) {
456                 // Create new value to insert
457
try {
458                     // Create new value to store
459
meGenericValue = delegator.makeValue(meName, findByMap);
460                 } catch (Exception JavaDoc e) {
461                     throw new GenericEntityException("Could not create new value for member entity" + meName + " of view " + modelViewEntity.getEntityName(), e);
462                 }
463             } else if (meResult.size() == 1) {
464                 // Update existing value
465
meGenericValue = (GenericValue) meResult.iterator().next();
466             } else {
467                 throw new GenericEntityException("Found more than one result for member entity " + meName + " in view " + modelViewEntity.getEntityName() + " - this is no updatable view");
468             }
469
470             // Construct fieldsToSave list for this member entity
471
List JavaDoc meFieldsToSave = FastList.newInstance();
472             Iterator JavaDoc fieldIter = fieldsToSave.iterator();
473
474             while (fieldIter != null && fieldIter.hasNext()) {
475                 ModelField modelField = (ModelField) fieldIter.next();
476
477                 if (memberModelEntity.isField(modelField.getName())) {
478                     ModelField meModelField = memberModelEntity.getField(modelField.getName());
479
480                     if (meModelField != null) {
481                         meGenericValue.set(meModelField.getName(), entity.get(modelField.getName()));
482                         meFieldsToSave.add(meModelField);
483                         if (Debug.verboseOn()) Debug.logVerbose("[singleUpdateView]: --- Added field to save: " + meModelField.getName() + " with value " + meGenericValue.get(meModelField.getName()), module);
484                     } else {
485                         throw new GenericEntityException("Could not get field " + modelField.getName() + " from model entity " + memberModelEntity.getEntityName());
486                     }
487                 }
488             }
489
490             /*
491              * Finally, do the insert/update
492              * TODO:
493              * Do the real inserts/updates outside the memberEntity-loop,
494              * only if all of the found member entities are updatable.
495              * This avoids partial creation of member entities, which would mean data inconsistency:
496              * If not all member entities can be updated, then none should be updated
497              */

498             if (meResult.size() == 0) {
499                 retVal += singleInsert(meGenericValue, memberModelEntity, memberModelEntity.getFieldsCopy(), sqlP);
500             } else {
501                 if (meFieldsToSave.size() > 0) {
502                     retVal += singleUpdate(meGenericValue, memberModelEntity, meFieldsToSave, sqlP);
503                 } else {
504                     if (Debug.verboseOn()) Debug.logVerbose("[singleUpdateView]: No update on member entity " + memberModelEntity.getEntityName() + " needed", module);
505                 }
506             }
507         }
508
509         return retVal;
510     }
511
512     /* ====================================================================== */
513
514     /* ====================================================================== */
515
516     public void select(GenericEntity entity) throws GenericEntityException {
517         SQLProcessor sqlP = new SQLProcessor(helperName);
518
519         try {
520             select(entity, sqlP);
521         } finally {
522             sqlP.close();
523         }
524     }
525
526     public void select(GenericEntity entity, SQLProcessor sqlP) throws GenericEntityException {
527         ModelEntity modelEntity = entity.getModelEntity();
528
529         if (modelEntity == null) {
530             throw new GenericModelException("Could not find ModelEntity record for entityName: " + entity.getEntityName());
531         }
532
533         if (modelEntity.getPksSize() <= 0) {
534             throw new GenericEntityException("Entity has no primary keys, cannot select by primary key");
535         }
536
537         StringBuffer JavaDoc sqlBuffer = new StringBuffer JavaDoc("SELECT ");
538
539         if (modelEntity.getNopksSize() > 0) {
540             sqlBuffer.append(modelEntity.colNameString(modelEntity.getNopksCopy(), ", ", "", datasourceInfo.aliasViews));
541         } else {
542             sqlBuffer.append("*");
543         }
544
545         sqlBuffer.append(SqlJdbcUtil.makeFromClause(modelEntity, datasourceInfo));
546         sqlBuffer.append(SqlJdbcUtil.makeWhereClause(modelEntity, modelEntity.getPksCopy(), entity, "AND", datasourceInfo.joinStyle));
547
548         try {
549             sqlP.prepareStatement(sqlBuffer.toString(), true, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
550             SqlJdbcUtil.setPkValues(sqlP, modelEntity, entity, modelFieldTypeReader);
551             sqlP.executeQuery();
552
553             if (sqlP.next()) {
554                 int idx = 1;
555                 Iterator JavaDoc nopkIter = modelEntity.getNopksIterator();
556                 while (nopkIter.hasNext()) {
557                     ModelField curField = (ModelField) nopkIter.next();
558                     SqlJdbcUtil.getValue(sqlP.getResultSet(), idx, curField, entity, modelFieldTypeReader);
559                     idx++;
560                 }
561
562                 entity.synchronizedWithDatasource();
563             } else {
564                 // Debug.logWarning("[GenericDAO.select]: select failed, result set was empty for entity: " + entity.toString(), module);
565
throw new GenericEntityNotFoundException("Result set was empty for entity: " + entity.toString());
566             }
567         } finally {
568             sqlP.close();
569         }
570     }
571
572     public void partialSelect(GenericEntity entity, Set JavaDoc keys) throws GenericEntityException {
573         ModelEntity modelEntity = entity.getModelEntity();
574
575         if (modelEntity == null) {
576             throw new GenericModelException("Could not find ModelEntity record for entityName: " + entity.getEntityName());
577         }
578
579         if (modelEntity instanceof ModelViewEntity) {
580             throw new org.ofbiz.entity.GenericNotImplementedException("Operation partialSelect not supported yet for view entities");
581         }
582
583         /*
584          if(entity == null || entity.<%=modelEntity.pkNameString(" == null || entity."," == null")%>) {
585          Debug.logWarning("[GenericDAO.select]: Cannot select GenericEntity: required primary key field(s) missing.", module);
586          return false;
587          }
588          */

589         // we don't want to select ALL fields, just the nonpk fields that are in the passed GenericEntity
590
List JavaDoc partialFields = FastList.newInstance();
591
592         Set JavaDoc tempKeys = new TreeSet JavaDoc(keys);
593
594         Iterator JavaDoc nopkIter = modelEntity.getNopksIterator();
595         while (nopkIter.hasNext()) {
596             ModelField curField = (ModelField) nopkIter.next();
597             if (tempKeys.contains(curField.getName())) {
598                 partialFields.add(curField);
599                 tempKeys.remove(curField.getName());
600             }
601         }
602
603         if (tempKeys.size() > 0) {
604             throw new GenericModelException("In partialSelect invalid field names specified: " + tempKeys.toString());
605         }
606
607         StringBuffer JavaDoc sqlBuffer = new StringBuffer JavaDoc("SELECT ");
608
609         if (partialFields.size() > 0) {
610             sqlBuffer.append(modelEntity.colNameString(partialFields, ", ", "", datasourceInfo.aliasViews));
611         } else {
612             sqlBuffer.append("*");
613         }
614         sqlBuffer.append(SqlJdbcUtil.makeFromClause(modelEntity, datasourceInfo));
615         sqlBuffer.append(SqlJdbcUtil.makeWhereClause(modelEntity, modelEntity.getPksCopy(), entity, "AND", datasourceInfo.joinStyle));
616
617         SQLProcessor sqlP = new SQLProcessor(helperName);
618
619         try {
620             sqlP.prepareStatement(sqlBuffer.toString(), true, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
621             SqlJdbcUtil.setPkValues(sqlP, modelEntity, entity, modelFieldTypeReader);
622             sqlP.executeQuery();
623
624             if (sqlP.next()) {
625                 for (int j = 0; j < partialFields.size(); j++) {
626                     ModelField curField = (ModelField) partialFields.get(j);
627                     SqlJdbcUtil.getValue(sqlP.getResultSet(), j + 1, curField, entity, modelFieldTypeReader);
628                 }
629
630                 entity.synchronizedWithDatasource();
631             } else {
632                 // Debug.logWarning("[GenericDAO.select]: select failed, result set was empty.", module);
633
throw new GenericEntityNotFoundException("Result set was empty for entity: " + entity.toString());
634             }
635         } finally {
636             sqlP.close();
637         }
638     }
639
640     /* ====================================================================== */
641     /* ====================================================================== */
642
643     /** Finds GenericValues by the conditions specified in the EntityCondition object, the the EntityCondition javadoc for more details.
644      *@param modelEntity The ModelEntity of the Entity as defined in the entity XML file
645      *@param whereEntityCondition The EntityCondition object that specifies how to constrain this query before any groupings are done (if this is a view entity with group-by aliases)
646      *@param havingEntityCondition The EntityCondition object that specifies how to constrain this query after any groupings are done (if this is a view entity with group-by aliases)
647      *@param fieldsToSelect The fields of the named entity to get from the database; if empty or null all fields will be retreived
648      *@param orderBy The fields of the named entity to order the query by; optionally add a " ASC" for ascending or " DESC" for descending
649      *@param findOptions An instance of EntityFindOptions that specifies advanced query options. See the EntityFindOptions JavaDoc for more details.
650      *@return EntityListIterator representing the result of the query: NOTE THAT THIS MUST BE CLOSED WHEN YOU ARE
651      * DONE WITH IT, AND DON'T LEAVE IT OPEN TOO LONG BEACUSE IT WILL MAINTAIN A DATABASE CONNECTION.
652      */

653     public EntityListIterator selectListIteratorByCondition(ModelEntity modelEntity, EntityCondition whereEntityCondition,
654             EntityCondition havingEntityCondition, Collection JavaDoc fieldsToSelect, List JavaDoc orderBy, EntityFindOptions findOptions)
655             throws GenericEntityException {
656         if (modelEntity == null) {
657             return null;
658         }
659
660         // if no find options passed, use default
661
if (findOptions == null) findOptions = new EntityFindOptions();
662
663         boolean verboseOn = Debug.verboseOn();
664
665         if (verboseOn) {
666             // put this inside an if statement so that we don't have to generate the string when not used...
667
Debug.logVerbose("Doing selectListIteratorByCondition with whereEntityCondition: " + whereEntityCondition, module);
668         }
669
670         // make two ArrayLists of fields, one for fields to select and the other for where clause fields (to find by)
671
List JavaDoc selectFields = FastList.newInstance();
672         if (fieldsToSelect != null && fieldsToSelect.size() > 0) {
673             Set JavaDoc tempKeys = FastSet.newInstance();
674             tempKeys.addAll(fieldsToSelect);
675             Iterator JavaDoc fieldIter = modelEntity.getFieldsIterator();
676             while (fieldIter.hasNext()) {
677                 ModelField curField = (ModelField) fieldIter.next();
678                 if (tempKeys.contains(curField.getName())) {
679                     selectFields.add(curField);
680                     tempKeys.remove(curField.getName());
681                 }
682             }
683
684             if (tempKeys.size() > 0) {
685                 throw new GenericModelException("In selectListIteratorByCondition invalid field names specified: " + tempKeys.toString());
686             }
687         } else {
688             selectFields = modelEntity.getFieldsCopy();
689         }
690
691         StringBuffer JavaDoc sqlBuffer = new StringBuffer JavaDoc("SELECT ");
692
693         if (findOptions.getDistinct()) {
694             sqlBuffer.append("DISTINCT ");
695         }
696
697         if (selectFields.size() > 0) {
698             sqlBuffer.append(modelEntity.colNameString(selectFields, ", ", "", datasourceInfo.aliasViews));
699         } else {
700             sqlBuffer.append("*");
701         }
702
703         // FROM clause and when necessary the JOIN or LEFT JOIN clause(s) as well
704
sqlBuffer.append(SqlJdbcUtil.makeFromClause(modelEntity, datasourceInfo));
705
706         // WHERE clause
707
StringBuffer JavaDoc whereString = new StringBuffer JavaDoc();
708         String JavaDoc entityCondWhereString = "";
709         List JavaDoc whereEntityConditionParams = FastList.newInstance();
710         if (whereEntityCondition != null) {
711             entityCondWhereString = whereEntityCondition.makeWhereString(modelEntity, whereEntityConditionParams);
712         }
713
714         String JavaDoc viewClause = SqlJdbcUtil.makeViewWhereClause(modelEntity, datasourceInfo.joinStyle);
715
716         if (viewClause.length() > 0) {
717             if (entityCondWhereString.length() > 0) {
718                 whereString.append("(");
719                 whereString.append(entityCondWhereString);
720                 whereString.append(") AND ");
721             }
722
723             whereString.append(viewClause);
724         } else {
725             whereString.append(entityCondWhereString);
726         }
727
728         if (whereString.length() > 0) {
729             sqlBuffer.append(" WHERE ");
730             sqlBuffer.append(whereString.toString());
731         }
732
733         // GROUP BY clause for view-entity
734
if (modelEntity instanceof ModelViewEntity) {
735             ModelViewEntity modelViewEntity = (ModelViewEntity) modelEntity;
736             String JavaDoc groupByString = modelViewEntity.colNameString(modelViewEntity.getGroupBysCopy(), ", ", "", false);
737
738             if (UtilValidate.isNotEmpty(groupByString)) {
739                 sqlBuffer.append(" GROUP BY ");
740                 sqlBuffer.append(groupByString);
741             }
742         }
743
744         // HAVING clause
745
String JavaDoc entityCondHavingString = "";
746         List JavaDoc havingEntityConditionParams = FastList.newInstance();
747
748         if (havingEntityCondition != null) {
749             entityCondHavingString = havingEntityCondition.makeWhereString(modelEntity, havingEntityConditionParams);
750         }
751         if (entityCondHavingString.length() > 0) {
752             sqlBuffer.append(" HAVING ");
753             sqlBuffer.append(entityCondHavingString);
754         }
755
756         // ORDER BY clause
757
sqlBuffer.append(SqlJdbcUtil.makeOrderByClause(modelEntity, orderBy, datasourceInfo));
758         String JavaDoc sql = sqlBuffer.toString();
759
760         SQLProcessor sqlP = new SQLProcessor(helperName);
761         sqlP.prepareStatement(sql, findOptions.getSpecifyTypeAndConcur(), findOptions.getResultSetType(),
762                 findOptions.getResultSetConcurrency(), findOptions.getFetchSize(), findOptions.getMaxRows());
763
764         if (verboseOn) {
765             // put this inside an if statement so that we don't have to generate the string when not used...
766
Debug.logVerbose("Setting the whereEntityConditionParams: " + whereEntityConditionParams, module);
767         }
768         // set all of the values from the Where EntityCondition
769
Iterator JavaDoc whereEntityConditionParamsIter = whereEntityConditionParams.iterator();
770         while (whereEntityConditionParamsIter.hasNext()) {
771             EntityConditionParam whereEntityConditionParam = (EntityConditionParam) whereEntityConditionParamsIter.next();
772
773             SqlJdbcUtil.setValue(sqlP, whereEntityConditionParam.getModelField(), modelEntity.getEntityName(), whereEntityConditionParam.getFieldValue(), modelFieldTypeReader);
774         }
775         if (verboseOn) {
776             // put this inside an if statement so that we don't have to generate the string when not used...
777
Debug.logVerbose("Setting the havingEntityConditionParams: " + havingEntityConditionParams, module);
778         }
779         // set all of the values from the Having EntityCondition
780
Iterator JavaDoc havingEntityConditionParamsIter = havingEntityConditionParams.iterator();
781         while (havingEntityConditionParamsIter.hasNext()) {
782             EntityConditionParam havingEntityConditionParam = (EntityConditionParam) havingEntityConditionParamsIter.next();
783
784             SqlJdbcUtil.setValue(sqlP, havingEntityConditionParam.getModelField(), modelEntity.getEntityName(), havingEntityConditionParam.getFieldValue(), modelFieldTypeReader);
785         }
786
787         long queryStartTime = 0;
788         if (Debug.timingOn()) {
789             queryStartTime = System.currentTimeMillis();
790         }
791         sqlP.executeQuery();
792         if (Debug.timingOn()) {
793             long queryEndTime = System.currentTimeMillis();
794             long queryTotalTime = queryEndTime - queryStartTime;
795             if (queryTotalTime > 150) {
796                 Debug.logTiming("Ran query in " + queryTotalTime + " milli-seconds: " + sql, module);
797             }
798         }
799         return new EntityListIterator(sqlP, modelEntity, selectFields, modelFieldTypeReader);
800     }
801
802     public List JavaDoc selectByMultiRelation(GenericValue value, ModelRelation modelRelationOne, ModelEntity modelEntityOne,
803         ModelRelation modelRelationTwo, ModelEntity modelEntityTwo, List JavaDoc orderBy) throws GenericEntityException {
804         SQLProcessor sqlP = new SQLProcessor(helperName);
805
806         // get the tables names
807
String JavaDoc atable = modelEntityOne.getTableName(datasourceInfo);
808         String JavaDoc ttable = modelEntityTwo.getTableName(datasourceInfo);
809
810         // get the column name string to select
811
StringBuffer JavaDoc selsb = new StringBuffer JavaDoc();
812         List JavaDoc collist = FastList.newInstance();
813         List JavaDoc fldlist = FastList.newInstance();
814
815         for (Iterator JavaDoc iterator = modelEntityTwo.getFieldsIterator(); iterator.hasNext();) {
816             ModelField mf = (ModelField) iterator.next();
817
818             collist.add(mf.getColName());
819             fldlist.add(mf.getName());
820             selsb.append(ttable + "." + mf.getColName());
821             if (iterator.hasNext()) {
822                 selsb.append(", ");
823             } else {
824                 selsb.append(" ");
825             }
826         }
827
828         // construct assoc->target relation string
829
int kmsize = modelRelationTwo.getKeyMapsSize();
830         StringBuffer JavaDoc wheresb = new StringBuffer JavaDoc();
831
832         for (int i = 0; i < kmsize; i++) {
833             ModelKeyMap mkm = modelRelationTwo.getKeyMap(i);
834             String JavaDoc lfname = mkm.getFieldName();
835             String JavaDoc rfname = mkm.getRelFieldName();
836
837             if (wheresb.length() > 0) {
838                 wheresb.append(" AND ");
839             }
840             wheresb.append(atable + "." + modelEntityOne.getField(lfname).getColName() + " = " + ttable + "." + modelEntityTwo.getField(rfname).getColName());
841         }
842
843         // construct the source entity qualifier
844
// get the fields from relation description
845
kmsize = modelRelationOne.getKeyMapsSize();
846         Map JavaDoc bindMap = FastMap.newInstance();
847
848         for (int i = 0; i < kmsize; i++) {
849             // get the equivalent column names in the relation
850
ModelKeyMap mkm = modelRelationOne.getKeyMap(i);
851             String JavaDoc sfldname = mkm.getFieldName();
852             String JavaDoc lfldname = mkm.getRelFieldName();
853             ModelField amf = modelEntityOne.getField(lfldname);
854             String JavaDoc lcolname = amf.getColName();
855             Object JavaDoc rvalue = value.get(sfldname);
856
857             bindMap.put(amf, rvalue);
858             // construct one condition
859
if (wheresb.length() > 0) {
860                 wheresb.append(" AND ");
861             }
862             wheresb.append(atable + "." + lcolname + " = ? ");
863         }
864
865         // construct a join sql query
866
StringBuffer JavaDoc sqlsb = new StringBuffer JavaDoc();
867
868         sqlsb.append("SELECT ");
869         sqlsb.append(selsb.toString());
870         sqlsb.append(" FROM ");
871         sqlsb.append(atable + ", " + ttable);
872         sqlsb.append(" WHERE ");
873         sqlsb.append(wheresb.toString());
874         sqlsb.append(SqlJdbcUtil.makeOrderByClause(modelEntityTwo, orderBy, true, datasourceInfo));
875
876         // now execute the query
877
List JavaDoc retlist = FastList.newInstance();
878         GenericDelegator gd = value.getDelegator();
879
880         try {
881             sqlP.prepareStatement(sqlsb.toString());
882             Set JavaDoc entrySet = bindMap.entrySet();
883
884             for (Iterator JavaDoc iterator = entrySet.iterator(); iterator.hasNext();) {
885                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
886                 ModelField mf = (ModelField) entry.getKey();
887                 Object JavaDoc curvalue = entry.getValue();
888
889                 SqlJdbcUtil.setValue(sqlP, mf, modelEntityOne.getEntityName(), curvalue, modelFieldTypeReader);
890             }
891             sqlP.executeQuery();
892             //int collsize = collist.size();
893

894             while (sqlP.next()) {
895                 GenericValue gv = gd.makeValue(modelEntityTwo.getEntityName(), Collections.EMPTY_MAP);
896
897                 // loop thru all columns for in one row
898
int idx = 1;
899                 Iterator JavaDoc fldIter = fldlist.iterator();
900                 while (fldIter.hasNext()) {
901                     String JavaDoc fldname = (String JavaDoc) fldIter.next();
902                     ModelField mf = modelEntityTwo.getField(fldname);
903                     SqlJdbcUtil.getValue(sqlP.getResultSet(), idx, mf, gv, modelFieldTypeReader);
904                     idx++;
905                 }
906                 retlist.add(gv);
907             }
908         } finally {
909             sqlP.close();
910         }
911
912         return retlist;
913     }
914
915     public long selectCountByCondition(ModelEntity modelEntity, EntityCondition whereEntityCondition, EntityCondition havingEntityCondition) throws GenericEntityException {
916         if (modelEntity == null) {
917             return 0;
918         }
919
920         // if no find options passed, use default
921
EntityFindOptions findOptions = new EntityFindOptions();
922         boolean verboseOn = Debug.verboseOn();
923
924         if (verboseOn) {
925             // put this inside an if statement so that we don't have to generate the string when not used...
926
Debug.logVerbose("Doing selectListIteratorByCondition with whereEntityCondition: " + whereEntityCondition, module);
927         }
928
929         StringBuffer JavaDoc sqlBuffer = new StringBuffer JavaDoc("SELECT ");
930
931         if (findOptions.getDistinct()) {
932             sqlBuffer.append("DISTINCT ");
933         }
934
935         sqlBuffer.append("COUNT(*) ");
936
937         // FROM clause and when necessary the JOIN or LEFT JOIN clause(s) as well
938
sqlBuffer.append(SqlJdbcUtil.makeFromClause(modelEntity, datasourceInfo));
939
940         // WHERE clause
941
StringBuffer JavaDoc whereString = new StringBuffer JavaDoc();
942         String JavaDoc entityCondWhereString = "";
943         List JavaDoc whereEntityConditionParams = FastList.newInstance();
944         if (whereEntityCondition != null) {
945             entityCondWhereString = whereEntityCondition.makeWhereString(modelEntity, whereEntityConditionParams);
946         }
947
948         String JavaDoc viewClause = SqlJdbcUtil.makeViewWhereClause(modelEntity, datasourceInfo.joinStyle);
949
950         if (viewClause.length() > 0) {
951             if (entityCondWhereString.length() > 0) {
952                 whereString.append("(");
953                 whereString.append(entityCondWhereString);
954                 whereString.append(") AND ");
955             }
956
957             whereString.append(viewClause);
958         } else {
959             whereString.append(entityCondWhereString);
960         }
961
962         if (whereString.length() > 0) {
963             sqlBuffer.append(" WHERE ");
964             sqlBuffer.append(whereString.toString());
965         }
966
967         // GROUP BY clause for view-entity
968
if (modelEntity instanceof ModelViewEntity) {
969             ModelViewEntity modelViewEntity = (ModelViewEntity) modelEntity;
970             String JavaDoc groupByString = modelViewEntity.colNameString(modelViewEntity.getGroupBysCopy(), ", ", "", false);
971
972             if (UtilValidate.isNotEmpty(groupByString)) {
973                 sqlBuffer.append(" GROUP BY ");
974                 sqlBuffer.append(groupByString);
975             }
976         }
977
978         // HAVING clause
979
String JavaDoc entityCondHavingString = "";
980         List JavaDoc havingEntityConditionParams = FastList.newInstance();
981         if (havingEntityCondition != null) {
982             entityCondHavingString = havingEntityCondition.makeWhereString(modelEntity, havingEntityConditionParams);
983         }
984         if (entityCondHavingString.length() > 0) {
985             sqlBuffer.append(" HAVING ");
986             sqlBuffer.append(entityCondHavingString);
987         }
988
989         String JavaDoc sql = sqlBuffer.toString();
990
991         SQLProcessor sqlP = new SQLProcessor(helperName);
992         sqlP.prepareStatement(sql, findOptions.getSpecifyTypeAndConcur(), findOptions.getResultSetType(), findOptions.getResultSetConcurrency());
993         if (verboseOn) {
994             // put this inside an if statement so that we don't have to generate the string when not used...
995
Debug.logVerbose("Setting the whereEntityConditionParams: " + whereEntityConditionParams, module);
996         }
997         // set all of the values from the Where EntityCondition
998
Iterator JavaDoc whereEntityConditionParamsIter = whereEntityConditionParams.iterator();
999         while (whereEntityConditionParamsIter.hasNext()) {
1000            EntityConditionParam whereEntityConditionParam = (EntityConditionParam) whereEntityConditionParamsIter.next();
1001            SqlJdbcUtil.setValue(sqlP, whereEntityConditionParam.getModelField(), modelEntity.getEntityName(), whereEntityConditionParam.getFieldValue(), modelFieldTypeReader);
1002        }
1003        if (verboseOn) {
1004            // put this inside an if statement so that we don't have to generate the string when not used...
1005
Debug.logVerbose("Setting the havingEntityConditionParams: " + havingEntityConditionParams, module);
1006        }
1007        // set all of the values from the Having EntityCondition
1008
Iterator JavaDoc havingEntityConditionParamsIter = havingEntityConditionParams.iterator();
1009        while (havingEntityConditionParamsIter.hasNext()) {
1010            EntityConditionParam havingEntityConditionParam = (EntityConditionParam) havingEntityConditionParamsIter.next();
1011            SqlJdbcUtil.setValue(sqlP, havingEntityConditionParam.getModelField(), modelEntity.getEntityName(), havingEntityConditionParam.getFieldValue(), modelFieldTypeReader);
1012        }
1013
1014
1015        try {
1016            sqlP.executeQuery();
1017            long count = 0;
1018            ResultSet JavaDoc resultSet = sqlP.getResultSet();
1019            if (resultSet.next()) {
1020                count = resultSet.getLong(1);
1021            }
1022            return count;
1023        } catch (SQLException JavaDoc e) {
1024            throw new GenericDataSourceException("Error getting count value", e);
1025        } finally {
1026            sqlP.close();
1027        }
1028    }
1029
1030    /* ====================================================================== */
1031
1032    /* ====================================================================== */
1033
1034    public int delete(GenericEntity entity) throws GenericEntityException {
1035        SQLProcessor sqlP = new SQLProcessor(helperName);
1036
1037        try {
1038            return delete(entity, sqlP);
1039        } catch (GenericDataSourceException e) {
1040            sqlP.rollback();
1041            throw new GenericDataSourceException("Exception while deleting the following entity: " + entity.toString(), e);
1042        } finally {
1043            sqlP.close();
1044        }
1045    }
1046
1047    public int delete(GenericEntity entity, SQLProcessor sqlP) throws GenericEntityException {
1048        ModelEntity modelEntity = entity.getModelEntity();
1049        if (modelEntity == null) {
1050            throw new GenericModelException("Could not find ModelEntity record for entityName: " + entity.getEntityName());
1051        }
1052        if (modelEntity instanceof ModelViewEntity) {
1053            throw new org.ofbiz.entity.GenericNotImplementedException("Operation delete not supported yet for view entities");
1054        }
1055
1056        String JavaDoc sql = "DELETE FROM " + modelEntity.getTableName(datasourceInfo) + " WHERE " + SqlJdbcUtil.makeWhereStringFromFields(modelEntity.getPksCopy(), entity, "AND");
1057
1058        int retVal;
1059
1060        try {
1061            sqlP.prepareStatement(sql);
1062            SqlJdbcUtil.setPkValues(sqlP, modelEntity, entity, modelFieldTypeReader);
1063            retVal = sqlP.executeUpdate();
1064            entity.removedFromDatasource();
1065        } finally {
1066            sqlP.close();
1067        }
1068        return retVal;
1069    }
1070
1071    public int deleteByCondition(ModelEntity modelEntity, EntityCondition condition) throws GenericEntityException {
1072        SQLProcessor sqlP = new SQLProcessor(helperName);
1073
1074        try {
1075            return deleteByCondition(modelEntity, condition, sqlP);
1076        } catch (GenericDataSourceException e) {
1077            sqlP.rollback();
1078            throw new GenericDataSourceException("Generic Entity Exception occured in deleteByCondition", e);
1079        } finally {
1080            sqlP.close();
1081        }
1082    }
1083
1084    public int deleteByCondition(ModelEntity modelEntity, EntityCondition condition, SQLProcessor sqlP) throws GenericEntityException {
1085        if (modelEntity == null || condition == null)
1086            return 0;
1087        if (modelEntity instanceof ModelViewEntity) {
1088            throw new org.ofbiz.entity.GenericNotImplementedException("Operation deleteByCondition not supported yet for view entities");
1089        }
1090
1091        String JavaDoc sql = "DELETE FROM " + modelEntity.getTableName(datasourceInfo);
1092
1093        sql += " WHERE " + condition.makeWhereString(modelEntity, null);
1094
1095        try {
1096            sqlP.prepareStatement(sql);
1097
1098            return sqlP.executeUpdate();
1099        } finally {
1100            sqlP.close();
1101        }
1102    }
1103
1104    /* ====================================================================== */
1105
1106    public void checkDb(Map JavaDoc modelEntities, List JavaDoc messages, boolean addMissing) {
1107        DatabaseUtil dbUtil = new DatabaseUtil(this.helperName);
1108        dbUtil.checkDb(modelEntities, messages, addMissing);
1109    }
1110
1111    /** Creates a list of ModelEntity objects based on meta data from the database */
1112    public List JavaDoc induceModelFromDb(Collection JavaDoc messages) {
1113        DatabaseUtil dbUtil = new DatabaseUtil(this.helperName);
1114        return dbUtil.induceModelFromDb(messages);
1115    }
1116}
1117
Popular Tags