I have my own editing contexts, one per component to be more specific, and I'm using the MultiECLockManager to handle the lock/unlock, also I don't use additional threads, here is more code, maybe something is wrong in it:

public void deleteItem() {

transaction.removeObjectFromBothSidesOfRelationshipWithKey(transactionDetailIterator, "inventorytransdetails");
ec.deleteObject(transactionDetailIterator);
}

the above method is used to remove details from the header, before saving changes I call this method in InventoryTransHeader to update the inventory:

public void updateInventory() throws InsuficientMaterialException {
try {
EOEditingContext ec = editingContext();
ec.refaultAllObjects();
ec.setFetchTimestamp(System.currentTimeMillis());
for (Enumeration enum = inventorytransdetailsSorted().objectEnumerator(); enum.hasMoreElements(); ) {
InventoryTransDetail iterator = (InventoryTransDetail)enum.nextElement();
if (iterator.product() == null || iterator.location() == null) throw new NullPointerException();
Inventory inventory = iterator.location().getInventory(iterator.product(), iterator.prefix(), iterator.lot(), iterator.materialStatus());
if (inventory == null && iterator.transsign().intValue() == 1) {
inventory = new Inventory();
ec.insertObject(inventory);

inventory.addObjectToBothSidesOfRelationshipWithKey(iterator.location(), "location");

inventory.addObjectToBothSidesOfRelationshipWithKey(iterator.product(), "product");
inventory.setPrefix(iterator.prefix());
inventory.setLot(iterator.lot());
inventory.setSecondarylot(iterator.secondarylot());
inventory.setStatus(Constant.STATUS_ENABLED);
inventory.setQty(iterator.qty());
}
else {
if (inventory == null || (iterator.transsign().intValue() == -1 && inventory.qty().compareTo(iterator.qty()) < 0)) {

throw new InsuficientMaterialException(iterator);
}
else {
if (iterator.lot() == null) {
iterator.setPrefix(inventory.prefix());
iterator.setLot(inventory.lot());
}

inventory.setQty(inventory.qty().add(iterator.qty().multiply(iterator.transsign())));
}
}
}
if (ec.hasChanges()) {
if (ec.updatedObjects() != null && ec.updatedObjects().count() > 0) {
for (Enumeration enum = ec.updatedObjects().objectEnumerator(); enum.hasMoreElements(); ) {
EOEnterpriseObject eo = (EOEnterpriseObject)enum.nextElement();
if (eo instanceof Inventory && !ec.insertedObjects().containsObject(eo)) {

if (((Inventory)eo).qty().compareTo(Constant.ZERO) == 0) {

eo.removeObjectFromBothSidesOfRelationshipWithKey(((Inventory)eo).location(), "location");

eo.removeObjectFromBothSidesOfRelationshipWithKey(((Inventory)eo).product(), "product");
ec.deleteObject(eo);
}
}
}
}
}
}
catch (NullPointerException e) {
throw new InsuficientMaterialException("Concurrency conflict, inventory entry deleted, moved or changed by someone else");
}
}

the method to save changes look like this:

public void save() throws InsuficientMaterialException {

transaction.updateInventory();
ec.saveChanges();
}


What am I doing wrong?

Cheers


On Aug 1, 2006, at 1:36 PM, Chuck Hill wrote:

On Aug 1, 2006, at 11:28 AM, Marcos Trejo Munguia wrote:

Thank you Chuck,

I'll check what I have in the editing context before saving changes, I'm 100% sure that productSelected.editingContext() == ec.
I just have to wait until the error appears again, because actually the error only appears in deployment and not all the time, annoying right? :-)

OK, that is a different problem. That sounds like a concurrency issue. Are you creating your own editing contexts? Are you locking them properly? Are you creating additional threads in your code?

Chuck


On Jul 31, 2006, at 11:35 PM, Chuck Hill wrote:

On Jul 31, 2006, at 4:34 PM, Marcos Trejo Munguia wrote:

Actually the relationship is to-many,

Well, I guess we can discard that theory. :-)


Here is the code that adds details to the header:

public void addItem() {
boolean addItemFailed = false;
if (productSelected == null) {
errors.takeValueForKey("Product is required", "product");
addItemFailed = true;
}
if (locationSelected == null) {
errors.takeValueForKey("Location is required", "location");
addItemFailed = true;
}
if (quantity == null) {
errors.takeValueForKey("Qty is required", "quantity");
addItemFailed = true;
} else if (quantity.doubleValue() <= 0) {
errors.takeValueForKey("Qty must be greater than 0", "quantity");
addItemFailed = true;
}

if (!addItemFailed) {
InventoryTransDetail transactionDetail = new InventoryTransDetail();
ec.insertObject(transactionDetail);

transaction.addObjectToBothSidesOfRelationshipWithKey(transactionDetail, "inventorytransdetails");
transactionDetail.setTranssign(Constant.ONE);
transactionDetail.setProduct(productSelected);
transactionDetail.setLocation(locationSelected);
transactionDetail.setSecondarylot(secondaryLot);
transactionDetail.setQty(quantity);
}
}

That looks fine.


Here is the code that throws the validation exception, this validateXXX are in the class InventoryTransDetail:

public Product validateProduct(Product newValue) throws NSValidation.ValidationException {
if (newValue == null) {
throw new NSValidation.ValidationException("Product is required");
}
return newValue;
}

Again, that looks fine.


I hope you can help me, I'll really appreciate any help with this, I have been struggling with this error for 6 months more less.

It still sounds to me like there is some other InventoryTransDetail object in that editing context. Have you tried printing out ec.insertedObjects() just before calling ec.saveChanges()? Is productSelected.editingContext() == ec?


Chuck


On Jul 31, 2006, at 5:39 PM, Chuck Hill wrote:

You probably have Propagate Primary Key set on this relationship. If the relationship is to-one and Propagate Primary Key is set, EOF will automatically create the object that is the destination of the relationship. You then create it again in your code, but the object that EOF created is still in the editing context, will all null values.

Chuck

On Jul 31, 2006, at 2:12 PM, Marcos Trejo Munguia wrote:

Hi list:
I've been having a problem with a validation exception that must not be happening, here is the stack trace:

com.webobjects.foundation.NSValidation$ValidationException: Product is required
at InventoryTransDetail.validateProduct(InventoryTransDetail.java:43)
at sun.reflect.GeneratedMethodAccessor82.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.webobjects.foundation._NSReflectionUtilities._invokeMethodOnObject(_NSReflectionUtilities.java:383)
at com.webobjects.foundation.NSValidation$_MethodBinding.validateValueOnObject(NSValidation.java:615)
at com.webobjects.foundation.NSValidation$DefaultImplementation._validateValueForKey(NSValidation.java:705)
at com.webobjects.eocontrol.EOCustomObject.validateValueForKey(EOCustomObject.java:1341)
at com.webobjects.eocontrol.EOCustomObject.validateForSave(EOCustomObject.java:1411)
at com.webobjects.eocontrol.EOCustomObject.validateForInsert(EOCustomObject.java:1473)
at com.webobjects.eocontrol.EOEditingContext.validateTable(EOEditingContext.java:2188)
at com.webobjects.eocontrol.EOEditingContext.validateChangesForSave(EOEditingContext.java:2968)
at com.webobjects.eocontrol.EOEditingContext._prepareForPushChanges(EOEditingContext.java:3222)
at com.webobjects.eocontrol.EOEditingContext.saveChanges(EOEditingContext.java:3152)
at ProductionReturn.save(ProductionReturn.java:240)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at KeyValueCodingProtectedAccessor.methodValue(KeyValueCodingProtectedAccessor.java:54)
at com.webobjects.foundation.NSKeyValueCoding$_MethodBinding.valueInObject(NSKeyValueCoding.java:1160)
at com.webobjects.foundation.NSKeyValueCoding$DefaultImplementation.valueForKey(NSKeyValueCoding.java:1268)
at com.webobjects.appserver.WOComponent.valueForKey(WOComponent.java:1539)
at com.webobjects.foundation.NSKeyValueCoding$Utility.valueForKey(NSKeyValueCoding.java:498)
at com.webobjects.foundation.NSKeyValueCodingAdditions$DefaultImplementation.valueForKeyPath(NSKeyValueCodingAdditions.java:212)
at com.webobjects.appserver.WOComponent.valueForKeyPath(WOComponent.java:1600)
at com.webobjects.appserver._private.WOKeyValueAssociation.valueInComponent(WOKeyValueAssociation.java:46)
at com.webobjects.appserver._private.WOActiveImage.invokeAction(WOActiveImage.java:255)
at com.webobjects.appserver._private.WODynamicGroup.invokeChildrenAction(WODynamicGroup.java:101)
at com.webobjects.appserver._private.WODynamicGroup.invokeAction(WODynamicGroup.java:110)
at com.webobjects.appserver._private.WOConditional.invokeAction(WOConditional.java:55)
at com.webobjects.appserver._private.WODynamicGroup.invokeChildrenAction(WODynamicGroup.java:101)
at com.webobjects.appserver._private.WODynamicGroup.invokeAction(WODynamicGroup.java:110)
at com.webobjects.appserver._private.WOConditional.invokeAction(WOConditional.java:55)
at com.webobjects.appserver._private.WODynamicGroup.invokeChildrenAction(WODynamicGroup.java:101)
at com.webobjects.appserver._private.WODynamicGroup.invokeAction(WODynamicGroup.java:110)
at com.webobjects.appserver._private.WOConditional.invokeAction(WOConditional.java:55)
at com.webobjects.appserver._private.WODynamicGroup.invokeChildrenAction(WODynamicGroup.java:101)
at com.webobjects.appserver._private.WODynamicGroup.invokeAction(WODynamicGroup.java:110)
at com.webobjects.appserver._private.WOForm.invokeAction(WOForm.java:82)
at com.webobjects.appserver._private.WODynamicGroup.invokeChildrenAction(WODynamicGroup.java:101)
at com.webobjects.appserver._private.WODynamicGroup.invokeAction(WODynamicGroup.java:110)
at com.webobjects.appserver._private.WOConditional.invokeAction(WOConditional.java:55)
at com.webobjects.appserver._private.WODynamicGroup.invokeChildrenAction(WODynamicGroup.java:101)
at com.webobjects.appserver._private.WODynamicGroup.invokeAction(WODynamicGroup.java:110)
at com.webobjects.appserver.WOComponent.invokeAction(WOComponent.java:945)
at com.webobjects.appserver._private.WOComponentReference.invokeAction(WOComponentReference.java:104)
at com.webobjects.appserver._private.WOSwitchComponent.invokeAction(WOSwitchComponent.java:171)
at com.webobjects.appserver._private.WOComponentContent.invokeAction(WOComponentContent.java:31)
at com.webobjects.appserver._private.WODynamicGroup.invokeChildrenAction(WODynamicGroup.java:101)
at com.webobjects.appserver._private.WOGenericContainer.invokeAction(WOGenericContainer.java:23)
at com.webobjects.appserver._private.WODynamicGroup.invokeChildrenAction(WODynamicGroup.java:101)
at com.webobjects.appserver._private.WOGenericContainer.invokeAction(WOGenericContainer.java:23)
at com.webobjects.appserver._private.WODynamicGroup.invokeChildrenAction(WODynamicGroup.java:101)
at com.webobjects.appserver._private.WODynamicGroup.invokeAction(WODynamicGroup.java:110)
at com.webobjects.appserver.WOComponent.invokeAction(WOComponent.java:945)
at com.webobjects.appserver._private.WOComponentReference.invokeAction(WOComponentReference.java:104)
at com.webobjects.appserver._private.WODynamicGroup.invokeChildrenAction(WODynamicGroup.java:101)
at com.webobjects.appserver._private.WODynamicGroup.invokeAction(WODynamicGroup.java:110)
at com.webobjects.appserver.WOComponent.invokeAction(WOComponent.java:945)
at com.webobjects.appserver.WOSession.invokeAction(WOSession.java:1166)
at com.webobjects.appserver.WOApplication.invokeAction(WOApplication.java:1375)
at com.webobjects.appserver._private.WOComponentRequestHandler._dispatchWithPreparedPage(WOComponentRequestHandler.java:196)
at com.webobjects.appserver._private.WOComponentRequestHandler._dispatchWithPreparedSession(WOComponentRequestHandler.java:287)
at com.webobjects.appserver._private.WOComponentRequestHandler._dispatchWithPreparedApplication(WOComponentRequestHandler.java:322)
at com.webobjects.appserver._private.WOComponentRequestHandler._handleRequest(WOComponentRequestHandler.java:358)
at com.webobjects.appserver._private.WOComponentRequestHandler.handleRequest(WOComponentRequestHandler.java:432)
at com.webobjects.appserver.WOApplication.dispatchRequest(WOApplication.java:1306)
at com.webobjects.appserver._private.WOWorkerThread.runOnce(WOWorkerThread.java:173)
at com.webobjects.appserver._private.WOWorkerThread.run(WOWorkerThread.java:254)
at java.lang.Thread.run(Unknown Source)

I'm using two tables(master-detail), the master is inserted in the EC when the component is loaded, then you can add details, the details are only created and inserted in the EC if the variables holding the values pass some validations(same validations are implemented in validateXXX methods in EO class), one of the validations is the one that is being thrown in saveChanges(). I've no idea of what I'm doing wrong. If you need a copy of the code and the component please let me now. I'll appreciate any help.

Thanks in advanced!


--
Coming in late 2006 - an introduction to web applications using WebObjects and Xcode http://www.global-village.net/wointro

Practical WebObjects - for developers who want to increase their overall knowledge of WebObjects or who are trying to solve specific problems. http://www.global-village.net/products/practical_webobjects





--
Coming sometime... - an introduction to web applications using WebObjects and Xcode http://www.global-village.net/wointro

Practical WebObjects - for developers who want to increase their overall knowledge of WebObjects or who are trying to solve specific problems. http://www.global-village.net/products/practical_webobjects



 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      (Webobjects-dev@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to archive@mail-archive.com

Reply via email to