Re: How to enforce Delete before Insert?

From: Juergen Saar (juerge..saar.org)
Date: Fri Apr 28 2006 - 06:38:34 EDT

  • Next message: Marcin Skladaniec: "Re: java.sql.SQLException: No rows for 'payment_items'"

    No, that's the dark side of this kind of working.

    For us this is really no problem,
    for most installation we use informix without transaction
    because it is much faster and we would need transactions
    in about 1% of our software. So we have implemented
    a kind of self-healing for most kinds of data-defects.

    We do it that way since about 20 years and there is
    no noteworthy data loss.

    Nevertheless it would be fine to have a fifo strategy for db-statements in
    cayenne.

    2006/4/28, Bill Fan <bil..anscom.com.au>:
    >
    > Thanks Juergen! Can you still manage the db traction when you do delete
    > and
    > insert in separate context?
    >
    > I can force it to do the DELETE first if I execute commitChanges() after
    > the
    > deleteObjects statement...however, this could be potentially dangerous as
    > what I'm trying to do here should be in a atomic db transaction.
    >
    > I guess I have to do it in the hard way, analyze the changes and do INSERT
    > and DELETE accordingly.
    >
    >
    > Cheers.
    >
    >
    >
    > -----Original Message-----
    > From: Jürgen Saar [mailto:Juerge..Saar.org]
    > Sent: Friday, 28 April 2006 5:40 PM
    > To: cayenne-use..ncubator.apache.org
    > Subject: Re: How to enforce Delete before Insert?
    >
    > This problem is well known to me.
    > We do it the same way.
    > It is much easyier because it is not neccessary
    > to analyze for changes.
    >
    > Cayenne does not commit the changes in a fifo-logic.
    > To solve this we use a separate context
    > for delete and insert ...
    >
    > --- Juergen ---
    >
    > -----Ursprüngliche Nachricht-----
    >
    > Hi,
    >
    > I have a Product & a ProductRelation tables. When the ProductRelation
    >
    > records for a product are managed in a web page, I'd like to delete the
    > exiting records in the ProductRelation table for this product first, then
    > insert the new one.
    >
    > I'm having trouble to do this with the following code. I got the "Cannot
    >
    > insert duplicate key in object ..." db error. The reason appears that the
    > DELET statements appear after the INSERT statements from what I can see in
    > the QueryLogger output. Could someone please help? I'm using Cayenne
    > 1.2B2.
    >
    >
    > The code:
    > =========
    > public void saveProductRelation(Product product, String
    > relatedProductId[], Type relationType)
    > {
    > // delete the existing records
    >
    > log.debug("product.getProductRelationArray().size()=" +
    > product.getProductRelationArray().size());
    >
    > threadDataContext().deleteObjects(product.getProductRelationArray());
    >
    > if (relatedProductId.length
    > > 0)
    > {
    > for
    > (int i=0; i<relatedProductId.length; i++)
    > {
    > log.debug("relatedProductId["
    > + i + "]=" +
    > relatedProductId[i]);
    >
    > ProductRelation
    > o = new ProductRelation();
    > threadDataContext().registerNewObject(o);
    > o.setToProduct(product);
    > o.setToProduct1((Product)
    > objectForPK(Product.class, new
    > Integer(relatedProductId[i].trim())));
    > o.setToType(relationType);
    >
    > product.addToProductRelationArray(o);
    > }
    > }
    >
    > commitChanges();
    >
    > }
    >
    >
    > The QueryLogger output:
    > =======================
    > dao.ProductDaoImpl.saveProductRelation(ProductDaoImpl.java:713) -
    > <relatedProductId[0]=9>
    > cayenne.access.QueryLogger.logQueryStart
    > (QueryLogger.java:459) - <--- will
    > run 2 queries.>
    > cayenne.access.QueryLogger.logBeginTransaction(QueryLogger.java:413) -
    > <---
    > transaction started.>
    > cayenne.access.QueryLogger.logQuery(QueryLogger.java
    > :336) - <INSERT INTO
    > dbo.ProductRelation (ProductId, RelatedProductid, TypeId) VALUES (?, ?,
    > ?)>
    > cayenne.access.QueryLogger.logQueryParameters(QueryLogger.java:358) -
    > <[bind: 242, 9, 16]>
    > cayenne.access.QueryLogger.logUpdateCount
    > (QueryLogger.java:404) - <===
    > updated 1 row.>
    > cayenne.access.QueryLogger.logQuery(QueryLogger.java:336) - <DELETE FROM
    > dbo.ProductRelation WHERE ProductId = ? AND RelatedProductid = ? AND
    > TypeId
    > = ?>
    >
    > cayenne.access.QueryLogger.logQueryParameters(QueryLogger.java:358) -
    > <[bind: 242, 222, 16]>
    >
    >
    > Many thanks in advace!
    >
    > Bill
    >



    This archive was generated by hypermail 2.0.0 : Fri Apr 28 2006 - 06:46:07 EDT