我正在尝试将一个关系“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()。
有什么想法吗?
答案 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