【问题标题】:ObjectDB relation ships对象数据库关系
【发布时间】:2013-04-01 18:34:02
【问题描述】:

我正在尝试将关系“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()。

有什么想法吗?

【问题讨论】:

  • 如果您添加负 1,请评论说明原因。没有人会从这样做中受益。谢谢
  • 到底是什么问题?是没有孩子的问题吗?你试过SELECT p FROM Parent p然后在返回的父对象上调用getChildren()吗?

标签: java jpa objectdb


【解决方案1】:

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

第一个问题,在 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 数据库。

【讨论】:

    【解决方案2】:

    我尝试了解决方案 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 原始类型。

    希望这会有所帮助...

    纳尔逊·德奥格拉西亚斯

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 2011-10-16
      • 1970-01-01
      • 1970-01-01
      • 2011-07-18
      • 1970-01-01
      • 2011-03-23
      相关资源
      最近更新 更多