views:

47

answers:

1

I've set up a Spring ROO application, set persistence to OpenJPA and created some entities. Then I replaced Spring MVC with Apache Wicket. Stuff seems to be working fine and I've successfully displayed a list of Customer entities.

Next up was the editing view for the customer. For now I've made a Wicket form that uses the OpenJPA entity directly as the form model, and thus I had to make the entity class implement Serializable.

Now, I'm not sure how to correctly implement the OpenJPA persistence, what I've got now is this:

@Override
protected void onSubmit() {
    try {
        if (customer.getId()!=null) {
            customer.merge();
        }
        else {
            customer.persist();
        }
    }
    catch (Exception e) {
        throw new Error(e);
    }
    super.onSubmit();
}

That works, but only once per Customer object. Somehow. That is, I submit my form once and it works both with a new customer (.persist()) and a existing customer (.merge()). However, I submit the form again for the same customer I get this error (I added some linebreaks here):

<openjpa-2.0.0-r422266:935683 nonfatal store error>
org.apache.openjpa.persistence.OptimisticLockException:
An optimistic lock violation was detected when flushing object instance "no.magge.iumb.domain.crm.PrivateCustomer-379" to the data store.
This indicates that the object was concurrently modified in another transaction.

My question is, what is the correct way to persist with OpenJPA and why am I getting that error ?

Wicket-wise: Should I have created a separate Wicket IModel with a detachable Customer model and could that be the reason that I have these problems?

Thanks a bunch for any advice!

+1  A: 

Do yourself a favor and separate your application layers. Code in a view should not ever access a Database.

Create a Service layer and / or a Dao layer, unit test the code of those layers to see that they are working and then inject a dao or service object into the wicket component. (I'd recommend you to use spring for that, but you can also do it manually)

With your scenario, there are so many different things that can fail in one spot, and it's nearly impossible to separate them.

Here are some pointers:

seanizer
I suppose you're right - it'd be better to create a separate application layer. Spring ROO had some reasoning around dropping the DAO layer, but I don't remember the details right now. Perhaps because the code one would normally need to separate out is already separate as the managed .aj files. Seems ROO is falling out of my application part by part. Anyway- thanks for your links I'll do some more reading!
Magnus