dao layer abstraction
interface DaoLayer {
Long createFavouriteWidgetInfo(FavouriteWidgetInfo favouriteWidget);
}
dao Layer Implementation
class DaoLayerImpl implements DaoLayer
@Transactional
@Override
public Long createFavouriteWidgetInfo(FavouriteWidgetInfo favouriteWidget) {
Session session=sessionFactory.getCurrentSession();
Long val= (Long) session.save(favouriteWidget);
throw new NullPointerException();
//return val;
}
Sample Test Case
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class Test {
@Autowired
private DaoLayer daoLayer;
@org.junit.Test
public void test()throws Exception {
FavouriteWidgetInfo info=new FavouriteWidgetInfo();
info.setGroupId(1);
info.setReportId(2);
info.setUserId(213);
info.setTenantId(21);
info.setApplicationId(2);
daoLayer.createFavouriteWidgetInfo(info);
}
when i run the above test case the transaction should rollback because intentionally am throwing NullPointerException which is a sub class of RuntimeException so my transaction should rollback when i enable spring transaction logs i can able see the rollback logging statements but when i look into the db the entity is persisted
Note:- am using SpringSessionContext class spring implementation of Hibernate current_session context so creating the session will be managed by spring framework.
CodePudding user response:
There are two possible situations: The first: If mysql does not support the storage engine, it will create a table with a MyISAM table, which is a non-transactional table. Generally modified to InnoDB The second type: Spring's AOP, declarative transaction management, defaults to rollback for unchecked exceptions. That is, by default, the RuntimeException() exception or its subclasses are rolled back; the checked exception, that is, the Exception can be caught by try{} and will not be rolled back. If you use try-catch to capture the thrown unchecked exception, it is not in the catch block. The page is hard-coded and the spring api is used to explicitly roll back the transaction, so the transaction will not be rolled back
I guess you used Exception in your controller, from the service layer to the controller layer, such as this statement throw new Exception("xxxxxxxxxxxx"); Transaction is not rolled back
Hope your problem can be solved
CodePudding user response:
in your DaoLayerImpl you already saved the data into the Database before throwing NPE. If you want to throw error intentionally for testing purposes and don't want to save data in DB then remove 6 line from your code and put it in catch block or else delete.
the code should be like this.
class DaoLayerImpl implements DaoLayer
@Transactional
@Override
public Long createFavouriteWidgetInfo(FavouriteWidgetInfo favouriteWidget) {
Session session=sessionFactory.getCurrentSession();
//Long val= (Long) session.save(favouriteWidget); //remove this line.
throw new NullPointerException();
//return val;
}
Please clarify in detail if this is not the solution you are looking for.