我有一个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
结果。我怀疑这是我性能问题的重要部分。
答案 0 :(得分:0)
如果您要检索不需要的回复,并且想要过滤,那么您可以使用 @JsonIgnore
例如:
@ManyToOne()
@JoinColumn(name = "entity_1_id")
@JsonIgnore
private Entity1 entity1;
答案 1 :(得分:0)
几点需要考虑:
默认情况下,请考虑将关联设置为Lazy,除非您确实要沿父项加载所有关联数据及其关联。
根据我们真正想要获取的关联和关联深度,在HQL /条件中使用JOIN。
或者使用EntityGraph来决定要获取哪些关联。
启用show_sql
,因为这显示了SQL的数量以及向数据库触发的确切SQL。这将是一个很好的起点,随后您可以根据您的使用情况调整您与LAZY / EAGER,SELECT / JOIN / SUBSELECT的关联。
您可以对数据库运行这些查询,看看调优查询/数据库(索引,分区等)是否有助于缩短查询时间。
查看二级缓存是否有助于您的用例。请注意,二级缓存将具有其自身的复杂性和额外开销,尤其是如果数据是事务类型而不是大多数只读。在节点上部署应用程序,维护缓存一致性将是另一个需要考虑的方面。需要验证额外的开销和复杂性是否真的值得二级缓存的效率结果。
从应用程序设计的角度来看,您还可以考虑并查看是否确实要在单个请求或UI中检索MainEntity和关联。相反,我们可以首先使用一些分页显示MainEntity,并根据选择我们可以通过分页获取该MainEntity的关联。
请注意,这不是完整列表。但这是一个很好的起点,根据您的使用案例,您可以看到哪一个适合您和其他任何其他技术。