Spring Data Projection加载其他字段

时间:2018-12-14 15:54:25

标签: java spring spring-data-jpa spring-data

我有一个小问题。 假设我有这个实体:

import lombok.Data;
import javax.persistence.*;
import java.util.Set;

@Data
@Entity
public class Person {

    enum SEX {F, M}

    @Id
    @GeneratedValue
    private Long id;

    @OrderBy
    @Enumerated(EnumType.STRING)
    @ElementCollection(fetch = FetchType.EAGER)
    private Set<SEX> sexes;

    private String firstName;
    private String lastName;
}

由于某些时候我不想加载名字和姓氏,因此我使用了Projections(https://docs.spring.io/spring-data/jpa/docs/1.10.2.RELEASE/reference/html/#projections): 我定义了此接口:

import java.util.Set;

public interface PersonSlim {

    String getId();
    Set<Person.SEX> getSexes();
}

现在看看这个存储库:

import org.springframework.data.repository.CrudRepository;

import java.util.List;

public interface PersonRepo extends CrudRepository<Person, Long> {

    List<PersonSlim> getAllBy();
}

如果启用SQL记录(logging.level.org.hibernate.SQL: DEBUG)并执行调用personRepo.getAllBy();,您将看到:

2018-12-14 16:36:36.808 DEBUG 14227 --- [           main] org.hibernate.SQL                        : select person0_.id as id1_0_, person0_.first_name as first_na2_0_, person0_.last_name as last_nam3_0_ from person person0_

因此,基本上,Spring会加载所有字段。如果在PersonSlim接口中排除getSexes()方法,Spring将仅加载id:

2018-12-14 16:38:03.977 DEBUG 14382 --- [           main] org.hibernate.SQL                        : select person0_.id as col_0_0_ from person person0_

如果我的投影包含ElementCollection,Spring将加载所有Field。

为什么会出现问题?
我将PostGIS-DB与几何字段一起使用,并且几何可能非常大。因此,如果我加载许多实体,它会变慢。在某些情况下,我不想加载此字段。

2 个答案:

答案 0 :(得分:0)

似乎当投影包含非基本类型时,所有列都将包含在查询中。

这里{@ 3}已经存在问题 ,从这个问题上看来,目前尚无法通过投影解决。

这可能对您有用https://jira.spring.io/browse/DATAJPA-1218 ,在此处https://github.com/Blazebit/blaze-persistence

中记录

它使用与投影类似的实现方式。

答案 1 :(得分:0)

在这种情况下,我会选择创建一个单独的实体,该实体包含我关心的所有字段,而不是依赖于投影,因为没有默认保证投影对象将仅返回 您想要在投影中显示的字段。

相信,它会在实际对象本身上添加一层抽象,因为它可能会检索所有列,但只有 expose < / em>少数。

考虑到该实体驱动了 most 部分的查询,创建一个单独的实体以仅拉回您想要的列可能是最方便的方法。当您想在一两个地方使用完全水化的实体时,这也将使您摆脱铸造到Person的诱惑。