一对多 - 如何正确 Link 对象?

One-To-Many - How to Link to Objects correctly?

我正在使用 JPA,但在理解一对多关系的工作原理时遇到了一些困难。

我有以下两个类:

@Entity
public class myCheck {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    protected int Check_id;

    @Column
    private String name;

    @ManyToOne
    private mySystem system;

    @Override
    public String toString() {
        return this.name;
    }

    public int getId() {
        return Check_id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public mySystem getLinkSystem() {
        return system;
    }

    public void linkSystem(mySystem system) {
        this.system = system;
    }

}

和:

@Entity
public class mySystem {
    @Id
    @GeneratedValue
    @Column(name = "system_id")
    protected int system_id;
    @Column
    public String name;

    @ManyToOne(cascade=CascadeType.ALL)
    private mySystem parent;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "system", fetch = FetchType.EAGER)
    private List<myCheck> checks;

    public mySystem() {
        //subSystems = new ArrayList<mySystem>();
        checks = new ArrayList<myCheck>();
    }   

    public boolean linkCheck(myCheck hc) {
        return checks.add(hc);
    }

    public boolean unlinkCheck(myCheck hc) {
        return checks.remove(hc);
    }

    public List<myCheck> getlinkedChecks() {
        return checks;
    }

    public myCheck getLinkCheck(int hcId) {
        for (myCheck hc : checks) {
            if (hc.getId() == hcId)
                return hc;
        }
        return null;
    }

    public int getId() {
        return system_id;
    }

    public void setId(int id) {
        this.system_id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    @Override
    public String toString() {
        return this.getName();
    }

}

现在我的数据库中有一个已加载的系统:

    // load System
    EntityManager entityManager1 = entityManagerFactory.createEntityManager();
    List<mySystem> systems = entityManager1.createQuery("from mySystem").getResultList();
    entityManager1.close();

我想向系统添加两项新检查。正在工作的是:

    EntityManager entityManager2 = entityManagerFactory.createEntityManager();
    entityManager2.getTransaction().begin();

    myCheck check = new myCheck();
    check.setName("Check 1");
    check.linkSystem(systems.get(0));
    entityManager2.persist(check);

    myCheck check2 = new myCheck();
    check2.setName("Check 2");
    check2.linkSystem(systems.get(0));
    entityManager2.persist(check2);

    entityManager2.merge(systems.get(0));
    entityManager2.getTransaction().commit();
    entityManager2.close();

但是我做不到:

    EntityManager entityManager2 = entityManagerFactory.createEntityManager();
    entityManager2.getTransaction().begin();

    myCheck check = new myCheck();
    check.setName("Check 1");
    systems.get(0).linkCheck(check);
    entityManager2.persist(check);

    myCheck check2 = new myCheck();
    check2.setName("Check 2");
    systems.get(0).linkCheck(check);
    entityManager2.persist(check2);

    entityManager2.merge(systems.get(0));
    entityManager2.getTransaction().commit();
    entityManager2.close();

第二个解决方案将保存支票,但我不 link 系统。

有人对此有解释吗?我真的很想明白这一点。

你有双向关系,这意味着关系的每一方都应该有对另一方的引用。

因此在您的持久性逻辑中,您还需要在检查中注入系统

myCheck check = new myCheck();
check.setName("Check 1");
check.linkSystem(systems.get(0);
systems.get(0).linkCheck(check);
entityManager2.persist(check);

但在这种情况下,如果您的 (systems.get(0)) 未附加到持久性上下文,您将遇到问题,因为在持久化检查时您将引用分离的对象,您可以将 Cascade 放在检查 class 内的系统上,或者改为保留系统,它已经级联检查,因此检查将被保留