How to change Hibernate GenerationType identifier depending on the underlying database

人走茶凉 提交于 2020-01-04 15:16:21

问题


I have a project called main_project (uses spring-boot v2) that contains all configuration classes including JPA configuration. The main_project also has entity classes (Like User, Personnel).

The JPA configuration for managed entity class in main_project is like below:

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

Other projects are using main_project as dependency for bootstrapping. Other projects that depends on main_project can use Personnel or User and ... entities and they can have different DBMS's like MySQL or Oracle.

When i used main_project as a dependency in project A , entity class of A project extends MainEntity<?> and creates it's own entity classes and have its own database configuration file.

my problem is on type of DBMS and GenerationType on id property in main_project.

  • 1) when A project uses Mysql database, MainEntity must have:

    @GeneratedValue(strategy = GenerationType.IDENTITY)

  • 2) when A project uses Oracle database, MainEntity must have:

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

How project A can detect its database type and switch between above approaches?

I think that i need reflected java util that in runtime and add some annotations based on databases type! is it right?

I also have read, this_post_19875993 but it didn't helped.

this_post_30731627 explained that we can select one of custom GenerationType but i want to select automatically without any changes to main_project, because A project can not change MainEntity class of main_project and just can used it.


回答1:


As I explained in this article, you could use the SEQUENCE identifier in your base class:

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

And override it for MySQL using the external mysql-orm.xml configuration file:

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

So, while for Oracle and PostgreSQL, you won't have to provide the mysql-orm.xml, for MySQL, just supply this file via the persistence.xml onfiguration file when you build the project using the mysql profile:

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

That's it.




回答2:


You can use orm.xml in project A to override the mapping configuration for the ID column according to the JPA specification:

An object/relational mapping XML file named orm.xml may be specified in the META-INF directory in the root of the persistence unit or in the META-INF directory of any jar file referenced by the persistence.xml.

Alternatively, or in addition, one or more mapping files may be referenced by the mapping-file elements of the persistence-unit element. These mapping files may be present anywhere on the class path.

— Section 8.2.1.6.2 of the JPA 2.1 Specification

See this and this for an example.



来源:https://stackoverflow.com/questions/50894094/how-to-change-hibernate-generationtype-identifier-depending-on-the-underlying-da

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!