0

我试图编写一个简单的测试程序来模拟我项目中的两个对象并遇到麻烦。基本上我有两个简单的对象,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 不起作用?

4

1 回答 1

0

当您在子表中@OneToMany没有时,您怎么能有一个? 您缺少与单亲相关的多个孩子的钥匙;添加到表并使用该列ParentId
ParentIdChild@JoinColumn(name = "ParentId")

编辑:

  • 初始化Parent.child_private List<Child> child = new ArrayList<Child>();
  • 更改private Integer pid;private Parent pid;(并添加到 @OneToMane mappedBy="parent")
  • 尝试注释字段而不是设置器
  • 让你Parent.setChild()只是一个任务

这通常是亲子关系的最佳实践

于 2013-09-03T18:51:19.297 回答