有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在Spring投影中获取惰性属性

我目前正在尝试评估使用Spring数据JPA的可能性

在尝试使用投影时,我目前陷入了获取特定属性的困境

我有一个简单的实体,它懒洋洋地引用另一个带有外键的实体。我现在想为先前的实体定义不同的预测。“Primitive”属性可以很好地投影到投影接口中,但是尝试投影另一个实体/投影会导致它仍然被延迟加载

现在,我想告诉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);
}

共 (2) 个答案

  1. # 1 楼答案

    我不认为有什么方法可以指导JPA/Hibernate使用投影急切地获取数据。投影是在执行fetch查询之后应用的,因此修改查询为时已晚

    有一个折衷的解决方案,使用启用了FORCE_LAZY_LOADING功能的jackson-datatype-hibernate模块。这将强制初始化并返回投影中所有延迟加载的对象

    请注意,这不如使用实体图或JOIN FETCH编写自定义查询有效。它的行为与对每个延迟加载的对象调用Hibernate.initialize,执行另一个select查询相同。所以它会导致N+1选择。但这可能是一个开始的好方法。当速度开始变慢时,您仍然可以通过编写连接获取或实体图查询来进行优化

  2. # 2 楼答案

    这是一个迟来的答案,但我希望它能帮助其他人

    “@EntityGraph”注释可以提供用户信息,以便在您的案例中快速加载

    未经测试,但我想下面的存储库方法适用于您的案例。我不确定您计划的泛型方法实现的实现

    public interface BuyerRepository extends Repository<Buyer, Integer> {
    
        @EntityGraph(attributePaths = {"user"})
        List<BuyerCProjection> findProjectedById(Integer id);
    }
    

    您可以找到关于如何使用实体图here的更详细说明