Я сейчас использую 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){
}
}
Затем тестовая работа, данные вставляются в базу данных.
- Кто-нибудь может объяснить, почему это происходит.Я не могу добавить @Transactional в SomeTransaction.execute, потому что он уже определен в GlobalAbstractTransaction.Могу ли я добавить @Transactional add level level вместо этого?
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 транзакции
Кто-нибудь имеет опыт в этом вопросе или есть более эффективные решения для шаблонов проектирования? Спасибо