Author: nmalin
Date: Sat Nov 8 21:00:55 2014
New Revision: 1637596
URL: http://svn.apache.org/r1637596
Log:
Manage multi pk with sub-sequence on entity-auto (OFBIZ-5800),
Add the possibility to the entity-auto engine on the create action to manage
entities with more than 2 primary keys which one is under sub sequence or
fromDate, like PerfReview (employeePartyId, employeeRoleTypeId, perfReviewId)
or PartyQual (partyId, partyQualTypeId, fromDate).
Improve return message for the create action if the entity value exist and the
delete action if the entity value not exist instead of the database message
error.
Modified:
ofbiz/trunk/framework/service/config/ServiceErrorUiLabels.xml
ofbiz/trunk/framework/service/servicedef/services_test_se.xml
ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java
ofbiz/trunk/framework/service/src/org/ofbiz/service/test/ServiceEntityAutoTests.java
Modified: ofbiz/trunk/framework/service/config/ServiceErrorUiLabels.xml
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/config/ServiceErrorUiLabels.xml?rev=1637596&r1=1637595&r2=1637596&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/config/ServiceErrorUiLabels.xml (original)
+++ ofbiz/trunk/framework/service/config/ServiceErrorUiLabels.xml Sat Nov 8
21:00:55 2014
@@ -272,11 +272,22 @@
<value xml:lang="zh">缺å°åæ°</value>
<value xml:lang="zh_TW">缺å°åæ¸</value>
</property>
+ <property key="ServiceValueFound">
+ <value xml:lang="en">Value found (with ids ${pkFields}), cannot create
a new one</value>
+ <value xml:lang="fr">La valeur a été trouvée (avec les réfs.
${pkFields}), une nouvelle ne peut donc pas être créée</value>
+ <value xml:lang="it">Valore troavato, non è possibile creare</value>
+ </property>
<property key="ServiceValueNotFound">
<value xml:lang="en">Value not found, cannot update</value>
+ <value xml:lang="fr">La valeur n'a pas été trouvée, elle ne peut
donc pas être mise à jour</value>
<value xml:lang="it">Valore non troavato, non è possibile
aggiornare</value>
<value
xml:lang="ja">å¤ãè¦ã¤ããã¾ãããæ´æ°ã§ãã¾ãã</value>
<value xml:lang="zh">æ²¡ææ¾å°å¼ï¼æ æ³æ´æ°</value>
<value xml:lang="zh_TW">æ²ææ¾å°å¼,ç¡æ³æ´æ°</value>
</property>
+ <property key="ServiceValueNotFoundForRemove">
+ <value xml:lang="en">Value not found, cannot remove</value>
+ <value xml:lang="fr">La valeur n'a pas été trouvée, suppression
impossible</value>
+ <value xml:lang="it">Valore non troavato, non è possibile
sopprimere</value>
+ </property>
</resource>
Modified: ofbiz/trunk/framework/service/servicedef/services_test_se.xml
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/servicedef/services_test_se.xml?rev=1637596&r1=1637595&r2=1637596&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/servicedef/services_test_se.xml (original)
+++ ofbiz/trunk/framework/service/servicedef/services_test_se.xml Sat Nov 8
21:00:55 2014
@@ -80,7 +80,7 @@ under the License.
<auto-attributes include="nonpk" mode="IN" optional="true"/>
<attribute name="testingId" mode="IN" type="String"/>
<attribute name="testingNodeId" mode="IN" type="String"/>
- <attribute name="fromDate" mode="OUT" type="String"/>
+ <attribute name="fromDate" mode="OUT" type="Timestamp"/>
</service>
<service name="testEntityAutoUpdateTesting" auth="false"
engine="entity-auto" default-entity-name="Testing" invoke="update">
Modified:
ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java?rev=1637596&r1=1637595&r2=1637596&view=diff
==============================================================================
---
ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java
(original)
+++
ofbiz/trunk/framework/service/src/org/ofbiz/service/engine/EntityAutoEngine.java
Sat Nov 8 21:00:55 2014
@@ -20,6 +20,7 @@ package org.ofbiz.service.engine;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
@@ -88,11 +89,16 @@ public final class EntityAutoEngine exte
try {
boolean allPksInOnly = true;
+ LinkedList<String> pkFieldNameOutOnly = null;
for (ModelField pkField: modelEntity.getPkFieldsUnmodifiable()) {
ModelParam pkParam = modelService.getParam(pkField.getName());
if (pkParam.isOut()) {
allPksInOnly = false;
}
+ if (pkParam.isOut() && !pkParam.isIn()) {
+ if (pkFieldNameOutOnly == null) pkFieldNameOutOnly = new
LinkedList();
+ pkFieldNameOutOnly.add(pkField.getName());
+ }
}
if ("create".equals(modelService.invoke)) {
@@ -128,7 +134,6 @@ public final class EntityAutoEngine exte
}
}
-
if (isSinglePk && isSinglePkOut && !isSinglePkIn) {
/*
**** primary sequenced primary key ****
@@ -145,7 +150,6 @@ public final class EntityAutoEngine exte
String sequencedId =
dctx.getDelegator().getNextSeqId(modelEntity.getEntityName());
newEntity.set(singlePkModeField.getName(), sequencedId);
- result.put(singlePkModelParam.name, sequencedId);
} else if (isSinglePk && isSinglePkOut && isSinglePkIn) {
/*
**** primary sequenced key with optional override passed
in ****
@@ -181,7 +185,6 @@ public final class EntityAutoEngine exte
}
}
newEntity.set(singlePkModeField.getName(), pkValue);
- result.put(singlePkModelParam.name, pkValue);
} else if (isDoublePk && doublePkPrimaryInParam != null &&
doublePkSecondaryOutParam != null) {
/*
**** secondary sequenced primary key ****
@@ -199,7 +202,6 @@ public final class EntityAutoEngine exte
newEntity.setPKFields(parameters, true);
dctx.getDelegator().setNextSubSeqId(newEntity,
doublePkSecondaryOutField.getName(), 5, 1);
- result.put(doublePkSecondaryOutParam.name,
newEntity.get(doublePkSecondaryOutField.getName()));
} else if (allPksInOnly) {
/*
**** plain specified primary key ****
@@ -213,24 +215,46 @@ public final class EntityAutoEngine exte
*
*/
newEntity.setPKFields(parameters, true);
+ //with all pks present on parameters, check if the entity
is not already exists.
+ GenericValue lookedUpValue =
PrimaryKeyFinder.runFind(modelEntity, parameters, dctx.getDelegator(), false,
true, null, null);
+ if (lookedUpValue != null) {
+ return
ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ServiceValueFound", UtilMisc.toMap("pkFields",
newEntity.getPkShortValueString()), locale));
+ }
} else {
- throw new GenericServiceException("In Service [" +
modelService.name + "] which uses the entity-auto engine with the create invoke
option: " +
- "could not find a valid combination of primary key
settings to do a known create operation; options include: " +
- "1. a single OUT pk for primary auto-sequencing, "
+
- "2. a single INOUT pk for primary auto-sequencing
with optional override, " +
- "3. a 2-part pk with one part IN (existing primary
pk) and one part OUT (the secdonary pk to sub-sequence, " +
- "4. all pk fields are IN for a manually specified
primary key");
+ /* We haven't all Pk and their are 3 or more, now check if
isn't a associate entity with own sequence
+ <set-pk-fields map="parameters" value-field="newEntity"/>
+ <sequenced-id sequence-name="ExempleItemAssoc"
field="newEntity.exempleItemAssocId"/>
+ <create-value value-field="newEntity"/>
+ */
+ if (pkFieldNameOutOnly != null &&
pkFieldNameOutOnly.size() == 1) {
+ newEntity.setPKFields(parameters, true);
+ String pkFieldName = pkFieldNameOutOnly.getFirst();
+ //if it's a fromDate, don't update it now, it's will
be done next step
+ if (! "fromDate".equals(pkFieldName)) {
+ String pkValue =
dctx.getDelegator().getNextSeqId(modelEntity.getEntityName());
+ newEntity.set(pkFieldName, pkValue);
+ }
+ } else {
+ throw new GenericServiceException("In Service [" +
modelService.name + "] which uses the entity-auto engine with the create invoke
option: " +
+ "could not find a valid combination of primary
key settings to do a known create operation; options include: " +
+ "1. a single OUT pk for primary
auto-sequencing, " +
+ "2. a single INOUT pk for primary
auto-sequencing with optional override, " +
+ "3. a 2-part pk with one part IN (existing
primary pk) and one part OUT (the secondary pk to sub-sequence), " +
+ "4. a N-part pk with N-1 part IN and one party
OUT only (missing pk is a sub-sequence mainly for entity assoc), " +
+ "5. all pk fields are IN for a manually
specified primary key");
+ }
}
// handle the case where there is a fromDate in the pk of the
entity, and it is optional or undefined in the service def, populate
automatically
ModelField fromDateField = modelEntity.getField("fromDate");
if (fromDateField != null && fromDateField.getIsPk()) {
ModelParam fromDateParam =
modelService.getParam("fromDate");
- if (fromDateParam == null || (fromDateParam.isOptional()
&& parameters.get("fromDate") == null)) {
+ if (fromDateParam == null || parameters.get("fromDate") ==
null) {
newEntity.set("fromDate", UtilDateTime.nowTimestamp());
}
}
+ newEntity.setNonPKFields(parameters, true);
if (modelEntity.getField("createdDate") != null) {
newEntity.set("createdDate", UtilDateTime.nowTimestamp());
if (modelEntity.getField("createdByUserLogin") != null) {
@@ -246,8 +270,8 @@ public final class EntityAutoEngine exte
newEntity.set("lastModifiedDate",
UtilDateTime.nowTimestamp());
}
}
- newEntity.setNonPKFields(parameters, true);
newEntity.create();
+ result.putAll(modelService.makeValid(newEntity, "OUT"));
} else if ("update".equals(modelService.invoke)) {
/*
<auto-attributes include="pk" mode="IN" optional="false"/>
@@ -313,9 +337,9 @@ public final class EntityAutoEngine exte
}
}
}
-
// NOTE: nothing here to maintain the status history, that
should be done with a custom service called by SECA rule
+ lookedUpValue.setNonPKFields(parameters, true);
if (modelEntity.getField("lastModifiedDate") != null) {
lookedUpValue.set("lastModifiedDate",
UtilDateTime.nowTimestamp());
if (modelEntity.getField("lastModifiedByUserLogin") !=
null) {
@@ -325,8 +349,6 @@ public final class EntityAutoEngine exte
}
}
}
-
- lookedUpValue.setNonPKFields(parameters, true);
lookedUpValue.store();
} else if ("delete".equals(modelService.invoke)) {
/*
@@ -344,6 +366,8 @@ public final class EntityAutoEngine exte
GenericValue lookedUpValue =
PrimaryKeyFinder.runFind(modelEntity, parameters, dctx.getDelegator(), false,
true, null, null);
if (lookedUpValue != null) {
lookedUpValue.remove();
+ } else {
+ return
ServiceUtil.returnError(UtilProperties.getMessage(resource,
"ServiceValueNotFoundForRemove", locale));
}
}
} catch (GeneralException e) {
Modified:
ofbiz/trunk/framework/service/src/org/ofbiz/service/test/ServiceEntityAutoTests.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/test/ServiceEntityAutoTests.java?rev=1637596&r1=1637595&r2=1637596&view=diff
==============================================================================
---
ofbiz/trunk/framework/service/src/org/ofbiz/service/test/ServiceEntityAutoTests.java
(original)
+++
ofbiz/trunk/framework/service/src/org/ofbiz/service/test/ServiceEntityAutoTests.java
Sat Nov 8 21:00:55 2014
@@ -104,11 +104,10 @@ public class ServiceEntityAutoTests exte
testingNodeMember.remove();
//test create auto sub-sequence
- //test missing pk
+ //test missing pk fromDate
Map<String, Object> testingNodeMemberPkMissingMap =
UtilMisc.toMap("testingId", "TESTING_3", "testingNodeId", "NODE_1");
results =
dispatcher.runSync("testEntityAutoCreateTestingNodeMemberPkMissing",
testingNodeMemberPkMissingMap, 10, true);
- assertTrue(ServiceUtil.isError(results));
- assertTrue(ServiceUtil.getErrorMessage(results).contains("1. a single
OUT pk for primary auto-sequencing"));
+ assertTrue(ServiceUtil.isSuccess(results));
}
public void testEntityAutoUpdateEntity() throws Exception {
@@ -141,7 +140,7 @@ public class ServiceEntityAutoTests exte
//test create with bad pk
Map<String, Object> testingDeleteFailedMap =
UtilMisc.toMap("testingId", "TESTING_5_FAILED");
results = dispatcher.runSync("testEntityAutoRemoveTesting",
testingDeleteFailedMap);
- assertTrue(ServiceUtil.isSuccess(results));
- //assertEquals(UtilProperties.getMessage("ServiceErrorUiLabels",
"ServiceValueNotFound", Locale.ENGLISH), ServiceUtil.getErrorMessage(results));
+ assertTrue(ServiceUtil.isError(results));
+ assertEquals(UtilProperties.getMessage("ServiceErrorUiLabels",
"ServiceValueNotFoundForRemove", Locale.ENGLISH),
ServiceUtil.getErrorMessage(results));
}
}