我试图编写一个简单的测试程序来模拟项目中的两个对象并遇到麻烦。基本上我有两个简单的对象,父和子有一对多的关系。以下是两个对象:
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),它也可以正常工作。我的问题是:为什么急切的提取不起作用?
答案 0 :(得分:0)
如果您在子表中没有@OneToMany
,怎么能有ParentId
?
您缺少一个与单亲相关的多个孩子的钥匙;将ParentId
添加到表Child
并在@JoinColumn(name = "ParentId")
编辑:
Parent.child
private List<Child> child = new
ArrayList<Child>();
private Integer pid;
更改private Parent pid;
(并添加到@OneToMane mappedBy =“parent”)Parent.setChild()
只是一项作业那是 - 通常 - 是亲子关系的最佳实践