JPA Hibernate动态实体映射&;运行时的持久性
基本上,我们有一个spring引导应用程序,它要求用户可以定义他/她自己的字段集,并且这些字段应该在运行时通过JPA/Hibernate持久化到他们自己的类/表中。这些类将通过bytebuddy动态生成 所有这些都应该动态完成,而无需重新启动应用程序。 Hibernate动态映射不是一个选项,因为我们将完全创建新类并重新映射它们 我也考虑过EAV模型,但这不起作用,因为我们需要为每组数据提供单独的表,所以JSON不能在同一个表中混合 我正在考虑的第一个解决方案是代理EntityManagetFactory,当我们有一个新实体要映射时,我将重新创建EntityManagetFactory并向其中添加新的映射实体,我还将hbm2ddl.auto设置为“update”,以确保创建新表方案 问题是,我不知道还有哪些类可能需要代理,我相信我必须代理Hibernate SessionFactory,但我不确定还有多少其他类需要重新创建和代理,我相信这是一条复杂的道路 另一种解决方案是通过使用Hibernate OGM在SQL和NoSQL解决方案之间进行混合,但在这种情况下,我将失去与现有SQL实体之间的任何关系,我不赞成运行第二个NoSQL DB 我还可以探索其他解决方案吗 编辑: 我将使用bytebuddy动态生成新类,它们将具有@Entity注释,生成的类将写入临时jar文件(例如/tmp/myjar.jar) 使用BeanPostProcessor.postProcessAfterInitialization,我将用代理类替换LocalContainerEntityManagerFactoryBean 我还使用LocalContainerEntityManagerFactoryBean.setPersistenceUnitPostProcessors添加了一个额外的处理器来处理新创建的jar中的类JPA Hibernate动态实体映射&;运行时的持久性,hibernate,jpa,spring-data,spring-data-jpa,hibernate-mapping,Hibernate,Jpa,Spring Data,Spring Data Jpa,Hibernate Mapping,基本上,我们有一个spring引导应用程序,它要求用户可以定义他/她自己的字段集,并且这些字段应该在运行时通过JPA/Hibernate持久化到他们自己的类/表中。这些类将通过bytebuddy动态生成 所有这些都应该动态完成,而无需重新启动应用程序。 Hibernate动态映射不是一个选项,因为我们将完全创建新类并重新映射它们 我也考虑过EAV模型,但这不起作用,因为我们需要为每组数据提供单独的表,所以JSON不能在同一个表中混合 我正在考虑的第一个解决方案是代理EntityManagetFa
因此,现在在使用bytebuddy创建新类之后,我将手动调用LocalContainerEntityManagerFactoryBeanProxy.afterProperties来完成JPA和hibernate层的所有引导工作,我还将“hibernate.hbm2ddl.auto”属性设置为“update”,以便创建模式(我知道在生产环境中这样做很危险)Hibernate将实体映射到表,元数据是在引导过程中生成的。因此,在应用程序运行时,您不能动态修改它 但是,只要继续添加新表而不修改现有结构,就可以在体系结构级别解决此问题:
但是,如果您已经使用了RDBMS,那么就不要因为这个原因而切换到NoSQL数据库。首先,问题是如何在热部署中添加实体类。我们可以通过一些交换工具(spring boot devtools或maven copy resource)来实现。 第二,要构建实体的不同模型,可以使用JPA继承() 或JPA行映射器 但是,我发现将JSON对象持久化为数据库中的文本更容易,并让服务的使用者(前台或其他服务)来解析它 另一种方法是尝试在运行时通过类路径加载类。我将尝试将Json对象持久化为文本,并将其类型保存在ddbb中。然后在application.properties中创建其类型和类路径(数据的java类)的映射,然后执行以下操作:
static{
Map<String, String> typeClassPathMap = ......// from properties
File file = new File("c:\\class-path\\");
// Convert File to a URL
URL url = file.toURL();
// file:/c:/myclasses/
URL[] urls = new URL[]{url};
ClassLoader cl = new URLClassLoader(urls);
}
Class<?> loadClass(String type){
Class clazz = urlClassLoader.loadClass(typeClassPathMap.get(type));
}
静态{
映射类型ClassPathMap=…//from属性
文件=新文件(“c:\\class path\\”;
//将文件转换为URL
URL=file.toURL();
//文件:/c:/myclass/
URL[]URL=新URL[]{URL};
ClassLoader cl=新的URLClassLoader(URL);
}
类装入类(字符串类型){
Class clazz=urlClassLoader.loadClass(typeClassPathMap.get(type));
}
它将在运行时读取类,并可通过属性进行配置。之后,对于每种类型的数据,我们在属性文件中定义su类型和类路径。当数据来自ddbb时,我们使用其类型获取java类,并将其解析为对象。当我们需要创建新类型的数据时,我们将类保留在类路径中,并在属性中进行配置es.感谢您的反馈,但基本上我们无法重建应用程序,因为用户希望在运行时创建和填充表格并添加条目。JSON是否在多个DB提供程序上受支持?我们应该支持postgres/h2/mysql,它是否允许is查询特定字段值?2020年,这是否仍然正确在JPA中,实体无法在运行时动态定义?如果您动态定义实体类或XML映射并引导EntityManagerFactory,它将正常工作。您能否找到解决方案,我在运行时创建实体时遇到问题?这是否回答了您的问题?