Использование транзакции в Spring 3.0 в Spring + JPA + Hibernate - PullRequest
1 голос
/ 10 мая 2011

Я сейчас использую Spring + JPA + hibernate в проекте.Затем я решаю свой шаблон проектирования в реализации модели DAN DAO.У меня есть реферат для всего моего класса цели транзакции.Каждый класс (как служба), который выполняет одну задачу обновления / создания / удаления, должен наследоваться от этого абстрактного класса.

public class GlobalAbstractTransaction {
 public abstract void validation(DTO param);
 public abstract void process(DTO param);
 public void execute(DTO param){
     validation(param);
     process(param);
 }
}

Тогда у меня есть другой класс (подкласс класса выше)

@Service
@Transactional //using spring annotation for transactional support
public class SomeTransaction extends GlobalAbstractTransaction
                           implements ITransaction {
     //implements abstract method
     public void validation(DTO param){
     }
     //implements abstract method
     public void process(DTO param){
     }
}

BusinessTransaction - это интерфейс, который имеет один метод

public interface ITransaction {
     public execute(DTO param);
}

Заметил, что я поместил @Transactional (по умолчанию Propagation.REQUIRED) в классе SomeTransaction, чтобы убедиться, что этот класс находится в Transaction.

При использовании в IntegrationTest

@Autowired //default by name
ITransaction someTransaction;

@Test
public void testInsert(){
       DTO someDTO = new DTO(); 
       //apply value for DTO
       someTransaction.execute(someDTO);
}

В результате транзакция не произошла.А someTransaction.execute, который выполняет только вставку данных в задачу базы данных, работает не очень хорошо.

А затем я перемещаю аннотацию @Transactional из SomeTransaction в GlobalAbstractTransaction, чтобы код был таким.

Изменено GlobalAbstractTransaction

public class GlobalAbstractTransaction {
 public abstract void validation(DTO param);
 public abstract void process(DTO param);

 @Transactional //added here
 public void execute(DTO param){
     validation(param);
     process(param);
 }
}

Изменено SomeTransaction

@Service
//transactional annotation removed
public class SomeTransaction extends GlobalAbstractTransaction
                           implements ITransaction {
     //implements abstract method
     public void validation(DTO param){
     }
     //implements abstract method
     public void process(DTO param){
     }
}

Затем тестовая работа, данные вставляются в базу данных.

  1. Кто-нибудь может объяснить, почему это происходит.Я не могу добавить @Transactional в SomeTransaction.execute, потому что он уже определен в GlobalAbstractTransaction.Могу ли я добавить @Transactional add level level вместо этого?
  2. SomeTransaction запланирован как Service, внутри сервиса я автоматически связал реализацию DAO с помощью autowiring (я не помещаю @Transactional на уровне DAO), эточто большинство людей рекомендует.Я просто аннотировал реализацию DAO как @Repository, класс обслуживания как @Service.(обратите внимание, что в моем сервисе выполняется только одна задача: InsertingService, UpdatingService, DeletingService будет разделена на три класса).Я планирую добавить еще один слой для Service Facade ([http://java.dzone.com/articles/jpa-implementation-patterns-3][1]) см. Ссылку для справки. Поэтому я создаю класс

    открытый класс ServiceFacadeBean {public void executeTransaction (String name) {

    }}

Я собираюсь использовать в приложении подобное.

 @Autowired //injected using Spring autowiring
 ServiceFacadeBean serviceFacadeBean;

 serviceFacadeBean.execute("com.mycompany.SomeTransaction");

В реализации execute я хочу использовать отражение с помощью "com.mycompany.SomeTransaction ", чтобы создать экземпляр. но я всегда получаю NullPointerException

 Class clazz = Class.forName("com.mycompany.SomeTransaction");

 clazz.newInstance() <--- get null

И я предполагаю, что 1 класс обслуживания выполняет только 1 задачу транзакции, такую ​​как Вставка в базу данных. Чтопередовой практикой размещения @Transactional, или у кого-либо есть хорошие ссылки, которые действительно хорошо объясняют проблему транзакции с использованием Spring транзакции

Кто-нибудь имеет опыт в этом вопросе или есть более эффективные решения для шаблонов проектирования? Спасибо

1 Ответ

1 голос
/ 11 мая 2011

У меня есть контакты с компанией-разработчиком программного обеспечения в Джакарте, которая использует ту же архитектуру, что и вы. У них есть BusinessTransactions, которые выполняют одну задачу и получают один DTO в качестве параметра. Управление bean-компонентами также осуществляется с помощью Spring 3.0, сохранение осуществляется с помощью JPA 2 и Hibernate. Что касается вашего NullPointerExecution, вы не должны использовать отражение или ваш ServiceFacadeBean, но должны позволять вашим BusinessTransactions называться bean-компонентами:

@Service("SomeTransaction")
//transactional annotation removed
public class SomeTransaction extends AbstractTransaction
                       implements ITransaction {
....
}

Всякий раз, когда вам нужно выполнить эту транзакцию, вы вводите ее следующим образом:

@Autowired
@Qualifier("SomeTransaction")
ITransaction someTransaction;

public doSomething() {
    DTO dto = new DTO();
    dto.putString("id", "948392943");
    someTransaction.execute(dto);
}

PS: Есть ли способ связаться с вами сейчас, когда я путешествую в Джакарте. Было бы очень интересно поделиться ИТ-опытом непосредственно с вами.

...