我有一个maven构建的基于CDI的Java SE应用程序,它有一个核心模块和其他模块.
核心有persistence.xml一些实体.模块有其他实体.
如何将实体添加到持久性单元的聚光灯下?
我已阅读Hibernate手册,http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/configuration.html#setup-configuration-packaging
我也看过这些问题
我正在寻找一个解决方案,其中Hibernate将扫描所有加载的类,或者,将从其他罐中获取一些配置文件(例如CDI所做的beans.xml).
我的应用程序不使用Spring.我不坚持可移植性 - 我会坚持使用Hibernate.
persistence.xml并向其添加类?EntityManagerFactory可以在创建后添加@Entity类吗?更新:我发现org.?hibernate.?ejb.?Ejb3Configuration:
public Ejb3Configuration configure(String persistenceUnitName, Map integration)
Run Code Online (Sandbox Code Playgroud)
使用Hibernate,您可以将Entity类加载为:
sessionFactory = new AnnotationConfiguration()
.addPackage("test.animals")
.addAnnotatedClass(Flight.class)
.addAnnotatedClass(Sky.class)
.addAnnotatedClass(Person.class)
.addAnnotatedClass(Dog.class);
Run Code Online (Sandbox Code Playgroud)
有没有办法做同样的事情 - 以编程方式加载您的实体类 - 以符合JPA 2.0的方式?
这个问题的原因是因为我想动态加载我的Entity类,因此不一定以编程方式.
现在我正在创建EntityManagerFactory这样的:
Map<String, String> properties = ImmutableMap.<String, String>builder()
.put(DRIVER, "com.mysql.jdbc.Driver")
.put(DIALECT, "org.hibernate.dialect.MySQL5Dialect");
.put(USER, dbUsername)
.put(PASS, dbPassword)
.put(URL, dbConnectionUrl)
//Some more properties
.build();
Ejb3Configuration cfg = new Ejb3Configuration();
cfg.configure(properties);
cfg.addAnnotatedClass(AuditEntry.class);
cfg.addAnnotatedClass(LastWrittenEventId.class);
//Some more annotated classes
return cfg.createEntityManagerFactory();
Run Code Online (Sandbox Code Playgroud)
但是正如我在javadocs中看到的那样,Ejb3Configuration不推荐使用它,我不应该使用它.我应该Persistence.createEntityManagerFactory()按照JPA规范 7.3节使用.但是后来我只能传递一些属性,但是我可以以某种方式添加带注释的类吗?
基本上我们有一个 spring boot 应用程序,它要求用户可以定义他/她自己的一组字段,并且这些字段应该在运行时通过 JPA/Hibernate 保存在他们自己的类/表中。这些类将通过 bytebuddy 动态生成。
所有这些都应该动态完成,而不必重新启动应用程序。Hibernate 动态映射不是一个选项,因为我们将完全创建新类并重新映射它们。
我还考虑了 EAV 模型,但它不起作用,因为我们需要为每组数据使用单独的表,因此 JSON 不能混合在同一个表中。
我正在考虑的第一个解决方案是代理 EntityManagetFactory,当我们有一个新实体要映射时,我将重新创建 EntityManagetFactory 并将新映射的实体添加到它,我还将设置 hbm2ddl.auto “更新”以确保创建新表方案。
问题是我不知道哪些其他类可能需要代理,我相信我必须代理 Hibernate SessionFactory,但我不确定需要重新创建和代理多少其他类,我相信这是一条复杂的道路。
另一种解决方案是通过使用 Hibernate OGM 在 SQL 和 NoSQL 解决方案之间进行混合,但在这种情况下,我将失去与现有 SQL 实体之间的任何关系,并且我不赞成运行第二个 NoSQL DB。
我可以探索其他任何解决方案吗?
编辑:
我会使用 bytebuddy 来动态生成新类,并且它们会有 @Entity 注释,生成的类被写入临时 jar 文件(例如 /tmp/myjar.jar )
使用 BeanPostProcessor.postProcessAfterInitialization 我将用代理类替换 LocalContainerEntityManagerFactoryBean。
我还使用 LocalContainerEntityManagerFactoryBean .setPersistenceUnitPostProcessors 添加了一个额外的处理器来处理新创建的 jar 中的类
因此,现在在使用 bytebuddy 创建新类后,我将手动调用 LocalContainerEntityManagerFactoryBeanProxy.afterProperties 来完成引导 JPA 和休眠层的所有工作,我还将“hibernate.hbm2ddl.auto”属性设置为“更新”,以便将创建架构(我知道在生产环境中这样做是有风险的)