Java Hibernate笛卡尔积中的许多结果
我是hibernate/JPA的新手,我为这个noob问题道歉。我一直关注实体中的关系Java Hibernate笛卡尔积中的许多结果,java,hibernate,jpa,Java,Hibernate,Jpa,我是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_
- 经理与工人有多对多的关系
- 工人与任务有多对多的关系
@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;
.................
}
有人能告诉我如何解决这个问题,并指出我在这种情况下应该使用的最佳实践吗
谢谢在
@manytomy
关系中,您的目标实体
在哪里
您应该有如下内容:
@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>();
@ManyToMany(targetEntity=Task.class)
@JoinTable(name=“worker\u task”,joinColumns={@JoinColumn(name=“worker\u id”)},
inverseJoinColumns={@JoinColumn(name=“task_id”)})
私有ArrayList任务=新建ArrayList();
无论如何,我建议你换成
@OneToMany
和@ManyToOne
关系。这一概念与数据库设计更为兼容,并且在查看ERD时更易于理解。因此,Manager
与Manager\u-Worker有一对多的关系,因此Manager\u-Worker与Manager有多对一的关系。对其余实体保持相同。发生这种情况是因为@manytomy
关系都已加载
这将导致在所有三个表上进行外部联接。此查询的结果是五行,其中W1显示三次,W2显示两次。到目前为止,一切都是正确的
但由于某些原因,Hibernate只是将所有工作进程放入集合中,即使它们是重复的。它甚至在书中有描述
有多个选项可解决此问题:
- 将其中一个关系更改为延迟加载
- 使用集合而不是列表(无论如何都不应该使用
作为变量的类型,尤其是在使用Hibernate时)ArrayList
- 使用
执行@Fetch(FetchMode.SELECT)
任务
Wokrer
类中尝试@manytomy(fetch=FetchType.LAZY)
执行任务。您能告诉我们如何保存对象吗?@Shazin我还没有编写保存代码。数据已经在DB中,我正在尝试查询它。你能告诉我们你是如何从DB中获取对象的吗?我已经添加了我用来获取对象的代码。要清楚@amique,它“解决”了这个问题,因为你只需要一个元素,但是,这并没有改变所有数据仍在返回的事实;只是Hibernate现在把它们放在一个集合中,所以没有重复的。实际上,您仍然应该考虑使用FetchMode.SUBSELECT以获得更好的性能。
@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>();