Я использую JAX-RS, чтобы предоставить основанный на HTTP интерфейс для управления моделью данных. Модель данных хранится в базе данных и взаимодействует с ней через JPA.
Это позволяет мне модифицировать интерфейс модели данных, чтобы он подходил для клиентов REST, и в основном работает достаточно хорошо. Однако я не уверен, как справиться со сценарием, когда метод, предоставляемый ресурсом JAX-RS, требует транзакции, которая влияет на шаблон JPA get, update, commit-on-tx-end, потому что есть только упаковка транзакции операция get, поэтому обновление никогда не фиксируется. Я вижу ту же проблему, если для одной операции REST требуется несколько операций JPA.
Поскольку я использую поддержку транзакций Spring, очевидно, что нужно применить @Transactional
к этим методам в ресурсах JAX-RS. Однако для того, чтобы это работало, Spring должен управлять жизненным циклом ресурсов JAX-RS, а в примерах использования, о которых я знаю, ресурсы создаются с помощью `new', когда это необходимо, что в любом случае заставляет меня немного нервничать.
Я могу придумать следующие решения:
У кого-нибудь есть предложения? Вполне возможно, что я где-то упустил какой-то ключевой момент.
Обновление. Чтобы обойти отсутствие транзакций в потоке получения, обновления, фиксации при закрытии транзакций, я могу открыть метод слияния (объекта) EntityManager и вызвать его вручную. Хотя это не аккуратно и не решает большую проблему.
Обновление 2 @skaffman Пример кода: На сервисном уровне JPA внедрены, аннотации работают
public class MyEntityJPAService {
...
@Transactional(readOnly=true) // do in transaction
public MyEntity getMyEntity(final String id) {
return em.find(MyEntity.class, id);
}
В ресурсе JAX-RS, созданном новым, нет транзакций
public class MyEntityResource {
...
private MyEntityJPAService jpa;
...
@Transactional // not injected so not effective
public void updateMyEntity(final String id, final MyEntityRepresentation rep) {
MyEntity entity = jpa.getMyEntity(id);
MyEntity.setSomeField(rep.getSomeField());
// no transaction commit, change not saved...
}