gpt4 book ai didi

java - 如何扩展不可修改的模型以与 JPA 一起使用?

转载 作者:行者123 更新时间:2023-12-02 09:55:41 26 4
gpt4 key购买 nike

为来自不可修改依赖项的数据模型创建持久性(例如通过 Spring Boot 或 JPA 或 Hibernate 本身)的最佳实践是什么?典型的限制例如无法覆盖字段或装饰器之类的模式允许什么以及什么不会减慢我的进度。我尝试了一些东西,但最终的结果总是需要修改源模型(例如添加注释以使其 native 兼容 ->我不想要的 fork )或编写大量包装器代码这会过多地复制原始模型 - 但即使这样现在也不起作用:

我试过了

  • 为原始类创建一个JpaRepository。不起作用,因为将扩展类强制转换为其父类不起作用。
  • 使用自定义类扩展原始类,该自定义类可以在此类存储库中使用必要的注释,例如 @Entity。但这里的问题是
    • 原始类缺少 @Id 注释,可以通过在扩展类中使用新 ID 来修复该注释,但是
    • 给定的模型也有一个不简单的架构,包括属于模型本身的其他类的列表。因此,可能需要其他注释(例如 @ElementCollection),但无法添加这些注释,因为不可能覆盖字段。
      • 通过在新类中创建同名的新字段来隐藏它是行不通的:
      • 类似 Could not certain type for: java.util.List, at table: yes_this_one, for columns:[org.hibernate.mapping.Column(objects)] 的错误表示原始字段无法完全隐藏(更改新类中的表和列名称以验证这一点)。
      • 所以当然添加 @ElementCollection (据说可以解决这个问题)在这里也没有帮助。
    • @AttributeOverride 也无法覆盖注释来设置 ID 或其他设置,只能更改名称和列。

我陷入了这种状态,想知道这是否是正确的方法。

根据我的理解,设置或我期望的工作:

总体思路基于此 Spring Boot REST tutorial ,我尝试使用依赖项中的模型对其进行扩展。

假设存在来自无法修改的依赖项的原始模型类ModelModelEntity 将是扩展类,充当将模型拉入 Spring 持久化的方式。

在依赖关系的范围内,原始类将如下所示:

// Given dependency, not modifiable
@Some existing annotation
public class Model extends AnotherClassFromDep {

@more annotations
private IdLikeClassFromDep modelId;

//more complex attribute
@Nullable
private List<RefClassFromDep> objects = new ArrayList<>();

// more attributes, getter, setter etc.
}

在我的计划范围内:

结合这个额外的orm.xml,可以将原始Model注释为MappedSuperclass,而无需修改它(根据https://stackoverflow.com/a/2516951/1844976) )。

<?xml version="1.0" encoding="UTF-8"?>

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0">
<mapped-superclass class="package.name.of.original.Model">

</mapped-superclass>
</entity-mappings>

这允许创建一个像这样的类,它扩展了原始 POJO 模型以添加 JPA 注释:

@Entity
public class ModelEntity extends Model {

// some @Id attribute is necessary, which should correspond to
// the already existing ID attribute from the original `Model`
// in the best case, but an additional one would work too
private @Id @GeneratedValue Long id;

// Different approaches to solve the List error from above, for
// instance hiding the original attribute
@ElementCollection
private List<RefClassFromDep> objects;

public ModelEntity(){
super();
}

}

在目前的状态下,这些问题阻碍了我进一步发展。但是,总的来说,我希望它能够与 JpaRepository 一起使用:

// of course, creating a JpaRepository with original `Model` wouldn't
// work, because it has no `@Entity`
public interface ModelRepository extends JpaRepository<ModelEntity, IdLikeClassFromDep> {
}

以某种方式实际访问它是可能的:

@Configuration
public class LoadDatabase {

@Bean
CommandLineRunner initDatabase(ModelRepository modelRepository) {
return args -> {
// depending on the implementation above, either create a
// Model and cast it or directly create a ModelEntity, set
// attriubtes and save it through the JpaRepository
modelRepository.save(model);
};
}
}

更抽象和具体的与代码相关的想法和注释都会对我有帮助。谢谢!

最佳答案

过去,Jpa/Hibernate 是通过 XML 配置的。您需要提供persistence.xml用于一般配置。在此文件中,您添加了 <mapping-file>指向另一个文件的标记 orm.xml在此文件中,您为实体配置了映射(目前通过 JPA 注释完成)。

参见https://vladmihalcea.com/how-to-use-external-xml-mappings-files-outside-of-jar-with-jpa-and-hibernate/

虽然上述方法被认为是遗留方法,但它们仍然受支持。 LocalContainerEntityManagerFactoryBean有方法setMappingResources允许您指向 orm.xml文件。关于搜索路径和默认位置有一些奇怪的地方,但有详细记录: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.html#setMappingResources-java.lang.String...-

请注意,您以这种方式配置的第三方类需要符合 Java Beans 约定(无参数构造函数、getter 和 setter)

关于java - 如何扩展不可修改的模型以与 JPA 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56028437/

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