我在hibernate中遇到了很多mamy关系的问题。
这个想法是:我有一个Employee(pracownik)表,一个grapfic(grafik)表和一个shift(detale zmiany)表。现在我想要一张表,我可以检查一位员工的工作情况,例如。从01.01-07.01上午6点到下午2点。
因此,该表将包含像idpracownika(employeeid),idgrafiku(graphicid)和idzmiany(shiftid)这样的列。
我所做的是:
Pracownik.class
@Entity(name = "pracownik")
@Inheritance(strategy = InheritanceType.JOINED)
@Proxy(lazy = false)
public class Pracownik
@ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL })
@JoinTable(name = "grafikpracownika", joinColumns = { @JoinColumn(name = "idosoby") },
inverseJoinColumns = { @JoinColumn(name = "idgrafiku") })
private List<Grafik> grafiki = new ArrayList<>();
@ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL })
@JoinTable(name = "grafikpracownika", joinColumns = { @JoinColumn(name = "idosoby") },
inverseJoinColumns = { @JoinColumn(name = "idzmiany") })
private List<DetaleZmiany> detaleZmiany = new ArrayList<>();
Grafik.class
@Entity(name = "grafik")
@Proxy(lazy = false)
public class Grafik
@ManyToMany(mappedBy = "grafiki", cascade = { CascadeType.ALL })
private List<Pracownik> pracownik = new ArrayList<>();
DataleZmiany
@Entity (name = "detalezmiany")
@Proxy(lazy = false)
public class DetaleZmiany {
@ManyToMany (mappedBy = "detaleZmiany",cascade = { CascadeType.ALL })
private List <Pracownik> pracownik = new ArrayList<>();
现在我在pracownik,grafik和detale zmiany表中有一些记录,所以现在我只需要&#34;结合&#34;它在一起。
public static void main(String[] args) {
PracownikService pracowniks = new PracownikService();
GrafikDao grafikdao = new GrafikDao();
DetaleZmianyDao dz = new DetaleZmianyDao();
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Pracownik emp1 = pracowniks.getPracownikById(19);
Pracownik emp2 = pracowniks.getPracownikById(20);
Grafik g1 = grafikdao.getGrafikById(1);
Grafik g2 = grafikdao.getGrafikById(2);
DetaleZmiany d1 = dz.getDetaleById(1);
DetaleZmiany d2 = dz.getDetaleById(2);
emp1.getGrafiki().add(g1);
emp1.getGrafiki().add(g2);
emp1.getDetaleZmiany().add(d1);
emp1.getDetaleZmiany().add(d2);
emp2.getGrafiki().add(g2);
emp2.getDetaleZmiany().add(d1);
pracowniks.updatePracownik(emp1);
pracowniks.updatePracownik(emp2);
}
尝试使用此代码我会收到"null value in column "idgrafiku" violates not-null constraint"
之类的例外情况
我还检查了sql插件,它看起来像:
insert
into
grafikpracownika
(idosoby, idzmiany)
values
(?, ?)
因此插入会跳过idgrafiku。为什么? 你能帮忙吗? 我尝试了几种选择但没有成功......
答案 0 :(得分:0)
您想在1个关联表中映射2个关系(pracownik&lt; - &gt; grafik,pracownik&lt; - &gt; zmiany)。这很好,但使用ORM(如Hibernate)实现它并不是那么简单。
Hibernate无法(根据您的定义)知道两个关系属于同一个关联,因此将它们视为2个不同的关联。因此,它尝试在关联表(grafikpracownika)中插入2行,这两行中的每一行在其中一列中都为null。这就是你得到空约束违规的原因。
您需要做的是添加一个代表该关联的新实体。现在,我并不真正理解&#34; grapfic&#34;的含义,所以我只给它一个通用名称&#34; Assoc&#34;。它显然有3个属性:idosoby,idgrafiku,idzmiany。现在将您的Pracownik链接到Assoc。
要解决员工工作时找到时间间隔的问题,您可以简单地遍历Pracownik的所有Assocs并过滤您感兴趣的那些。但是如果您的数据库将包含许多条目,为了提高效率我强烈建议删除FetchType.EAGER
修饰符并改为使用默认的延迟加载。然后使用HQL将过滤留到数据库是有意义的。