自定义Hibernate实体持久化器

3

我正在进行性能测试/优化一个映射项目。

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

HyperJaxb3被用来协调文档、Java类、数据库模式和映射逻辑。ORM部分使用了Hibernate提供的JPA。
这个应用大约有50种不同类型的实体,它们之间有很多关系。应用程序的一个重要功能是加载文档,然后将数据重新组织成新文档;每个传入文档的所有部分最终都会在一个传出文档中发送出去。虽然我更喜欢不生活在关系世界中,但事务语义非常适合这个应用程序 - 涉及大笔资金和政府监管,因此我们需要确保每件事情都只能交付一次。
从功能上讲,一切都很顺利,性能也还可以(进行了相当程度的调整后)。每个文档由几千个实体组成,最终在数据库中创建了几千行。文档的大小各不相同,插入性能基本上与需要插入的行数成比例(毫不意外)。
我看到了一个重要的优化潜力,这就是我的问题所在。
每个文档都映射到实体树。树的“叶子”部分包含许多详细信息,这些信息对于生成传出文档的决策并不重要。换句话说,我不需要能够查询/过滤许多表的内容。
我想将适当的实体子树映射到二进制大对象(BLOB)中,从而节省我当前处理方式中的大部分行插入/更新/索引的开销。
看起来我的最佳选择是实现一个自定义的EntityPersister并将其与适当的实体相关联。这是正确的方法吗?Hibernate文档并不坏,但它是一个相当复杂的类,需要实现,看了javadoc后我还有很多问题。你能给我指出一个具体但简单的例子,作为起点吗?
对于另一种方法来解决这个优化问题,你有什么想法吗?
1个回答

1

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

可能会减慢速度的一件事是Hibernate执行的所有此类型对象的outer join。为了避免这种情况,您可以将对象标记为强制性的。但是,如果数据库不会给您带来巨大的性能损失,建议您不要管它。我发现,如果我尝试获取常规连接,Hibernate倾向于立即加载二进制数据。

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

希望对您有所帮助


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接