I'm trying to get a better handle on the use of Spring's @Transactional
attribute. I understand that it basically wraps the contents of the method marked as @Transactional
in a transaction. Would it be appropriate to mark a service/business layer method as transactional, as opposed to the actual DAO method, as I have done here?
Service Implementation
public class UserServiceImpl implements UserServiceInt{
@Autowired
private UserServiceDAO serviceDAO;
@Override
public User getUser(int id){
return serviceDAO.getUser(id);
}
@Override
@Transactional
public void updateUserFirstName(int id, String firstName) throws SomeException{
User userToUpdate = getUser(id);
if(userToUpdate == null){
throw new SomeException("User does not exist");
}
userToUpdate.setFirstName(firstName);
serviceDAO.updateUser(userToUpdate);
}
}
DAO Implementation
public class UserServiceDAOImpl implements UserServiceDAOInt{
@PersistenceContext(unitName="myUnit")
private EntityManager entityManager;
@Override
public void updateUser(User user){
entityManager.merge(user);
}
}
I'm not even sure if the call to merge is even necessary. How does Spring know which EntityManager to use since there isn't an EntityManager declare in the UserServiceImpl class?
@Transactional
- for example in case the service spans more than a single DAO. Also, you are right, you don't have to explicitly call merge. The User object is already associated with the persistence context (by callingget()
) and it's state synchronized with the DB at the end of the transaction . Merge is used to update an object which had been changed outside of a transaction – Sussi