Try structuring it like this, this is a very frequent solution, it's the Domain Driven Development approach described in the blue book, here is a free short version approved by the same author:
Controller
The controller is not transactional and does not have business logic, so it does not try to navigate the user object graph which could cause LazyInitializationExceptions
.
If by any reason other than business logic this is needed, then either the controller calls a service that returns an eager fetched object graph or it first merges the object into a session.
This is meant to be the exception and not the rule, in general the role of the controller is to validate the input parameters to see if they have the correct type/mandatory parameters, call the business logic and prepare a DTO for the response if one is needed.
@RequestMapping(value = "/{userId}", method = RequestMethod.GET)
@ResponseBody
public JsonUser doSomethingOnUser(@PathVariable("userId") Long userId) {
// all the business logic is in the service layer
User user = mUserService.doSomething(userId);
// conversion to DTO is handled in the controller layer,
// the domain does not know about DTOs
return mUserPresenter.convertToJsonUser(user);
}
Service
The service contains the business logic written using the domain model, and defines the transaction scope.
@Service
public class MyUserService {
@Autowired
private MyRepository repository;
@Transactional
public User doSomething(String userId) {
//this object is attached due to @Transactional, no exceptions will be thrown
User user = mUserRepository.findOne(userId);
// do something with the attached object
....
}
Repository
The repository is usually not transactional, as it cannot know the scope of the transaction it's in. It is responsible for retrieving data from the database and transforming it in domain objects, and for storing domain objects in the database:
@Repository
public class MyRepository {
@PersistenceContext
private EntityManager em;
public void someDataRelatedMethod(...) {
... use entity manager ...
}
}