Spring @Transactional placement -
i'm playing little spring/jpa2 understand better how works. during experiments found strange behaviour. question is:
why following code works (confirmed record added in db):
@repository public class userdao { @persistencecontext entitymanager em; @transactional public void add(user user) { doadd(user); } public void doadd(user user) { em.persist(user); } }
but following (@transactional annotation moved inner method):
@repository public class userdao { @persistencecontext entitymanager em; public void add(user user) { doadd(user); } @transactional public void doadd(user user) { em.persist(user); } }
throws exception:
javax.persistence.transactionrequiredexception: no transactional entitymanager available @ org.springframework.orm.jpa.sharedentitymanagercreator$sharedentitymanagerinvocationhandler.invoke(sharedentitymanagercreator.java:273) @ com.sun.proxy.$proxy556.persist(unknown source) @ com.example.userdao.doadd(userdao.java:24) ...
in proxy mode (which default), external method calls coming in through proxy intercepted. means self-invocation, in effect, method within target object calling method of target object, not lead actual transaction @ runtime if invoked method marked @transactional.
the @transactional annotation support works wrapping actual dao instance in proxy, intercepts method calls , starts/commits transaction. in second example actual userdao instance calling dosave method , therefore there no proxy intercept method call.
Comments
Post a Comment