我有一个小问题。 假设我有这个实体:
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与几何字段一起使用,并且几何可能非常大。因此,如果我加载许多实体,它会变慢。在某些情况下,我不想加载此字段。
答案 0 :(得分:0)
似乎当投影包含非基本类型时,所有列都将包含在查询中。
这里{@ 3}已经存在问题 ,从这个问题上看来,目前尚无法通过投影解决。
这可能对您有用https://jira.spring.io/browse/DATAJPA-1218 ,在此处https://github.com/Blazebit/blaze-persistence
中记录它使用与投影类似的实现方式。
答案 1 :(得分:0)
在这种情况下,我会选择创建一个单独的实体,该实体包含我关心的所有字段,而不是依赖于投影,因为没有默认保证投影对象将仅返回 您想要在投影中显示的字段。
我相信,它会在实际对象本身上添加一层抽象,因为它可能会检索所有列,但只有 expose < / em>少数。
考虑到该实体驱动了 most 部分的查询,创建一个单独的实体以仅拉回您想要的列可能是最方便的方法。当您想在一两个地方使用完全水化的实体时,这也将使您摆脱铸造到Person
的诱惑。