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

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

问题描述

基本上,我们有一个Spring Boot应用程序,要求用户可以定义自己的字段集,并且这些字段应在运行时通过JPA/Hibernate保留在自己的类/表中.这些类将通过字节预算动态生成.

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 Dynamic映射,因为我们将完全创建新类并重新映射它们.

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层的所有工作,我还将"hibernate.hbm2ddl.auto"属性设置为"update"以便创建架构(我知道在生产环境中这样做很冒险)

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,则

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天全站免登陆