我目前正在尝试评估使用Spring Data JPA的可能性。
尝试使用Projections,我目前只是试图获取特定属性Eager。
我有一个简单的实体,它使用外键延迟引用另一个实体。我现在想为前一个实体定义不同的预测。 “原始”属性很好地投射到投影界面中,但是尝试投影另一个实体/投影会导致它仍然被延迟加载。
我现在想告诉Spring / JPA急切地在预测中加载实体/投影。一种可能的方法是使用EntityGraphs(它们运行良好),但我必须使用不同的图形为每个方法创建存储库。问题是其他方式有哪些?
示例:
实体买方:
@Entity
public class Buyer {
private Integer id;
private String someProperty;
private User user;
...
@OneToOne(
fetch = FetchType.LAZY)
@JoinColumn(
name = "CAB_USR_ID",
referencedColumnName = "ID",
updatable = false,
nullable = true,
foreignKey = @ForeignKey(name = "FK_CAB_USR"))
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
实体用户:
@Entity
public class User {
private Integer id;
private String name;
...
}
投影买方
public interface BuyerCProjection {
Integer getId();
UserProjection getUser();
}
投影用户
public interface UserProjection {
Integer getId();
String getName();
}
存储库我想使用
public interface BuyerRepository extends Repository<Buyer, Integer> {
<T> List<T> findBy(Class<T> t);
}
答案 0 :(得分:0)
我不认为有一种方法可以指示JPA / Hibernate急切地使用投影来获取。投影是在执行提取查询后应用的,因此修改查询为时已晚。
有一个折衷的解决方案是使用jackson-datatype-hibernate模块并启用了FORCE_LAZY_LOADING
功能。这会强制初始化投影中所有延迟加载的对象并返回。
请注意,这不如使用实体图或JOIN FETCH
编写自定义查询有效。它的行为与在每个延迟加载的对象上调用Hibernate.initialize
相同,执行另一个select查询。因此,它导致N + 1个选择。但这可能是入门的好方法。当事情开始变慢时,您仍然可以通过编写联接获取或实体图查询进行优化。
答案 1 :(得分:-1)
这是一个很晚的答案,但是,我希望它可以帮助其他人。
“ @ EntityGraph”注释可以提供用户信息,以备您急切加载。
未经测试,但是我想下面的存储库方法可以适合您的情况。我不确定您打算使用的通用方法的实现。
public interface BuyerRepository extends Repository<Buyer, Integer> {
@EntityGraph(attributePaths = {"user"})
List<BuyerCProjection> findProjectedById(Integer id);
}
您可以找到有关如何使用实体图here
的更详细的说明