自定义hibernate实体persister

时间:2013-01-18 00:19:10

标签: java database hibernate orm

我正在进行性能测试/优化地图项目

a document <--> Java object tree <--> mysql database

用于映射的文档,Java类,数据库模式和逻辑是使用HyperJaxb3编排的。它的ORM部分是由hibernate提供的JPA。

大约有50个不同的实体,它们之间显然有很多关系。该应用程序的一个主要功能是加载文档,然后将数据重新组织为新文档;每个传入文档的所有部分最终都会在一个传出文档中发送出去。虽然我宁愿不生活在关系世界中,但交易语义非常适合这种应用 - 涉及很多资金和政府监管,所以我们需要确保一切都只交付一次。

从功能上来说,一切进展顺利,表现也不错(经过大量的调整后)。每个文档由几千个实体组成,最终在数据库中创建几千行。文档的大小各不相同,插入性能与需要插入的行数成正比(这并不奇怪)。

我看到了重大优化的可能性,这就是我的问题所在。

每个文档都映射到实体树。树的“叶子”一半包含许多详细信息,这些信息在决定如何生成传出文档时未使用。换句话说,我不需要能够通过许多表的内容来查询/过滤。

我想将相应的实体子树映射到blob,从而节省了插入/更新/索引我当前正在处理的大多数行的开销。

似乎我最好的办法是实现一个自定义的EntityPersister并将其与相应的实体相关联。这是正确的方法吗? hibernate文档也不错,但它是一个相当复杂的类需要实现,在查看javadoc后我留下了很多问题。你能指点一个我可以作为起点的具体但简单的例子吗?

有关另一种方法来处理此优化的想法吗?

1 个答案:

答案 0 :(得分:1)

我遇到了存储大量二进制数据的同样问题。我发现最好的解决方案是对象模型的非规范化。例如,我创建一个主记录,然后创建一个保存二进制数据的第二个对象。在主服务器上,使用@OneToOne映射到辅助对象,但将关联标记为惰性。现在,只有在您需要时才会加载数据。

可能减慢你速度的一件事是hibernate对这种类型的所有对象执行的outer join。要避免它,您可以将对象标记为必需。但是如果数据库没有给你带来巨大的性能影响,我建议你不要管它。我发现如果我试图获得常规连接,Hibernate会立即加载二进制数据。

最后,如果需要在单个SQL调用中检索大量二进制数据,请使用HQL fetch join命令。例如:from Article a fetch join a.data其中a.data是与二进制持有者的一对一关系。 HQL编译器会将此视为在单个sql调用中获取所有数据的指令。

HTH