0

我正在尝试将关系“OneToMany”添加到我正在创建的数据库中,以测试 ObjectDB 是否对我有好处。

到目前为止我所尝试的:

@Entity
public class Parent {
    @Id
    private int parentID;
    private int childFK;
    Set<Child> children;

    public Parent(int p,int c) {
    this.parentID = p;
    this.childFK = c;
    }

    @OneToMany(orphanRemoval=true)
    @JoinColumn(name="childFK")
    public Set<Child> getChildren(){
        return childern;
    }
}

这个子类是:

@Entity
public class Child {
    @Id
    private int childID;
    private String name;

    public Child(int c,String n) {
    this.childID = c;
    this.name = n;
    }
}

我的主要方法是:

   EntityManagerFactory emf = Persistence.createEntityManagerFactory("$objectdb/db/test.odb");
   EntityManager em = emf.createEntityManager();

   em.getTransaction().begin();

   Parent p = new Parent(01,02);
   em.persist(p);
   Child c = new Child(02,"bob");
   em.persist(c);

   em.getTransaction().commit();

这将创建数据库没有问题,但不存在任何关系。这是文档说明如何执行此操作。

我还尝试将 child 的实际实例添加到数据库中。这有点起作用,因为它知道有一个可用的数据库实例,但它不知道如何使用它。

我试过查询:

 SELECT p.getChildren() FROM Parent p

这只是不返回这样的方法 getChildren()。

有任何想法吗?

4

2 回答 2

2

你的测试有两个问题。修复这些错误后,父子关系将按预期创建。

第一个问题,在 JPA 中您可以使用字段访问或属性访问,但不允许混合使用它们。如果您使用 @Id 注释字段,那么您正在使用字段访问。在这种情况下,其他注释也应该在字段上而不是在属性方法上。

因此,您的 Parent 类应定义为:

@Entity
public static class Parent {
    @Id
    private int parentID;
    private int childFK;
    @OneToMany(orphanRemoval=true)
    // @JoinColumn(name="childFK") ignored by ObjectDB
    Set<Child> children;

    public Parent(int p,int c) {
        this.parentID = p;
        this.childFK = c;
    }

    public Set<Child> getChildren(){
        return children;
    }
}

第二个问题是 main 方法持久化了两个对象,一个父对象和一个子对象,但没有连接它们。您必须添加一行代码来连接这两个对象:

    EntityManager em = emf.createEntityManager();

    em.getTransaction().begin();

    Parent p = new Parent(01,02);
    em.persist(p);
    Child c = new Child(02,"bob");
    em.persist(c);
    p.children = Collections.singleton(c); // connect the child to the parent

    em.getTransaction().commit();

在使用这些修复运行测试之后,将使用该关系创建一个 ObjectDB 数据库。

于 2013-04-02T13:18:28.840 回答
0

我尝试了解决方案 p.children = Collections.singleton(c) 但它对我不起作用。这是我对这个问题的看法……让我们像上面的例子一样使用父对象和类对象。

@Entity
public class Parent { 
  @Id
  private int parentID;
  private int childFK;

  Set<Child> children;

  public Parent(int p,int c) {
    this.parentID = p;
    this.childFK = c;
  }

  . . .

  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
  @JoinColumn(name="childFK")
  public Set<Child> getChildren(){
    return childern;
  }
  public void setChildren(Set<Child> children) {
    this.children = children;
  }
}


@Entity
public class Child {
  @Id
  private int childID;      
  private String name;
  private int parentID;

  public Child(int c,String n, int p) {
    this.childID = c;
    this.name = n;
    this.parentID = p;
  }
}

在现实世界的场景中,您需要从某个来源获取 childID 值,在这种情况下,让我们从 Child 类中获取一个 id。

public int childLastID(EntityManager em){
  TypedQuery<Child> query = em.createQuery("SELECT c FROM Child c order by i.childID 
                                            DESC", Child.class);

  List<Child> chldx = query.setFirstResult(0).setMaxResults(1).getResultList();

  if(chldx == null) return 100;  // In case your Child is new and empty 
                                 // lets start with 100

  return (chldx.get(0)).getId();                                    
}

现在让我们填充那些父子类...

EntityManagerFactory emf = Persistence.createEntityManagerFactory("...");            
EntityManager em = emf.createEntityManager();

int ix = childLastID(em);

em.getTransaction().begin();
Parent p = new Parent(01, ++ix); // increment the last ID to make sure it's unique


Set<Child> cset = new HashSet<Child>();   
Child c1 = new Child(ix,"bob", 01);
cset.add(c1);

Child c2 = new Child(++ix,"beb", 01);
cset.add(c2);

Child c3 = new Child(++ix, "bib", 01);
cset.add(c3)


p.setChildren(cset);
em.persist(p)    

em.getTransaction().commit();

现在, Child c1 ... c3 的集合将保留在 Parent 类上。我在 c2 和 c3 上增加了 ++ix,因为它们需要在 Child 类上有一个唯一的 id。我在 Child 类上添加了一个 parentID,作为 Parent 和 Child 类的参考。

我使用 FetchType.EAGER 以便在检索 Parent 时也会检索这些 Child 引用。

实体类的 ID 也应该是 long 而不是 int 类型,所以只需将那些 int 更改为 long 原始类型。

希望这会有所帮助...

纳尔逊·德奥格拉西亚斯

于 2013-06-15T19:47:02.620 回答