【问题标题】:How to change Hibernate GenerationType identifier depending on the underlying database如何根据底层数据库更改 Hibernate GenerationType 标识符
【发布时间】:2018-11-26 09:24:47
【问题描述】:

我有一个名为 ma​​in_project 的项目(使用 spring-boot v2),其中包含所有配置类,包括 JPA 配置ma​​in_project 也有实体类(如 User、Personnel)。

ma​​in_project托管实体类的JPA配置如下:

@Entity
public abstract class MainEntity<T extends Serializable> {
    @Id
    @GeneratedValue(GenerationType=?)
    @Column(name = "id")
    private T id;
}

@Entity
public class Personnel extends MainEntity<Long> {
    @Column(name = "firstName")
    private String firstName;

    // other proprties
}

其他项目正在使用 ma​​in_project 作为引导的依赖项。其他依赖于 ma​​in_project 的项目可以使用 Personnel 或 User 和 ... 实体,它们可以有不同的 DBMS,例如 MySQLOracle。 p>

当我使用 ma​​in_project 作为项目 A 中的依赖项时,A 项目extends MainEntity&lt;?&gt; 的实体类并创建它自己的实体类和拥有自己的数据库配置文件。

我的问题在于 ma​​in_projectid 属性的 DBMS 类型和 GenerationType

  • 1)A项目使用Mysql数据库时,MainEntity必须有:

    @GeneratedValue(strategy = GenerationType.IDENTITY)

  • 2)A项目使用Oracle数据库时,MainEntity必须有:

    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "id_generator") @SequenceGenerator(name="id_generator", sequenceName = "id_seq", allocationSize=1)

项目 A 如何检测其数据库类型并在上述方法之间切换?

我认为我需要在运行时反映 java util,并根据数据库类型添加一些注释!对吗?

我也读过,this_post_19875993,但没有帮助。

this_post_30731627 解释说我们可以选择自定义 GenerationType 之一,但我想自动选择而不对 ma​​in_project 进行任何更改,因为 A project 不能改变 ma​​in_projectMainEntity 类,只能使用它。

【问题讨论】:

  • @vlad-mihalcea 你的想法是什么?

标签: java spring hibernate jpa hibernate-entitymanager


【解决方案1】:

您可以在基类中使用SEQUENCE 标识符:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "id_generator") 
@SequenceGenerator(name="id_generator", sequenceName = "id_seq", allocationSize=1)
private Long id;

并使用外部mysql-orm.xml 配置文件为 MySQL 覆盖它:

<entity-mappings
    xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm orm_2_1.xsd"
    version="2.1"
        >
    <package>com.vladmihalcea.book.hpjp.hibernate.identifier.global</package>
    <entity class="Post" access="FIELD">
        <attributes>
            <id name="id">
                <generated-value strategy="IDENTITY"/>
            </id>
        </attributes>
    </entity>
</entity-mappings>

因此,对于 Oracle 和 PostgreSQL,您不必提供 mysql-orm.xml,对于 MySQL,只需在使用 mysql 配置文件构建项目时通过 persistence.xml 配置文件提供此文件:

<persistence
    xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
    http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
    version="2.1">
 
    <persistence-unit name="persistenceUnit">
 
        <provider>
            org.hibernate.jpa.HibernatePersistenceProvider
        </provider>
 
        <mapping-file>
            mappings/identifier/global/mysql-orm.xml
        </mapping-file>
 
        <class>
            com.vladmihalcea.book.hpjp.hibernate.identifier.global.Post
        </class>
 
    </persistence-unit>
</persistence>

就是这样。

【讨论】:

    【解决方案2】:

    您可以在项目A中使用orm.xml根据JPA specification覆盖ID列的映射配置:

    可以指定名为 orm.xml 的对象/关系映射 XML 文件 在持久单元根目录的 META-INF 目录中或 引用的任何 jar 文件的 META-INF 目录 持久性.xml。

    另外,或者另外,一个或多个映射文件可以是 由持久性单元的映射文件元素引用 元素。这些映射文件可能存在于类中的任何位置 路径。

    — JPA 2.1 规范的第 8.2.1.6.2 节

    有关示例,请参阅 thisthis

    【讨论】:

    • 嗨。感谢您的回复,但是通过这种方法,我必须为每个应用程序创建 orm.xml,然后在其中添加 main_project 和 child_project 的整个实体。是否有任何编程方法可以自动覆盖 id 的映射配置?
    • 如果您想以编程方式进行,我相信您需要尝试使用 Hibernate Metadata API (docs.jboss.org/hibernate/orm/5.3/userguide/html_single/…)。或者,我会编写一个程序来扫描所有实体类,然后生成 orm.xml,这应该是 IMO 更容易的任务。
    • 好的,谢谢,我尝试编写一个程序来生成 orm.xml。只是,以后有可能加入hibernate框架吗?
    猜你喜欢
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    相关资源
    最近更新 更多