一对多 - 如何正确链接到对象?

时间:2017-06-07 10:08:17

标签: java hibernate jpa one-to-many many-to-one

我使用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();

我想向Systems添加两个新检查。有效的是:

    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();

第二种解决方案将保存支票,但我不会将它们与系统联系起来。

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

1 个答案:

答案 0 :(得分:0)

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

所以在你的持久性逻辑中你还需要在你的支票中注入系统

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

但是在这种情况下,如果你的(systems.get(0))没有附加到持久化上下文,你会遇到问题,因为在持久检查时你将引用deatached对象,你可以将Cascade放在系统内部检查类或代替持久系统,它已经级联检查,因此检查将保持