当前位置: 首页 > 知识库问答 >
问题:

(N+1)用子映射集合选择问题

鄢博简
2023-03-14

朋友们!我有这些实体:

文件:

@Entity
@Table(name = "documents")
public class Document extends AbstractNamedEntity {

....
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "document_change_notices",
            joinColumns = @JoinColumn(name = "document_id"),
            inverseJoinColumns = @JoinColumn(name = "change_notice_id"))
    @MapKeyColumn(name = "change")
    private Map<Integer, ChangeNotice> changeNotices;
....

}
@Entity
@Table(name="change_notices")
public class ChangeNotice extends AbstractNamedEntity {

....
    @ElementCollection(fetch = FetchType.LAZY)
    @CollectionTable(name = "document_change_notices", joinColumns = @JoinColumn(name = "change_notice_id"))
    @MapKeyJoinColumn(name = "document_id")
    @Column(name = "change")
    private Map<Document, Integer> documents;
....

}
public interface DocumentRepository extends JpaRepository<Document, Integer> {

....
    @Query("select d from Document d left join fetch d.changeNotices where d.decimalNumber=:decimalNumber")
    Optional<Document> findByDecimalNumberWithChangeNotices(@Param("decimalNumber") String decimalNumber);
....

}
public interface ChangeNoticeRepository extends JpaRepository<ChangeNotice, Integer> {

....
    @Query("select c from ChangeNotice c left join fetch c.documents where c.id=:id")
    Optional<ChangeNotice> findByIdWithDocuments(@Param("id") int id);
....

}

所以,当我想用changeNotices获取文档时,这不是问题,我只有一个选择。但是当我想用文档获取ChangeNotice时,我有(n+1),首先是文档,n是changeNotices map。

我在查询中使用join fetch,但没有帮助。我认为问题在于,在文档中我有map ,其中实体是一个值,我应该使用@manytomany关系。在ChangeNotice中,我有映射 ,其中实体是一个键,我应该使用@ElementCollection。

是否有任何方法可以编写一个查询,在一次选择中选择带有文档的ChangeNotice?(在不更改实体代码的情况下,可能会进行一些小的修复)

共有1个答案

曹自怡
2023-03-14

所以,很多时间过去了,我没有找到答案。但这是我的架构问题。我不得不使用另一个类,它包含Document、ChangeNotice和Integer Field。我的Document和ChangeNotice实体具有这个类的具有@OneTomany关系的子集合。它解决了问题。

 类似资料:
  • 这个步骤,在默认情况下,只有源和目标之间含有相同名的表或集合会在列表中映射。如果你不想同步某些表或集合,只需从下拉式列表手动禁用它们。 相同名的键和字段也会映射。你可以在“键映射”和“字段映射”列中更改映射。

  • 这个步骤,在默认情况下,只有源和目标之间含有相同名的表或集合会在列表中映射。如果你不想同步某些表或集合,只需从下拉式菜单手动禁用它们。 相同名的键和字段也会映射。你可以在“键映射”和“字段映射”列中更改映射。

  • 这个步骤,在默认情况下,只有源和目标之间含有相同名的表或集合会在列表中映射。如果你不想同步某些表或集合,只需从下拉式列表手动禁用它们。 相同名的键和字段也会映射。你可以在“键映射”和“字段映射”列中更改映射。

  • 主要内容:集合类型,以下是纠正/补充内容:集合(Collection)是一个将多个对象分组为一个单元的java框架。它用于存储,检索和操作汇总数据。 在JPA中,可以使用集合来持久化包装类和String的对象。JPA允许三种对象存储在映射集合中 - 基本类型,实体和嵌入式类型。 集合类型 根据要求,我们可以使用不同类型的集合来持久化对象。如下所示 - List Set Map 包中包含集合框架的所有类和接口。 以下是纠正/补充内容: 根据

  • 问题内容: 我很难理解如何避免在jpa或hibernate状态下进行n + 1选择。 从我阅读的内容来看,有一个“ left join fetch”,但是我不确定它是否仍然适用于多个列表(oneToMany)。 有人可以给我解释一下,还是给我一个带有清晰完整说明的链接? 很抱歉,如果这是一个菜鸟问题,但我找不到关于此问题的真正清晰的文章或文档。 谢谢 问题答案: 除了联接之外,您还可以使用子选择。

  • TL; DR 我想以一种从AbstractP的映射方式来使用ModelMapper,然后在ModelMapper-Config中为每个子类调用特定的映射器,然后跳过其余的(abstrac类)映射。 这怎么可能?这是正确的做法吗?是否存在设计缺陷? 我所拥有的: 母公司: 一个子实体: 另一个子实体: 然后我有父DTO类: 一个孩子DTO: 另一个DTO: 在我的例子中,我将从控制器获取DTO,并在