Apache Wicket, OpenJPA и Spring/ROO

Я настроил приложение Spring ROO, установил постоянство в OpenJPA и создал несколько объектов. Затем я заменил Spring MVC на Apache Wicket. Кажется, все работает нормально, и я успешно отобразил список объектов Customer.

Следующим было представление редактирования для клиента. На данный момент я сделал форму Wicket, которая использует объект OpenJPA непосредственно в качестве модели формы, и поэтому мне пришлось сделать класс объекта реализующим Serializable.

Теперь я не уверен, как правильно реализовать постоянство OpenJPA, теперь у меня есть следующее:

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

Это работает, но только один раз для каждого объекта Customer. Как-то. То есть я отправляю свою форму один раз, и она работает как с новым клиентом (.persist()), так и с существующим клиентом (.merge()). Однако я снова отправляю форму для того же клиента, я получаю эту ошибку (здесь я добавил несколько разрывов строк):

<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.

Мой вопрос: как правильно работать с OpenJPA и почему я получаю эту ошибку?

Wicket-wise: Должен ли я создать отдельную Wicket IModel с отсоединяемой моделью клиента, и может ли это быть причиной этих проблем?

Громадное спасибо за любой совет!


person Magnus    schedule 12.10.2010    source источник
comment
В качестве примечания, если вы еще этого не сделали, взгляните на шаблон Open Session iv View и его реализацию в Wicket + Spring. Звучит похоже на вашу проблему, но я работал только с Hibernate, поэтому я не могу сформулируйте ответ, который будет работать для вас ..   -  person Tim    schedule 12.10.2010
comment
Хм, да - может быть, это связано. Как указано в ответе ниже, мне действительно следует перепроектировать приложение, чтобы я мог провести некоторое тестирование на разных уровнях приложения. Я использую фильтр OpenJPAs, который, как я понял, должен открывать и закрывать сеанс для каждого запроса, что, по-видимому, является сутью шаблона Open Session in View?   -  person Magnus    schedule 13.10.2010


Ответы (1)


Сделайте себе одолжение и разделите слои приложения. Код в представлении никогда не должен обращаться к базе данных.

Создайте слой службы и/или слой Dao, выполните модульное тестирование кода этих слоев, чтобы убедиться, что они работают, а затем внедрите объект dao или службы в компонент калитки. (Я бы порекомендовал вам использовать для этого spring, но вы также можете сделать это вручную)

С вашим сценарием так много разных вещей могут дать сбой в одном месте, и почти невозможно их разделить.

Вот несколько советов:

person Sean Patrick Floyd    schedule 12.10.2010
comment
Я полагаю, вы правы - было бы лучше создать отдельный прикладной уровень. У Spring ROO были некоторые соображения по поводу удаления слоя DAO, но я не помню подробностей прямо сейчас. Возможно, потому что код, который обычно необходимо отделить, уже отделен от управляемых файлов .aj. Кажется, ROO выпадает из моего приложения по частям. В любом случае - спасибо за ваши ссылки, я почитаю еще! - person Magnus; 13.10.2010