gpt4 book ai didi

java - 在运行时创建 Spring JPA 实体

转载 作者:行者123 更新时间:2023-12-03 07:51:05 26 4
gpt4 key购买 nike

我想在运行时根据给定的数据库方案创建 JPA 实体,该实体将通过 REST-API 进行轮询,并且我需要在 Spring 上下文中注册它们。

我想到了两种方法:

  1. 使用类似于 hbm2java (hibernate-tools) 的代码生成器,在启动时生成实体。但是,每次添加表时我都必须重新启动。

  2. 也为实体生成代码,但在运行时编译 java 代码并手动在 spring 上下文中注册实体。

它必须是 Spring Data JPA,因为我想在上面设置 Spring Data(或具有 Spring 支持的 OData)。

是否有一种方法可以在运行时注册实体而无需创建 POJO/实体类(作为文件)?

最佳答案

您可以使用 Bytebuddy 在运行时创建类并将它们加载到特定的 ClassLoader 中:

    Map<String, Class<?>> fields = new HashMap<>();
fields.put("firstName", String.class);
fields.put("lastName", String.class);
fields.put("birthDate", Date.class);
fields.put("image", byte[].class);
fields.put("version", Long.class);
var className = "com.hzerai.dynamicjpa.models.Person";
var builder = new ByteBuddy().subclass(Object.class)
.annotateType(AnnotationDescription.Builder.ofType(javax.persistence.Entity.class).build());
for (Map.Entry<String, Class<?>> e : fields.entrySet()) {
builder = builder.defineField(e.getKey(), e.getValue())
.annotateField(AnnotationDescription.Builder.ofType(javax.persistence.Column.class).build());
}
builder = builder.defineField("id", Long.class).annotateField(
AnnotationDescription.Builder.ofType(javax.persistence.Id.class).build(),
AnnotationDescription.Builder.ofType(javax.persistence.Column.class).build(),
AnnotationDescription.Builder.ofType(javax.persistence.GeneratedValue.class).build());
Unloaded<?> generatedClass = builder.name(className).make();
generatedClass.load(Main.class.getClassLoader(), ClassLoadingStrategy.Default.INJECTION);
Class<?> cls = Class.forName(className);

您可以对 spring 存储库执行相同的操作。

将类加载到 classLoader 后,只需刷新 spring 上下文即可重新扫描包。

我做了类似的事情,创建实体并在运行时使用 jpa/hibernate 管理它们。

查看此存储库:https://github.com/HabibZerai/dynamic-jpa.git

关于java - 在运行时创建 Spring JPA 实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77151029/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com