我有3个实体

马尔凯

public class Marche implements  Serializable,Cloneable{


    @Id
    @GeneratedValue(strategy = GenerationType.TABLE,generator="marche" )

    @OneToMany(fetch=FetchType.EAGER,cascade= CascadeType.ALL )
    @org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.SUBSELECT)
    private List<Marchetraveau> marchetraveau;
}


马尔凯特拉沃

public class Marchetraveau implements  Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE,generator="marchetraveau" )
    @Column(name="idmarchetraveau")
    private int idmarchetraveau;

    @OneToOne
    @JoinColumn(name="idtraveau")
    private Traveaux traveaux ;
}


特拉沃

public class Traveaux implements  Serializable{

private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE,generator="traveau" )
    @Column(name="idtraveau")
    private int idtraveau;
    @Column(name="article")
    private String article;
    @Column(name="designation")
    private String designation;
}


我想选择具有等于参数的Traveaux.idtraveau的Marchetraveau,所以我写了以下查询

Query q = em.createQuery("select mar.marchetraveau  from Marche mar inner join mar.marchetraveau as t where t.traveaux.idtraveau = :idtrav ");

        q.setParameter("idtrav", idtrav);


但是这里的问题是结果是来自所有Marche的所有marchetraveau,这意味着休眠状态正在忽略where t.traveaux.idtraveau = :idtrav我该怎么办?

编辑1

PS:我无法直接从Marchetraveau中进行选择,因为表格marchetraveau包含了我不需要的行,通过从Marche中选择Marchetraveau,我保证我只选择了Marche中包含的Marchetraveau

最佳答案

您需要添加从Marcheveau到Marche的引用:

public class Marchetraveau implements  Serializable {

    @ManyToOne
    @JoinColumn(name="idmarche", insertable=false, updatable=false)
    private Marche marche;
}


通常最好由@ManyToOne负责关联,所以这样做会更好:

public class Marchetraveau implements  Serializable {

    @ManyToOne
    @JoinColumn(name="idmarche")
    private Marche marche;
}

public class Marche implements  Serializable,Cloneable {

    @OneToMany(fetch=FetchType.EAGER,cascade= CascadeType.ALL, mappedBy="marche")
    @org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.SUBSELECT)
    private List<Marchetraveau> marchetraveau;

}


因此,现在@OneToMany端已被映射,它是@ManyToOne FK端来控制此双向关联。

通过建立这种双向关联,我们可以在查询中加入Marche:

Query q = em.createQuery(
"select m " +
"from Marchetraveau m " +
"inner join m.marche " +
"inner join m.traveaux t " +
"where t.idtraveau = :idtrav"
);
q.setParameter("idtrav", idtrav);
q.getResultList();


更新资料

对于双向关联,无论何时添加/删除孩子,都必须设置双方:

public addChild(Marchetraveau marchetraveau) {
    marche.getMarchetraveau().add(marchetraveau);
    marchetraveau.setMarche(marche);
}

public removeChild(Marchetraveau marchetraveau) {
    marche.getMarchetraveau().remove(marchetraveau);
    marchetraveau.setMarche(null);
}

10-06 12:59