【问题标题】:JPA getSingleResult did not retrieve the associated @OneToMany entitesJPA getSingleResult 未检索到关联的 @OneToMany 实体
【发布时间】:2020-08-06 11:34:26
【问题描述】:

正如标题所示,getSingleResult 没有检索关联的 OneToMany 实体。但事情是这样的,它在我重新部署项目后工作(顺便说一句,这是一个 JSF 项目)。

租赁等级:

  @Id
  @Basic(optional = false)
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  private Integer id;
  @Column(name = "leaseDate")
  @Temporal(TemporalType.DATE)
  private Date leaseDate;
  @Column(name = "returnDate")
  @Temporal(TemporalType.DATE)
  private Date returnDate;
  @Column(name = "status")
  private Integer status;
  
  @OneToMany(cascade = CascadeType.ALL, mappedBy = "lease")
  private Collection<LeaseDetail> leaseDetailCollection;

租约详情:

  @EmbeddedId
  protected LeaseDetailPK leaseDetailPK;
  @Column(name = "status")
  private Integer status;
  @JoinColumn(name = "bookId", referencedColumnName = "id", insertable = false, updatable = false)
  @ManyToOne(optional = false)
  private Book book;
  @JoinColumn(name = "leaseId", referencedColumnName = "id", insertable = false, updatable = false)
  @ManyToOne(optional = false)
  private Lease lease;

我如何将 Lease 和 LeaseDetail 插入 DB:

  public Lease insert(Lease lease){
    em.persist(lease);
    return lease;
  }
  
  public void insertDetail(List<LeaseDetail> details){
    for (LeaseDetail leaseDetail : details) {
      em.persist(leaseDetail);
    }
  }

我如何从数据库中获取租赁,按 ID 过滤:

  public Lease findLease(int id){ //THE PROBLEM: only retrieve associated LeaseDetail AFTER redeploying project
    try{
      return em.createNamedQuery("Lease.findById",Lease.class) //@NamedQuery(name = "Lease.findById", query = "SELECT l FROM Lease l WHERE l.id = :id")
          .setParameter("id", id)
          .getSingleResult();
    }catch(Exception e){
      e.printStackTrace();
      return null;
    }
  }

如果我插入一个带有少量关联 LeaseDetail 的 Lease(比如说 Lease A),然后继续从数据库中获取新插入的 Lease(Lease A),它没有关联的 LeaseDetail,即使 Lease it self 已完全检索。

现在,如果我重新部署项目,然后继续获取 Lease A,那么它只有关联的 LeaseDetail 集合。我似乎无法发现问题。

【问题讨论】:

    标签: java jpa


    【解决方案1】:

    如果您总是想从实体中检索关联的集合。您可以在 @NamedQuery 中使用 JOIN FETCH。

    @NamedQuery(name = "Lease.findById", query = "SELECT l FROM Lease l JOIN FETCH l.leaseDetailCollection WHERE l.id = :id")
    

    【讨论】:

      【解决方案2】:

      关系@OneToMany 的默认行为是惰性获取。您可以通过在注解中添加fetch=FetchType.EAGER 来覆盖获取类型。

      @OneToMany(fetch=FetchType.EAGER) 
      

      在现实世界的编程中当然要小心,这可能会导致您从数据库中获取过多的数据。

      如果您想了解更多关于延迟获取的信息

      https://thorben-janssen.com/5-ways-to-initialize-lazy-relations-and-when-to-use-them/

      【讨论】:

        猜你喜欢
        • 2011-02-06
        • 1970-01-01
        • 2020-01-30
        • 1970-01-01
        • 2015-07-19
        • 1970-01-01
        • 2021-12-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多