Why Hibernate Eager Fetch Does Not Work? -
i trying write simple testing program simulate 2 objects in project , run trouble. have 2 simple object, parent , child 1 many relationship. following 2 objects:
import java.util.list; import javax.persistence.cascadetype; import javax.persistence.column; import javax.persistence.entity; import javax.persistence.fetchtype; import javax.persistence.id; import javax.persistence.joincolumn; import javax.persistence.onetomany; import javax.persistence.table; import org.hibernate.session; import org.hibernate.transaction; import com.fhp.ems.common.data.dao.hibernateinitializer; @entity @table(name = "parent") public class parent { private integer id; private string data; private list<child> child; public parent() {} @id @column(name = "id", nullable = false) public integer getid() { return this.id; } public void setid(integer id) { this.id = id; } @column(name = "data", length = 128) public string getdata() { return this.data; } public void setdata(string data) { this.data = data; } @onetomany(cascade = { cascadetype.all }, fetch = fetchtype.eager, orphanremoval = true) @joincolumn(name = "pid") //@fetch(value=fetchmode.select) public list<child> getchild() { return child; } public void setchild(list<child> child) { this.child = child; if(child != null && child.size() > 0) { for(child c : child) { this.data = c.getvalue(); } } } public static void main(string[] args) { session session = null; transaction tx = null; try { hibernateinitializer.initlocal(); session = hibernateinitializer.getsession(null); int id = 101; tx = session.begintransaction(); parent p = (parent)session.get(parent.class, 101); //parent p = new parent(); //p.setid(id); //child c = new child(); //c.setpid(id); //c.setid(1); //c.setvalue("child"); //child c1 = new child(); //c1.setpid(id); //c1.setid(2); //c1.setvalue("child1"); //list<child> childs = new arraylist<child>(); //childs.add(c); //childs.add(c1); //p.setchild(childs); //session.saveorupdate(p); tx.commit(); } catch(exception exc) { exc.printstacktrace(); } { hibernateinitializer.closesession(session, null); } } } import javax.persistence.column; import javax.persistence.entity; import javax.persistence.id; import javax.persistence.table; //create table `child` ( // `id` int(11) not null, // `pid` int(11) not null, // `value` varchar(128) default null, // primary key (`id`) //) @entity @table(name = "child") public class child { private integer id; private integer pid; private string value; public child() {} @id @column(name = "id", unique = true, nullable = false) public integer getid() { return this.id; } public void setid(integer id) { this.id = id; } @column(name = "pid", nullable = false) public integer getpid() { return this.pid; } public void setpid(integer pid) { this.pid = pid; } @column(name = "value", length = 128) public string getvalue() { return this.value; } public void setvalue(string value) { this.value = value; } }
when run program, following error:
hibernate: select parent0_.id id81_1_, parent0_.data data81_1_, child1_.pid pid81_3_, child1_.id id3_, child1_.id id82_0_, child1_.pid pid82_0_, child1_.value value82_0_ parent parent0_ left outer join child child1_ on parent0_.id=child1_.pid parent0_.id=? org.hibernate.propertyaccessexception: exception occurred inside setter of com.fhp.ems.common.data.dao.test.parent.child @ org.hibernate.property.basicpropertyaccessor$basicsetter.set(basicpropertyaccessor.java:89) @ org.hibernate.tuple.entity.abstractentitytuplizer.setpropertyvalues(abstractentitytuplizer.java:583) @ org.hibernate.tuple.entity.pojoentitytuplizer.setpropertyvalues(pojoentitytuplizer.java:229) @ org.hibernate.persister.entity.abstractentitypersister.setpropertyvalues(abstractentitypersister.java:3822) @ org.hibernate.engine.twophaseload.initializeentity(twophaseload.java:152) @ org.hibernate.loader.loader.initializeentitiesandcollections(loader.java:982) @ org.hibernate.loader.loader.doquery(loader.java:857) @ org.hibernate.loader.loader.doqueryandinitializenonlazycollections(loader.java:274) @ org.hibernate.loader.loader.loadentity(loader.java:2037) @ org.hibernate.loader.entity.abstractentityloader.load(abstractentityloader.java:86) @ org.hibernate.loader.entity.abstractentityloader.load(abstractentityloader.java:76) @ org.hibernate.persister.entity.abstractentitypersister.load(abstractentitypersister.java:3268) @ org.hibernate.event.def.defaultloadeventlistener.loadfromdatasource(defaultloadeventlistener.java:496) @ org.hibernate.event.def.defaultloadeventlistener.doload(defaultloadeventlistener.java:477) @ org.hibernate.event.def.defaultloadeventlistener.load(defaultloadeventlistener.java:227) @ org.hibernate.event.def.defaultloadeventlistener.proxyorload(defaultloadeventlistener.java:285) @ org.hibernate.event.def.defaultloadeventlistener.onload(defaultloadeventlistener.java:152) @ org.hibernate.impl.sessionimpl.fireload(sessionimpl.java:1090) @ org.hibernate.impl.sessionimpl.get(sessionimpl.java:1005) @ org.hibernate.impl.sessionimpl.get(sessionimpl.java:998) @ com.fhp.ems.common.data.dao.test.parent.main(parent.java:98) caused by: java.lang.reflect.invocationtargetexception @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:39) @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:25) @ java.lang.reflect.method.invoke(method.java:597) @ org.hibernate.property.basicpropertyaccessor$basicsetter.set(basicpropertyaccessor.java:66) ... 20 more caused by: org.hibernate.lazyinitializationexception: failed lazily initialize collection, no session or session closed @ org.hibernate.collection.abstractpersistentcollection.throwlazyinitializationexception(abstractpersistentcollection.java:383) @ org.hibernate.collection.abstractpersistentcollection.throwlazyinitializationexceptionifnotconnected(abstractpersistentcollection.java:375) @ org.hibernate.collection.abstractpersistentcollection.readsize(abstractpersistentcollection.java:122) @ org.hibernate.collection.persistentbag.size(persistentbag.java:248) @ com.fhp.ems.common.data.dao.test.parent.setchild(parent.java:71)
if change earger fetch lazy fetch, works fine. if use @fetch(value=fetchmode.select), works fine. question is: why eager fetch not work?
how can have @onetomany
when don't have parentid
in child table?
missing key have multiple children related single parent; add parentid
table child
, use column in @joincolumn(name = "parentid")
edit:
- init
parent.child
private list<child> child = new arraylist<child>();
- change
private integer pid;
private parent pid;
(and add @onetomane mappedby="parent") - try annotate field , not setter
- make
parent.setchild()
assignment
that - - best pratice parent-child relationship
Comments
Post a Comment