带有Onetomany的春季数据投影返回太多结果



我有一个具有Onetomany关系(ContactInfo)的JPA实体(人)。

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

我定义了一个投影界面,其中包括此oneretomany关系,如下所述。

public interface PersonProjection {
    Integer getId();
    String getName();
    String getLastname();
    List<ContactInfo> getContactInfoList();
}
public interface PersonRepository extends JpaRepository<Person,Integer> {
    List<PersonProjection> findAllProjectedBy();
}

当我用 findAllProjected 检索数据时,结果包含太多行。看起来返回的数据是类似于以下的JOIN查询的结果:

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');

findAllProjected 方法返回2个对象(错误地)和标准 findall 返回1个对象(正确)。

完整的项目在这里

我已经进行了一些调试,似乎问题在于JPA查询。Findall方法使用此查询:

select generatedAlias0 from Person as generatedAlias0

FindAllProjected By使用此查询:

select contactInfoList, generatedAlias0.id, generatedAlias0.name, generatedAlias0.lastname from Person as generatedAlias0 
left join generatedAlias0.contactInfoList as contactInfoList

有人知道如何修复这种无效的行为吗?

此处描述了此问题的快速解决方法: https://jira.spring.io/browse/datajpa-1173

您需要用@Value注释来描述一个单个投影属性之一。对于上面发布的示例,您将最终以:

import java.util.List;
import org.springframework.beans.factory.annotation.Value;
public interface PersonProjection {
    @Value("#{target.id}")
    Integer getId();
    String getName();
    String getLastname();
    List<ContactInfo> getContactInfoList();
}

最新更新