I am defining Transaction function in my application, But its not working for Abstract class of Concrete method, Since my controller is calling first Abstract class method then it will enter to Concrete class method. Can anyone help me to fix? I tried with Concrete class method, its working, But I need to bring it to abstract layer since I am calling CRUD Operation DAO function in Abstract layer only.
I tried to insert data for Multiple table and at last I thrown exception to make sure Transaction has to roll back. But Data is capturing even though Exception occurs also.
--Controller code Start
@RequestMapping(value = "/new", method = RequestMethod.GET)
public String add() throws Exception {
addDTO();
return "demo";
}
protected void addDTO() {
try {
service.addDTO();
} catch (Exception e) {
log.error("addDTO", e);
}
}
--- Controller code End
--- Abstract Service with concrete method
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class })
public void addDTO() throws Exception {
try {
E entity = this.entityFromDTO();
this.dao.add(entity);
// Added For Transaction Test START
TMstPackage packType = getPackageEntity();
mstPackageDao.add(packType);
throw new Exception("Transaction RollBack test");
// Added For Transaction Test END
} catch (Exception ex) {
Log.error("addData");
throw ex;
}
}
--- Concrete Service
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class })
protected TMstContainer entityFromDTO() throws Exception {
TMstContainer container = null;
try {
Date date = Calendar.getInstance().getTime();
container = new TMstContainer();
container.setCntCode("TEST1");
container.setCntDescription("Test Desc");
container.setCntDtCreate(date);
container.setCntDtLupd(date);
container.setCntStatus('A');
container.setCntUidCreate("SYS");
container.setCntUidLupd("SYS");
} catch (Exception e) {
log.error(e);
}
return container;
}
The same code I tried by defining in concrete class function with @Transactional, Its working Fine. But If I bring it to abstract function with same annotation, Data is capturing to database.Can anyone please help.
Image for Abstract Class with Concrete method & @Transactional annotation defined :
This is the expected behavior. @Transactional method should be directly called from outside, in that case the object instance should be retrieved through spring injection. Spring doesn't do any magic here. it creates a AOP proxy fro the class you specified, and if someone call a method using that proxy , if the method is annotated as @Transactional , that proxy method invocation handler will execute it through a transaction template. if you call a Transnational method directly from a non transnational method in that class, spring doesn't know anything.