неділя, 1 квітня 2012 р.

JPA 2.0: Entities design

При проектировании модели данных с использованием JPA, особенных правил, которые были бы определены стандартом, фактически нет. Очевидно, что класс должен

  1. Быть сериализуемым
  2. Cодержать реализацию equals и hashCode
  3. Некоторые рекомендуют перегружать toString
  4. Иметь публичные getters & setters для своих полей

Но это фактически требования к стандартным JavaBean's, чем конкретно к JPA entity beans. А между тем, именно JPA entity имеют свои особенности, о которых было очень полезно знать непостредственно при проектировании. И снова источником вдохновения стала статья Stijn Geukens на StackOwerflow

JPA 2.0: Persist vs Merge

Интересная вещь мне открылась, когда я решал проблему, традиционную для JPA, есть классическая ORM модель, в которой необходимо создать новый объект, но связать его с уже существующими данными. Довольно часто здесь возникает javax.persistence.PersistenceException, связанный с тем, что мы пытаемся вставить в базу данных объект, находящийся в состоянии DETACHED. Мой метод saveOrUpdate выглядел традицоинным образом
public T saveOrUpdate(final T entity) { 
    if (entity.getId() == null) { 
        entityManager.persist(entity); 
        entityManger.refresh(entity); 
    } else { 
        entityManger.merge(entity); 
    } 
    return entity; 
}
Так я использовал его множество раз и множество подобных примеров встречал в интернете. Моя наибольшая проблема заключалась в том, что модель приложения весьма обширна и вручную обрабатывать все связные классы на предмет их наличия в базе данных заняло бы очень много времени. Поэтому я стал искать более элегатное решение. И нашел его, но не совсем там, где расчитывал. А именно в документации по JPA. Подробное описание различия между методами persist и merge, я нашел в статье Zbyněk Šlajchrt. А я хотел бы поделится выводы, которые из этой статьи сделал: