一对多 - 如何正确 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 内的系统上,或者改为保留系统,它已经级联检查,因此检查将被保留
我正在使用 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 内的系统上,或者改为保留系统,它已经级联检查,因此检查将被保留