如何根据底层数据库更改Hibernate GenerationType标识符

时间:2018-06-17 05:57:15

标签: java spring hibernate jpa hibernate-entitymanager

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

main_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
}

其他项目使用 main_project 作为引导的依赖项。依赖于 main_project 的其他项目可以使用Personnel或User和......实体,它们可以有不同的DBMS,如 MySQL Oracle

当我使用 main_project 作为项目 A 中的依赖项时, A 项目extends MainEntity<?>的实体类并创建它自己的实体类和拥有自己的数据库配置文件。

我的问题在于DBMS的类型和主要项目 id 属性的 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 之一,但我想自动选择而不对 main_project 进行任何更改,因为 A 项目无法更改主要项目 MainEntity 类,只是可以使用它。

2 个答案:

答案 0 :(得分:1)

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

  

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

     

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

     

- JPA 2.1规范的第8.2.1.6.2节

请参阅thisthis以获取示例。

答案 1 :(得分:1)

正如我在this article中所解释的那样,您可以在基类中使用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提供mysql-orm.xml,只需在使用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>

就是这样。