Jpa 多对多关系,生成错误 sql 查询
Jpa many to many relation, bad sql query generated
我有一个房客对象,有可能有很多联系。同一个联系人可以关联到多个房客。这是多对多的关系。
在我的房客中,
@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
在我的联系人存储库界面中,我创建了这个方法
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: illegal attempt to dereference
collection [contact0_.contact_id.lodger] with element property
reference [lodgerId]
正如您从生成的 JPQL 中看到的那样,您的映射是错误的:Hibernate 在 contact_id = lodger_id
上连接表(反之亦然),而不是在 contact_id = contact_id
上连接它们(并且 lodger_id = lodger_id
).
那是因为你用 inverseJoinColumns 反转了 joinColumns。映射应该是
@JoinTable(name = "lodger_contact",
joinColumns = @JoinColumn(name = "contact_id"),
inverseJoinColumns = @JoinColumn(name = "lodger_id"))
我有一个房客对象,有可能有很多联系。同一个联系人可以关联到多个房客。这是多对多的关系。
在我的房客中,
@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
在我的联系人存储库界面中,我创建了这个方法
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: illegal attempt to dereference collection [contact0_.contact_id.lodger] with element property reference [lodgerId]
正如您从生成的 JPQL 中看到的那样,您的映射是错误的:Hibernate 在 contact_id = lodger_id
上连接表(反之亦然),而不是在 contact_id = contact_id
上连接它们(并且 lodger_id = lodger_id
).
那是因为你用 inverseJoinColumns 反转了 joinColumns。映射应该是
@JoinTable(name = "lodger_contact",
joinColumns = @JoinColumn(name = "contact_id"),
inverseJoinColumns = @JoinColumn(name = "lodger_id"))