带连接列的HQL查询

时间:2014-12-16 13:56:23

标签: mysql hibernate hql

我有3个实体

Marche的

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;
}

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 ;
}

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,这意味着hibernate忽略了where t.traveaux.idtraveau = :idtrav我应该怎么做?

EDIT1

PS:我不能直接从Marchetraveau中选择,因为表marchetraveau包含我不需要的行,从Marche选择Marchetraveau我保证我只选择Marche中包含的Marchetraveau

1 个答案:

答案 0 :(得分:0)

您需要添加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);
}