繁体   English   中英

Hibernate - 将 ElementCollection 与实体获取查询的其余部分连接起来

[英]Hibernate - join ElementCollection with the rest of an entity fetch query

当我尝试将实体映射到响应时,我遇到了主要的性能问题。

这是实体:

@Entity
@Table(name = "MyEntity")
public class MyEntity extends BaseEntity {

    @Column(name = "someOtherId", nullable = false)
    private String someOtherId;

    @ElementCollection
    @CollectionTable(name = "Phones", joinColumns = @JoinColumn(name = "myEntityId"))
    @Column(name = "phone")
    private List<String> phones; // <------- we care about this

    @ElementCollection
    @CollectionTable(name = "Websites", joinColumns = @JoinColumn(name = "myEntityId"))
    @Column(name = "websites")
    private List<String> websites; // <------- we care about this

    @Fetch(FetchMode.SUBSELECT)
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "myEntity")
    private List<ContactEntity> bbb;

    @Fetch(FetchMode.SUBSELECT)
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "myEntity")
    private List<AddressEntity> ccc;

}

这是我使用 DAL 获取它的方式:

List<MyEntity> findByTenantIdAndIdIn(String someOtherId, Set<String> MyEntityIds);

现在,当我迭代List<MyEntity>以映射它并调用myEntity.getPhones() ,我看到正在进行数据库调用,这就是导致速度变慢的原因,1000 个实体的速度变慢了 70 秒。 那么我该怎么做才能强制它join我调用findByTenantIdAndIdIn时所做的第一个查询?

笔记:

  • Phones是一个带有列的简单表:[myEntityId, phone]
  • Websites同样的问题

这与它是@ElementCollection无关。 就像您想的那样,您可以使用子选择提取,也可以使用批量大小进行选择提取(默认策略)。 另一种可能性是在查询中使用 fetch join,但在 fetch join 多个集合时要小心,因为这可能会创建笛卡尔积,从而导致传输过多行导致性能问题。 获取连接示例 HQL 查询如下所示:

SELECT e FROM MyEntity e LEFT JOIN FETCH e.phones LEFT JOIN FETCH e.websites

我发布后立即解决了它。

我用@Fetch(FetchMode.SUBSELECT)注释了手机和网站,它创建了一个并行子查询。

解决此问题的另一种方法是不使用@ElementCollection因为它的性能很差,而是使用他们在视频中推荐的实体: https : //thorben-janssen.com/hibernate-tips-query-elementcollection/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM