繁体   English   中英

休眠多对多3个表

[英]Hibernate many to many 3 tables


我在休眠状态下的多妈妈关系有问题。
这个想法是:我有一个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表中有一些记录,所以现在我只需要将它们“组合”在一起。

    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。 为什么? 你能帮忙吗? 我尝试了几种选择,但没有成功。

您想要在1个关联表中映射2个关系(pracownik <-> grafik,pracownik <-> zmiany)。 很好,但是使用诸如Hibernate之类的ORM并不是那么简单。

发生的是,Hibernate无法(根据您的定义)知道两个关系都在同一关联中,因此将它们视为2个不同的关联。 因此,它尝试在关联表(grafikpracownika)中插入2行,这两行中的每行在其中一列中都为空。 这就是为什么您会收到空约束冲突的原因。

您需要做的是添加一个新实体来代表该关联。 现在,我并没有真正理解“ grapfic”的含义,所以我只给它一个通用名称“ Assoc”。 显然它将具有3个属性:idosoby,idgrafiku,idzmiany。 现在,仅将Pracownik链接到Assoc。

要解决查找员工上班时间间隔的问题,您可以简单地遍历Pracownik的所有Assocs并过滤您感兴趣的对象。但是,如果您的数据库将包含许多条目,出于效率考虑,我强烈建议删除FetchType.EAGER修饰符,并使用默认的延迟加载。 然后使用HQL将筛选留给数据库是有意义的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM