Since I'm not know in deep the mmbase transaction manager, I don't think this is a good fix and probabily it introduces new bugs, however it may be helpful for a real solution implementation. I would like to hear your comments.
The fix adds one new method to the transaction manager, in order to avoid the "node not added as it was already in the transaction" error. This metod checks if a node that has to be deleted is already in transaction, then marks it for deletion, without throwing an exception. If the node isn't in transaction adds it and then marks it for deletion.
So, three steps:
1) Add this method to org.mmbase.module.core.TransactionManager.java:
public void addAndDelete(String transactionname,String owner,String tmpnumber)
throws TransactionManagerException
{
MMObjectNode node;
Vector v;
v=(Vector)transactions.get(transactionname);
node=tmpNodeManager.getNode(owner,tmpnumber);
if (node!=null)
{
if (v==null)
{
v=new Vector();
v.addElement(node);
transactions.put(transactionname,v);
}
else
{
int n;
n=v.indexOf(node);
if (n==-1)
{
v.addElement(node);
}
} // Mark it as to delete
node.setValue("_exists",EXISTS_NOLONGER);
}
else
{
throw new TransactionManagerException(
"System error: Can't add node as it doesn't exist ");
}
}2) Add this method to org.mmbase.bridge.implementation.BasicTransaction.java:
void addAndDelete(String currentObjectContext)
{
try
{
BasicCloudContext.transactionManager.addAndDelete(transactionContext,
account,currentObjectContext);
}
catch (TransactionManagerException e) {
String message = e.getMessage();
log.error(message);
throw new BridgeException(message,e);
}
}
3) Modify method deleteRelations(int) of org.mmbase.bridge.implementation.BasicNode.java:
private void deleteRelations(int type) {
List relations = null;
if (type == -1) {
relations = mmb.getInsRel().getAllRelationsVector(getNode().getNumber());
} else {
relations = mmb.getInsRel().getRelationsVector(getNode().getNumber());
}
if (relations != null) {
// check first
for (Iterator i = relations.iterator(); i.hasNext();) {
MMObjectNode node = (MMObjectNode)i.next();
cloud.verify(Operation.DELETE, node.getNumber());
}
// then delete
for (Iterator i = relations.iterator(); i.hasNext();) {
MMObjectNode node = (MMObjectNode)i.next();
if ((type == -1) || (node.getIntValue("rnumber") == type)) {
if (cloud instanceof Transaction) {
String oMmbaseId = "" + node.getValue("number");
String currentObjectContext = BasicCloudContext.tmpObjectManager.getObject(account, "" + oMmbaseId, oMmbaseId);
// BEGIN OF MODIFIED CODE
((BasicTransaction)cloud).addAndDelete(currentObjectContext);
// ((BasicTransaction)cloud).delete(currentObjectContext);
// END OF MODIFIED CODE
} else {
node.remove( ((BasicUser)cloud.getUser()).getUserContext());
}
}
}
}
}
Regards, Marco Ciancimino
