JPA Hibernate 动态实体映射 &运行时的持久性 [英] JPA Hibernate Dynamic entity mapping & persistence at runtime

查看:53
本文介绍了JPA Hibernate 动态实体映射 &运行时的持久性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上我们有一个 Spring Boot 应用程序,它要求用户可以定义他/她自己的一组字段,并且这些字段应该在运行时通过 JPA/Hibernate 持久化在他们自己的类/表中.这些类会通过bytebuddy动态生成.

Basically we have a spring boot application that requires that the user can define his/her own set of fields and that these fields should be persisted in their own class/table through JPA/Hibernate at runtime. These classes will be generated dynamically through bytebuddy.

所有这些都应该动态完成,而无需重新启动应用程序.Hibernate 动态映射不是一个选项,因为我们将完全创建新类并重新映射它们.

All that should be done dynamically without having to restart the application. The Hibernate Dynamic mapping is not an option, since we will be creating new classes entirely and re-map them.

我也考虑过 EAV 模型,但是这行不通,因为我们需要为每组数据设置单独的表,因此 JSON 不能混合在同一个表中.

I have also considered an EAV model but that will not work since we will need separate tables for each set of data so the JSON cannot be mixed in the same table.

我正在考虑的第一个解决方案是代理 EntityManagetFactory,当我们有一个新实体要映射时,我将重新创建 EntityManagetFactory 并将新的映射实体添加到其中,我还将拥有 hbm2ddl.auto 设置为update",以确保创建新的表方案.

The first solution that I'm considering is to proxy the EntityManagetFactory and when we have a new entity to map , I'll re-create the EntityManagetFactory and add the new mapped entity to it, I'll also have the hbm2ddl.auto set to "update" in order to ensure that the new tables scheme will get created.

问题是我不知道可能需要代理哪些其他类,我相信我必须代理 Hibernate SessionFactory 但我不确定需要重新创建和代理多少其他类我相信这是一条复杂的道路.

Problem is that I don't know what other classes that might need proxying, I believe I'll have to proxy the Hibernate SessionFactory but I'm not sure how many other classes that will need to be re-created and proxied and I believe that this is a complex path to go.

另一种解决方案是使用 Hibernate OGM 在 SQL 和 NoSQL 解决方案之间进行混合,但在这种情况下,我将失去与现有 SQL 实体的任何关系,并且我不赞成运行第二个NoSQL 数据库.

The other solution is to mix between the SQL and NoSQL solution by using Hibernate OGM, but in that case I'll loose any relationship that I can have with the existing SQL entities and I'm not in favor of running a second NoSQL DB.

还有其他我可以探索的解决方案吗?

is there are any other solutions I can explore ?

我会使用 bytebuddy 来动态生成新类,它们会有 @Entity 注释,生成的类被写入一个临时 jar 文件(例如/tmp/myjar.jar)

I would use bytebuddy in order to generate the new classes dynamically and they would have the @Entity annotation, the generated classes are written into a temporary jar file ( e.g. /tmp/myjar.jar )

使用 BeanPostProcessor.postProcessAfterInitialization 我会用代理类替换 LocalContainerEntityManagerFactoryBean.

Using a BeanPostProcessor.postProcessAfterInitialization I would replace the LocalContainerEntityManagerFactoryBean with a proxy class.

我还使用 LocalContainerEntityManagerFactoryBean .setPersistenceUnitPostProcessors 添加了一个额外的处理器来处理新创建的 jar 中的类

Also I used the LocalContainerEntityManagerFactoryBean .setPersistenceUnitPostProcessors to add an extra processor that would process the classes from the newly created jar

所以现在在使用 bytebuddy 创建新类之后,我将手动调用 LocalContainerEntityManagerFactoryBeanProxy.afterProperties 来完成引导 JPA 和休眠层的所有工作,我还将hibernate.hbm2ddl.auto"属性设置为更新"以便创建架构(我知道在生产环境中这样做是有风险的)

So now after creating the new class with bytebuddy I would manually call the LocalContainerEntityManagerFactoryBeanProxy.afterProperties that does all the job of bootstrapping the JPA and hibernate layer , I do also set the "hibernate.hbm2ddl.auto" property to "update" so that the schema would be created ( I know that this is risky to be done in a production environment )

推荐答案

Hibernate 将实体映射到表,元数据在引导期间构建.因此,您不能在应用程序运行时即时修改它.

Hibernate maps entities to tables, and the metadata is built during bootstrap. So, you can't modify it on the fly while the application is running.

但是,只要您在不修改现有结构的情况下继续添加新表,就可以在架构级别解决此问题:

However, as long as you keep on adding new tables without modifying the existing structure, you can address this issue at the architecture level:

  1. 您可以根据需要进行类更改.
  2. 您构建项目工件.
  3. 您将新项目工件部署到新服务器.
  4. 您无需停机即可将流量从旧服务器实例切换到负载均衡器中的新服务器实例.

或者,只需使用 NoSQL 数据库(如 MongoDB 和 Hibernate OGM),因为您的要求无论如何都不太适合关系数据库.

Or, just use a NoSQL database like MongoDB with Hibernate OGM since your requirements do not fit very well into a relational database anyway.

但是,如果您已经使用 RDBMS,那么 使用 JSON 更简单 而不是仅仅因为这个原因切换到 NoSQL 数据库.

But, if you already use a RDBMS, then it's simpler to just use JSON instead of switching to a NoSQL database just for that reason.

这篇关于JPA Hibernate 动态实体映射 &运行时的持久性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆