Hibernate @ ManyToOne / @ JoinColumn优化

时间:2018-03-16 12:51:08

标签: java hibernate hibernate-mapping

我有一个Hibernate实体,它由在应用程序中使用的许多其他实体组成。组成此MainEntity的其他实体使用@ManyToOne@JoinColumn加入。此MainEntity类包含5列(@Column)和7 @ManyToOne / @JoinColumn个实体。

在检索所有这些MainEntity类时,我似乎遇到了性能问题。我们希望将MainEntity序列化为JSON以及与其关联的其他实体。请注意,我们正在检索的数量不多 - 总共少于30个。

以下是该类与我的findAll()方法一起检索这些类的示例。我知道@ManyToOne默认为EAGER,所以我想知道是否有更好的方法让所有这些实体在系统上更容易。提前谢谢。

@Entity(name = "MainEntity")
@Table(name = "main_entity")
public class MainEntity {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  private Integer id;

  // Other @Columns defined here

  @ManyToOne()
  @JoinColumn(name = "entity_1_id")
  private Entity1 entity1;

  @ManyToOne()
  @JoinColumn(name = "entity_2_id")
  private Entity2 entity2;

  @ManyToOne()
  @JoinColumn(name = "entity_3_id")
  private Entity3 entity3;

  // ... and so on, for a total of 7 @ManyToOne() columns
}

以下是findAll()方法:

final List<E> findAllOrdered(Class<E> clazz, Order order) {
    final Session session = sessionManager.openNewSession();
    try {
        return session.createCriteria(clazz)
                .addOrder(order)
                .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
                .list();
    } finally {
        sessionManager.closeSession(session);
    }
}

我发现自己必须添加Criteria.DISTINCT_ROOT_ENTITY,因为如果孩子有多个与之关联,我们会收到重复的MainEntity结果。我怀疑这是我性能问题的重要部分。

2 个答案:

答案 0 :(得分:0)

如果您要检索不需要的回复,并且想要过滤,那么您可以使用 @JsonIgnore

例如:

  @ManyToOne()
  @JoinColumn(name = "entity_1_id")
  @JsonIgnore
  private Entity1 entity1;

答案 1 :(得分:0)

几点需要考虑:

  1. 默认情况下,请考虑将关联设置为Lazy,除非您确实要沿父项加载所有关联数据及其关联。

  2. 根据我们真正想要获取的关联和关联深度,在HQL /条件中使用JOIN。

  3. 或者使用EntityGraph来决定要获取哪些关联。

  4. 启用show_sql,因为这显示了SQL的数量以及向数据库触发的确切SQL。这将是一个很好的起点,随后您可以根据您的使用情况调整您与LAZY / EAGER,SELECT / JOIN / SUBSELECT的关联。

  5. 您可以对数据库运行这些查询,看看调优查询/数据库(索引,分区等)是否有助于缩短查询时间。

  6. 查看二级缓存是否有助于您的用例。请注意,二级缓存将具有其自身的复杂性和额外开销,尤其是如果数据是事务类型而不是大多数只读。在节点上部署应用程序,维护缓存一致性将是另一个需要考虑的方面。需要验证额外的开销和复杂性是否真的值得二级缓存的效率结果。

  7. 从应用程序设计的角度来看,您还可以考虑并查看是否确实要在单个请求或UI中检索MainEntity和关联。相反,我们可以首先使用一些分页显示MainEntity,并根据选择我们可以通过分页获取该MainEntity的关联。

  8. 请注意,这不是完整列表。但这是一个很好的起点,根据您的使用案例,您可以看到哪一个适合您和其他任何其他技术。