ObjectDB关系

时间:2013-04-01 18:34:02

标签: java jpa objectdb

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

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您的测试中存在两个问题。修复这些错误后,将按预期创建父级和子级之间的关系。

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

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

@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数据库。

答案 1 :(得分: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类型,所以只需用long原始类型更改那些int。

希望这会有所帮助......

Nelson Deogracias