我是hibernate / JPA的新手,对这个noob问题道歉。我跟随实体的关系
以下是ERD
以下是我的java课程
@Entity
@table(name="manager")
public class Manager {
private long id;
private String name;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "manager_worker", joinColumns = { @JoinColumn(name = "manager_id") },
inverseJoinColumns = { @JoinColumn(name = "worker_id") })
private ArrayList<Worker> workers = new ArrayList<Worker>();
// ......getter setter
}
@Entity
@Table(name = "worker")
public class Worker {
@Id
private long id;
private String name;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "worker_task", joinColumns = { @JoinColumn(name = "worker_id") },
inverseJoinColumns = { @JoinColumn(name = "task_id") })
private ArrayList<Task> tasks = new ArrayList<Task>();
...........................
}
@Entity
@Table(name = "task")
public class Task {
@Id
private long id;
private String title;
.................
}
我有以下数据:
当我获得Id M1的Manager对象时,结果具有Worker和Task的笛卡尔积,即W1数据重复3次,W2数据重复2次,即Manager.worker数组列表有5个worker对象而不是2
要加载我正在使用Session.get()方法的数据
public E find(final K key) {
return (E) currentSession().get(daoType, key);
}
任何人都可以告诉我如何解决这个问题并指出我在这种情况下应该使用的任何最佳做法。
由于
答案 0 :(得分:3)
这是因为两个@ManyToMany
关系都是急切加载的。
这将导致所有三个表的外连接。此查询的结果是五行,其中W1出现三次,W2出现两次。到目前为止,一切都是正确的。
但是出于某种原因,Hibernate只是将所有工作者都放在集合中,即使它们是重复的。它甚至在FAQ中描述。
有多种方法可以解决此问题:
ArrayList
作为变量类型,尤其是在使用Hibernate时)@Fetch(FetchMode.SELECT)
用于tasks
答案 1 :(得分:2)
targetEntity
关系中的@ManyToMany
在哪里?
你应该有类似的东西:
@ManyToMany(targetEntity = Task.class)
@JoinTable(name = "worker_task", joinColumns = { @JoinColumn(name = "worker_id") },
inverseJoinColumns = { @JoinColumn(name = "task_id") })
private ArrayList<Task> tasks = new ArrayList<Task>();
我建议你改为@OneToMany
和@ManyToOne
关系。这个概念与数据库设计更加兼容,当人们查看ERD时更容易理解。所以Manager
与Manager_Worker有一对多的关系,因此manager_worker与经理有多对一的关系。对其他实体保持不变。