spring - LazyInitializationException while updating Entity in database -
i have 3 entities employee, person , emailadress given below:
@entity public class employee { private person person; //other data members @manytoone(fetch=fetchtype.lazy, cascade = cascadetype.merge) @joincolumn(name="person_id") public partner getperson() { return person; } //other getter , setters } @entity public class person { private set<emailaddress> emails; //other data members @onetomany(fetch=fetchtype.lazy, mappedby="person", cascade=cascadetype.all) public set<emailaddress> getemails() { return emails; } public void setemails(set<emailaddress> emails) { this.emails = emails; for(emailaddress email : this.emails) { email.setperson(this); } } //other getter , setters } @entity public class emailaddress { private person person; private string email; private string emailtype; //getter , setter @manytoone(fetch=fetchtype.eager) @joincolumn(name="partner_id") public partner getperson() { return person; } }
and employeedao performs save, updates, delete operation on employee entity.
@repository("employeedao") @transactional public class employeedao { public employee saveorupdate(employee emp) { try { return (employee) sessionfactory.getcurrentsession().merge(emp); } catch(exception excp) { //handle exception } return null; } //other methods }
this saveorupdate() in employeedao save employee entity db without problem, when use same saveorupdate() update employee, fails lazyinitializationexception. following employeedaotest:
//test class public class employeedaotest extends abstracttestngspringcontexttests { @autowired private employeedao employeedao; private employee createdummyemployee() { // create dummy employee initialized person , emailaddress return employee; } @test public void testsaveorupdate() { employee emp = createdummyemployee(); //test save/insert employee savedemp = employeedao.saveorupdate(emp); assert.assertnotnull(savedemp); //works fine. employee gets saved correctly //test update savedemp.getperson().setname("updated name"); employee updatedemp = employeedao.saveorupdate(savedemp); assert.assertnotnull(updatedemp); // fails... because of "org.hibernate.lazyinitializationexception: not initialize proxy - no session" } }
i did little bit of googling before posting question here. , figured out there 2 ways fix it:
don't use lazy initialization i.e lazy=false. approach has own implication. , can't use approach because of performance issue.
use @persistencecontext(type = persistencecontexttype.extended). solves problem, think, approach spring not manage entitymanager/transactionmanager , have manage these myself. there way spring manage entitymanager/transactionmanager approach don't have manage myself.
or there better approach fix problem?
inside test method 2 separate sessions created, , when attempting update getperson fails due lazyinitializatin....
you should annotate method @transactional
maintain same persistent context on whole test method.
import rg.springframework.transaction.annotation.transactional ... @test @transactional public void testsaveorupdate() {
similarly, in real business code, whenever access dao multiple times inside method, method should annotate transactional maintain context. of course side effect is, whole method logic fail if 1 of dao operations fails demannded bahaviour.
Comments
Post a Comment