我有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);
}