hibernate的复杂查询

时间:2014-01-23 21:02:58

标签: java sql database hibernate

我有三个表在hibernate中有实体。 DB - MySQL。我需要从实体“Item”获取其中ModelsMm.id具有某些值的字段。起初我尝试进行单独的查询,这总是需要大量的请求。所以,我试图做复杂的查询,但它已经很长时间了。

我认为有一种更简单的方法,但我不知道是什么。

我的查询和实体。

    List<Item> itemIds = session.createQuery("select it from Item it where :id in elements(it.mmPrice.modelsMm)");

    @Entity (name = "MODELS_MM")
    public class ModelsMm {

        @Id
        private int Id;

        @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
        @JoinTable(name="parth_mm", joinColumns={@JoinColumn(name="MODEL_ID", referencedColumnName="ID")}, inverseJoinColumns={@JoinColumn(name="PART_ID", referencedColumnName="ID")})
        private List<MmPrice> mmPrices;

    @Entity (name = "MM_PRICE")
    public class MmPrice {

        @Id
        private int id;

        private String article;

        @OneToOne(optional = true, fetch = FetchType.LAZY)
        @JoinColumn(name = "article", referencedColumnName = "article",insertable = false, updatable = false)
        private Item item;
        @ManyToMany
        @JoinTable(name="parth_mm", joinColumns={@JoinColumn(name="PART_ID", referencedColumnName="ID")}, inverseJoinColumns={@JoinColumn(name="MODEL_ID", referencedColumnName="ID")})
        private List<ModelsMm> modelsMm; 

    @Entity
    @Table(name="SHOP_ITEMS")
    public class Item implements Serializable {

        @Id
        private int id;
        private String article;

        @OneToOne(optional = true, fetch = FetchType.LAZY)
        @JoinColumn(name = "article", referencedColumnName = "article",insertable = false, updatable = false)
        private MmPrice mmPrice;

在控制台中我有查询

Hibernate: select item0_.ID as ID0_, item0_.ARTICLE as ARTICLE0_, item0_.article as article0_ from SHOP_ITEMS item0_ cross join MM_PRICE mmprice1_ where item0_.article=mmprice1_.article and (? in (select modelsmm2_.MODEL_ID from parth_mm modelsmm2_ where mmprice1_.ID=modelsmm2_.PART_ID))

感谢。

1 个答案:

答案 0 :(得分:0)

首先,您必须修复映射。在双向关联中,一侧必须是反面,因此使用mappedBy属性。例如,如果选择ModelsMm作为反面,则其mmPrices属性应声明为

    @ManyToMany(mappedBy = "modelsMm")
    private List<MmPrice> mmPrices;

你还应该忘记关于ManyToMany关联的CascadeType.ALL:它没有任何意义。当您删除学生时,您不想删除学生的所有课程,因为该课程也会被其他几个学生跟踪。

现在,关于您的查询,您不清楚自己想做什么。如果要选择价格至少有一个ID在ID集合中的所有项目,那么您只需要以下查询:

select distinct i from Item i
join i.mmPrice p
join p.modelsMm m
where m.id in :modelIds

附注:请修改您的命名。 mm作为前缀或后缀的不一致和不必要的使用使代码不可读。为您的班级Price,价格price类型的字段以及价格prices的集合命名。就像你用英语做的那样:物品有价格,价格有模型。