0

I have a big Service method in my Spring/Hibernate app which previously wasn't transactional, and was working OK. As soon as I added @Transactional(readOnly = false, rollbackFor = {Exception.class}) to it, the Select (Fetch) part of that method started breaking at a Select statement (even prior to any persistence):

org.hibernate.PersistentObjectException: detached entity passed to persist: app.domain.Activities

in this code:

@Transactional(readOnly = false, rollbackFor = {Exception.class})
public String save(PlansModel plan, String id, Model model,HttpServletRequest request) throws IllegalAccessException, InvocationTargetException {
   //...
   //... some initial Selects - NO Persistence yet
   Project proj = planService.getProjectByID(projId); // <-- BROKE HERE "detached entity passed to persist"
   // ... NO Persistence yet
   // ...
   // At the end, some persistence starts
   planService.savePlan(plan); //etc.
}

We're maintaining this messy code and it's hard to analyze what may have caused it. Some objects are being modified there.

We decided to work around it by putting @Transactional just around the actual persistence bottom part, which is all that matters for transactionality. (Our goal is to ensure that this whole method has transactionality/rollback.)

But when we did that, we found that in this new design, transactions don't get rolled back in case of errors. We've split it up into 2 methods, and just the 2nd method is @Transactional, but there's no rollback from here, and the Transaction mechanism doesn't kick in. Everywhere else it works.

public String save(PlansModel plan, String id, Model model,HttpServletRequest request) throws IllegalAccessException, InvocationTargetException {
   //...
   //... some initial Selects - NO Persistence yet
   Project proj = planService.getProjectByID(projId); // <-- WORKING AGAIN without @Transactional
   // ... NO Persistence yet
   // ...
   return persistPart(..); // for persistence
}

@Transactional(readOnly = false, rollbackFor = {Exception.class})
public String persistPart(..) {

   planService.savePlan(plan); // <-- NO ROLLBACK from here
}

It seems like we're dealing with a method which has some issues as soon as @Transactional is added, but we need to ensure transactionality/rollback is enabled for it. Based on these symptoms, does anyone know what the solution might be?

gene b.
  • 10,512
  • 21
  • 115
  • 227

1 Answers1

1

@Transactional doesn't work when you call this method from inside the service class like you do. It's true not only for @Transactional. It's a limitation of Spring AOP.

Your question is almost a duplicate of this one. So you either need to inject this service into itself and call this transactional method on the injected object OR create another service which will call this transactional method

Dmitrii Bocharov
  • 872
  • 6
  • 21