2009-10-18 2 views
5

новых весны и здесь @stackoverflowSpring @Transactional слияния и сохраняются вопросы

Я построение автономной инвентаризации & продаж отслеживания приложений (Apache Pivot/Spring/JPA/Hibernate/MySQL) для дистрибьютора бизнеса ,

До сих пор я думаю, что все это CRUD, поэтому я планирую иметь базовый класс со всем @Transactional.

Тогда у меня возникла проблема с моим общим универсальным методом. Есть ли способ сохранения и слияния EntityManager из Spring?

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

@Transactional 
public abstract class GenericDAO { 

    protected EntityManager em; 

// em [email protected]/setter 

    public void save(T t) { 
//  if (t.getId() == null) // create new 
//  { 
//   em.persist(t); 
//  } else // update 
//  { 
      em.merge(t); 
//  } 
    } 
} 

И btw, имея такую ​​установку, я не буду сильно компрометировать производительность? Как вызывать salesDAO.findAll() для создания отчетов (что не обязательно должно быть транзакционным, верно?).

спасибо !!!

ответ

5

This SO question - хорошее обсуждение persist vs. merge, и принятый ответ объясняет это довольно хорошо. Другой ответ также связан с хорошим сообщением в блоге об этом.

В соответствии с первым ответом в this other post, похоже, было бы возможно вызвать слияние для сохранения и обновления объекта, но это не то, как я это сделал. В моих приложениях Spring/JPA у меня только что мои DAO расширяют JpaDaoSupport и используют getJpaTemplate() следующим образом.

/** 
* Save a new Album. 
*/ 
public Album save(Album album) { 
    getJpaTemplate().persist(album); 
    return album; 
} 

/** 
* Update an existing Album. 
*/ 
public Album update(Album album) { 
    return getJpaTemplate().merge(album); 
} 
+0

Я гость, это самый простой способ пойти. Итак, если у меня есть JpaDaoSupport, и я получаю от нее сущность, любые изменения будут автоматически совершены? Я думаю, у меня будет два варианта метода сохранения, который сохраняется и тот, который вызывает флеш. Есть какие-либо комментарии по этому поводу? – thirdy

+0

Вы имеете в виду автоматический как в совершенном без сохранения или обновления? Если это так, я бы так не подумал, я всегда просто вызываю сохранение нового объекта или обновление существующего для сохранения. Мне никогда не нужно было вызывать метод flush, но мой доступ к БД довольно прост для любого заданного запроса. –

+0

На данный момент мне придется отказаться от попыток Весны. Просто любопытно, как Граальс улучшает это? Мне не придется сталкиваться с такими проблемами, как в Grails? – thirdy

4

link на другой вопрос SO Калеб отправил делает хорошую работу покрытия различия и подводных камней, из упорствовать() против слияния(). Тем не менее, я всегда просто реализовал свои классы Dao с помощью одного метода save(), который вызывает только merge() для обработки как вставок, так и обновлений, и я никогда не сталкивался с какой-либо проблемой persist() vs merge().

Что касается производительности и транзакционных методов: Использование @Transactional на методы, которые только операции чтения не будет реально влиять на производительность, хотя я предпочитаю использовать аннотации на уровне метода только так я могу легко сказать, какие методы обновления и которые читаются. Вы можете сделать это, установив атрибут readOnly в аннотации @Transactional.

Если вы будете следовать соглашению об именах в своих методах (т.е. любой метод чтения всегда начинается с getXXX), вы можете также использовать poincut синтаксис в файле конфигурации Spring автоматически делает эту дифференциацию:

<tx:advice id="txAdvice" transaction-manager="txManager"> 
    <tx:attributes> 
     <tx:method name="get*" read-only="true"/> 
     <tx:method name="*"/> 
    </tx:attributes> 
    </tx:advice> 

См Spring documentation on Transactions для получения дополнительной информации.

Кроме того, я обычно добавляю атрибуты @Transactional на один уровень выше моих классов Dao на сервисном уровне. Методы классов Dao представляют собой различные операции с базой данных для каждого вызова метода, в то время как методы службы могут выполнять один фиксацию/откат для серии обновлений.

+0

спасибо за ответ. Я думаю, что я буду придерживаться чистой JPA (мне не нужна гибкость) – thirdy

Смежные вопросы