jpa关系很多很多,生成错误的sql查询

时间:2015-10-23 13:35:43

标签: hibernate jpa spring-data spring-data-jpa

我有一个住宿对象,有可能有很多联系。相同的联系人可以与许多住客相关联。这是一个多对多的关系。

我有住宿,

@ManyToMany(mappedBy = "lodger")
private List<Contact> contactList;

联系我,

@ManyToMany
@JoinTable(name = "lodger_contact", joinColumns = @JoinColumn(name = "lodger_id"), inverseJoinColumns = @JoinColumn(name = "contact_id"))
private List<Lodger> lodger;

我使用spring-jpa数据。使用的Jpa实现是hibernate

在我的Contact资源库界面中,我创建了此方法

List<Contact> findByLodgerLodgerIdNot(Long lodgerId);

我有一个房客和一个联系人(没有关联)。当我调用此方法时,不会返回任何内容。

生成的查询是

    select
    contact0_.contact_id as contact_1_9_,
    contact0_.address as address2_9_,
    contact0_.city_cityId as city_cit5_9_,
    contact0_.contact_sub_category_contactSubCategoryId as contact_6_9_,
    contact0_.first_name as first_na3_9_,
    contact0_.last_name as last_nam4_9_,
    contact0_.phone_phoneId as phone_ph7_9_ 
from
    contact contact0_ 
left outer join
    lodger_contact lodger1_ 
        on contact0_.contact_id=lodger1_.lodger_id 
left outer join
    lodger lodger2_ 
        on lodger1_.contact_id=lodger2_.lodger_id 
where
    lodger2_.lodger_id<>?

编辑,我完成了JB Nizet提出的更改

select
    contact0_.contact_id as contact_1_9_,
    contact0_.address as address2_9_,
    contact0_.city_cityId as city_cit5_9_,
    contact0_.contact_sub_category_contactSubCategoryId as contact_6_9_,
    contact0_.first_name as first_na3_9_,
    contact0_.last_name as last_nam4_9_,
    contact0_.phone_phoneId as phone_ph7_9_ 
from
    contact contact0_ 
left outer join
    lodger_contact lodger1_ 
        on contact0_.contact_id=lodger1_.contact_id 
left outer join
    lodger lodger2_ 
        on lodger1_.lodger_id=lodger2_.lodger_id 
where
    lodger2_.lodger_id<>?

相同的结果

编辑2

使用此代码,该工作

@Query("select c from Contact c where :lodger not member of c.lodger")
List<Contact> findByLodgerLodgerIdNot(@Param("lodger") Lodger lodger);

可以使用lodgerId吗?

而不是使用lodger

生成此代码

select
    contact0_.contact_id as contact_1_9_,
    contact0_.address as address2_9_,
    contact0_.city_cityId as city_cit5_9_,
    contact0_.contact_sub_category_contactSubCategoryId as contact_6_9_,
    contact0_.first_name as first_na3_9_,
    contact0_.last_name as last_nam4_9_,
    contact0_.phone_phoneId as phone_ph7_9_ 
from
    contact contact0_ 
where
    ? not in  (
        select
            lodger1_.lodger_id 
        from
            lodger_contact lodger1_ 
        where
            contact0_.contact_id=lodger1_.contact_id

编辑3

@Query("select c from Contact c where :lodgerId not member of c.lodger.lodgerId")
List<Contact> findByLodgerLodgerIdNot(@Param("lodgerId") Long lodger);
  

org.hibernate.QueryException:非法尝试取消引用   使用element属性收集[contact0_.contact_id.lodger]   参考[lodgerId]

1 个答案:

答案 0 :(得分:2)

从生成的JPQL中可以看出,您的映射是错误的:Hibernate加入contact_id = contact_id上的表(反之亦然),而不是lodger_id = lodger_id上加入它们(和@JoinTable(name = "lodger_contact", joinColumns = @JoinColumn(name = "contact_id"), inverseJoinColumns = @JoinColumn(name = "lodger_id")) })。

那是因为您使用inverseJoinColumns反转了joinColumns。映射应该是

newlines: \n