【发布时间】:2018-02-09 18:59:34
【问题描述】:
我有一个具有单对多关系 (ContactInfo) 的 JPA 实体 (Person)。
@Entity
public class Person {
@Id
@GeneratedValue
private Integer id;
private String name;
private String lastname;
private String sshKey;
@OneToMany(mappedBy = "personId")
private List<ContactInfo> contactInfoList;
}
@Entity
public class ContactInfo {
@Id
@GeneratedValue
private Integer id;
private Integer personId;
private String description;
}
我已经定义了一个投影接口,其中包括here 中描述的这种单对多关系。
public interface PersonProjection {
Integer getId();
String getName();
String getLastname();
List<ContactInfo> getContactInfoList();
}
public interface PersonRepository extends JpaRepository<Person,Integer> {
List<PersonProjection> findAllProjectedBy();
}
当我使用 findAllProjectedBy 检索数据时,结果包含太多行。看起来返回的数据是类似于以下内容的连接查询的结果:
select p.id, p.name, p.lastname, ci.id, ci.person_id, ci.description
from person p
join contact_info ci on ci.person_id = p.id
例如对于这个数据集:
insert into person (id,name,lastname,ssh_key) values (1,'John','Wayne','SSH:KEY');
insert into contact_info (id, person_id, description) values (1,1,'+1 123 123 123'), (2,1,'john.wayne@west.com');
findAllProjectedBy 方法返回 2 个对象(不正确),标准 findAll 方法返回 1 个对象(正确)。
完整项目是here
我做了一些调试,似乎问题出在 jpa 查询上。 findAll 方法使用此查询:
select generatedAlias0 from Person as generatedAlias0
findAllProjectedBy 使用这个查询:
select contactInfoList, generatedAlias0.id, generatedAlias0.name, generatedAlias0.lastname from Person as generatedAlias0
left join generatedAlias0.contactInfoList as contactInfoList
有人知道如何解决这种无效行为吗?
【问题讨论】:
-
这是正常行为。您到底想通过投影实现什么?也许您只需要加载包含
ContactInfos 的Persons 列表?... -
'正常行为' - 在任何地方都有记录?我正在实现的一般用例是带有视图参数的 api。视图可以是完整的 (findAll) 或有限的 (findAllProjectedBy)。我希望能够限制从数据库中检索到的数据。上面的例子非常简单。
-
对我来说似乎是一个错误/缺失的功能。你能打开一个问题吗? jira.spring.io/browse/DATAJPA/…
-
春季jira上报:jira.spring.io/browse/DATAJPA-1173
-
我正在使用 Spring Boot v2.0.0,我将得到整个对象......而不仅仅是那些用 Projection 编写的字段
标签: java jpa spring-data one-to-many projection