【问题标题】:JPA Hibernate SQL Query to NOT fetch data from one of the associated tablesJPA Hibernate SQL 查询不从关联表之一获取数据
【发布时间】:2021-11-22 21:35:08
【问题描述】:

我正在尝试使用 JPA 查询使用以下查询从数据库中获取数据:

from Candidate c where c.id = :id

其中,id = Candidate_id(主表的主键)。

此查询也从其所有关联表中获取数据,而我的要求是仅从其关联表中的 2 个中获取数据。因为第三张表包含大量 JSON 数据,这会降低上述查询的响应时间。

我尝试使用 JOINFetch JOIN 的父级及其 2 个关联表,但没有成功。我还在研究如何在获取候选数据时只跳过一列数据(第三个表的列,JSON 很重),但没有运气。

是否可以使用 JPA 查询来实现它,或者我需要尝试其他方法?我很高兴使用repo.save(candidate) 一次性保存候选人及其所有相关表数据,但不想获取相关表数据之一。

这就是我在 spring-boot 中建立关联的方式:

候选实体:

@OneToOne(cascade = CascadeType.ALL,                              
        fetch = FetchType.LAZY,                                   
        mappedBy = "candidate")                                    
@JsonManagedReference                                             
private Address address;                            
                                                                  
@OneToMany(cascade = CascadeType.ALL,                             
        fetch = FetchType.LAZY,                                   
        mappedBy = "candidate")                                    
@JsonManagedReference                                             
private Set<Skills> skills= new HashSet<>();                    
                                                                  
@OneToMany(cascade = CascadeType.ALL,                             
        fetch = FetchType.LAZY,                                   
        mappedBy = "candidate")                                    
@JsonManagedReference                                             
private Set<Prefrence> prefrences = new HashSet<>();

地址实体:

@OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "candidate_id")
    @JsonBackReference
    private Candidate candidate;

技能实体:

@ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "candidate_id")
    @JsonBackReference
    private Candidate candidate;
//rest of the fields

偏好实体:

@ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "candidate_id")
    @JsonBackReference
    private Candidate candidate;
//rest of the fields

我不想在使用 candidateRepo.findById(id) 时获取 Preference 实体数据在获取的 Candidate 中应该始终为 null 附上图 diagram

【问题讨论】:

  • 如果它不应该被获取,你为什么要映射它?
  • @SimonMartinelli,我将其映射为一次将候选人的数据保存在所有关联表中。即 repo.save(candidate).
  • 您的要求与 JPA 的工作方式不匹配。
  • 好的..你的意思是如果我们通过映射保存数据,那么它会带回数据以及一切......是吗?没有 JPA 查询可以帮助我
  • 这就是它的工作方式。您已将获取类型设置为惰性,但候选对象将包含一个代理,如果您访问该属性,该代理将触发加载

标签: java spring-boot hibernate jpa


【解决方案1】:

您需要的是 DTO,我认为这是 Blaze-Persistence Entity Views 的完美用例。

我创建了该库以允许在 JPA 模型和自定义接口或抽象类定义模型之间轻松映射,例如 Spring Data Projections on steroids。这个想法是您按照自己喜欢的方式定义目标结构(域模型),并通过 JPQL 表达式将属性(getter)映射到实体模型。

使用 Blaze-Persistence Entity-Views 的用例的 DTO 模型可能如下所示:

@EntityView(Candidate.class)
public interface CandidateDto {
    @IdMapping
    Long getId();
    String getName();
    AddressDto getAddress();
    Set<SkillsDto> getSkills();

    @EntityView(Address.class)
    interface AddressDto {
        @IdMapping
        Long getId();
        String getName();
    }
    @EntityView(Skills.class)
    interface SkillsDto {
        @IdMapping
        Long getId();
        String getName();
    }
}

查询是将实体视图应用于查询的问题,最简单的就是通过 id 进行查询。

CandidateDto a = entityViewManager.find(entityManager, CandidateDto.class, id);

Spring Data 集成让您可以像使用 Spring Data Projections 一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

Page<CandidateDto> findAll(Pageable pageable);

最好的部分是,它只会获取实际需要的状态!

【讨论】:

    猜你喜欢
    • 2016-08-04
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多