我试图编写一个简单的测试程序来模拟我项目中的两个对象并遇到麻烦。基本上我有两个简单的对象,Parent 和 Child 有一对多的关系。以下是两个对象:
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();
}
finally {
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;
}
}
当我运行程序时,我收到以下错误:
Hibernate:
select
parent0_.ID as ID81_1_,
parent0_.DATA as DATA81_1_,
child1_.PID as PID81_3_,
child1_.ID as ID3_,
child1_.ID as ID82_0_,
child1_.PID as PID82_0_,
child1_.VALUE as VALUE82_0_
from
Parent parent0_
left outer join
Child child1_
on parent0_.ID=child1_.PID
where
parent0_.ID=?
org.hibernate.PropertyAccessException: Exception occurred inside setter
of com.fhp.ems.common.data.dao.test.Parent.child
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:89)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:583)
at org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:229)
at org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:3822)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:152)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:982)
at org.hibernate.loader.Loader.doQuery(Loader.java:857)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.loadEntity(Loader.java:2037)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:86)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:76)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3268)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:496)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:477)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:227)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:285)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:152)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1090)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:1005)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:998)
at com.fhp.ems.common.data.dao.test.Parent.main(Parent.java:98)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.hibernate.property.BasicPropertyAccessor$BasicSetter.set(BasicPropertyAccessor.java:66)
... 20 more
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:122)
at org.hibernate.collection.PersistentBag.size(PersistentBag.java:248)
at com.fhp.ems.common.data.dao.test.Parent.setChild(Parent.java:71)
如果我将earger fetch 更改为lazy fetch,它可以正常工作。如果我使用@Fetch(value=FetchMode.SELECT),它也可以正常工作。我的问题是:为什么 Eager fetch 不起作用?