开发者

Using transaction in Spring 3.0 in Spring + JPA + Hibernate

I currently using Spring + JPA + hibernate in a project. Then i decide my design pattern in model dan DAO implementation. I have a abstract for all my transaction purpose class. Every class( as a service) that perform a single update/create/delete task must inherits from this abstract class.

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

Then i have another class (subclass of class above)

@Service
@Transactional //using spring annotation for transactional support
public cl开发者_如何学Pythonass SomeTransaction extends GlobalAbstractTransaction
                           implements ITransaction {
     //implements abstract method
     public void validation(DTO param){
     }
     //implements abstract method
     public void process(DTO param){
     }
}

The BusinessTransaction is an interface that have one method

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

Noted that I put @Transactional (with default Propagation.REQUIRED) at class SomeTransaction want to make sure that this class is in a Transaction.

When using in IntegrationTest

@Autowired //default by name
ITransaction someTransaction;

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

The result is there is no transaction occured. And the someTransaction.execute which only perform inserting data to database task, was not running well.

And then I move the @Transactional annotation from SomeTransaction, to GlobalAbstractTransaction so the code would be like this.

Modified 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);
 }
}

Modified 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){
     }
}

Then, the test work, data is inserted to database.

  1. Anybody could explain why this is happening. I can't add @Transactional at SomeTransaction.execute, because it already defined in GlobalAbstractTransaction. Can I add @Transactional add class level instead ?
  2. SomeTransaction is planned as Service, inside the service I autowired a DAO implementation using autowiring (I don't put any @Transactional at DAO level), that's what most people recommends. I just annotaed DAO implementation as @Repository, the service class as @Service. (note that in my service only perform one task, InsertingService, UpdatingService, DeletingService will be separated in three classes). I'm planning to add another layer for Service Facade ([http://java.dzone.com/articles/jpa-implementation-patterns-3][1]) see link for reference. So i create a class

    public class ServiceFacadeBean { public void executeTransaction(String name){

    } }

I'm intended to using in the application like this.

 @Autowired //injected using Spring autowiring
 ServiceFacadeBean serviceFacadeBean;

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

In the implementation of the execute I want to use reflection using "com.mycompany.SomeTransaction" to create instance. but I always get NullPointerException

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

 clazz.newInstance() <--- get null

And I'm intended that 1 service class, only perform 1 transaction task such as Inserting to database. What to best practices for putting @Transactional, or anyone have good links that really explaining well bout Transaction issue using Spring transaction

Anyone have experience on this, or have any better design pattern solutions? Thanks


I have contacts to a software company in Jakarta that is using exactly the same architecture as you are implementing. They have BusinessTransactions that perform a single task and receives a single DTO as a parameter. The beans are also managed using Spring 3.0, persistence is done with JPA 2 and Hibernate as well. Concerning your NullPointerExecution you should not use reflection neither your ServiceFacadeBean but let your BusinessTransactions be named beans like that:

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

Whenever you need to execute this transaction you inject it like that:

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

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

PS: Is there any way to contact you as I am traveling in Jakarta right now. Would be very interesting to share IT experience directly with you.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜