I have a RestController that has a Service with a public method annotated with @Transactional
. The RestController class is annotated with @RestController
, and the service bean is injected using Constructor injection. You can assume that the service is written as a different public class. MyRespository
is annotated with @Repository
annotation.
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.transaction.Transactional;
@RestController
@RequiredArgsConstructor
public class MyController {
private final MyService myService;
@PatchMapping("/some-endpoint")
public SomeCustomObject updateSomeObject(){
// This prints `package.x.y.z.MyService` as opposed to something like `package.x.y.z.MyService$$EnhancerBySpringCGLIB$$a1b2c3d4`
log.info("myService proxy {}", myService.getClass());
return myService.updateSomeObject();
}
}
@Service
@RequiredArgsConstructor
public class MyService extends SomeBaseService{
private final MyRepository myRepository;
@Transactional(rollbackOn = SomeCustomException.class)
public SomeCustomObject updateSomeObject(){
log.info("Is Transaction Active {} Name {} ", TransactionSynchronizationManager.isActualTransactionActive(),
TransactionSynchronizationManager.getCurrentTransactionName()); // This prints `false` and `null`
SomeCustomObject someCustomObject = getTheObj();
updateTheObject(someCustomObject);
} // Updates are not persisted to the database.
private SomeCustomObject getTheObj(){
return myRepository.HugeMethodNameThatsWhyUsedAMethodAsWrapper();
}
private void updateTheObject(SomeCustomObject someCustomObject){
myRepository.setSomething(someCustomObject);
}
}
On googling, I found Spring may not be able to create a proxy if circular dependencies are there. So I tried Field injection using @Autowired
still the log output show the real object.
In one of the other controllers which have another service, which also extends from the SomeBaseService
like MyService
class, injected, the proxy is being created and all these classes are within the same base package.