如何根据底层数据库更改 Hibernate GenerationType 标识符
How to change Hibernate GenerationType identifier depending on the underlying database
我有一个名为 main_project 的项目(使用 spring-boot v2),其中包含所有配置 classes,包括 JPA 配置。 main_project 也有实体 classes(如用户、人员)。
管理实体class在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.
当我在项目 A 中使用 main_project 作为依赖项时,[=44 的实体 class =]A 项目 extends MainEntity<?>
并创建自己的实体 classes 并拥有自己的数据库配置文件。
我的问题是关于 DBMS 的类型和 GenerationType 在 id 属性 in main_project.
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 在运行时使用它并根据数据库类型添加一些注释!对吗?
我也读过,this_post_19875993但没有帮助。
解释说我们可以 select 自定义 GenerationType 之一,但我想 select 自动 select 而无需对 [=44 进行任何更改=]main_project,因为A工程不能改MainEntityclass of main_project刚好可以用
您可以在项目A中使用orm.xml
根据JPA specification覆盖ID列的映射配置:
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
有关示例,请参阅 this and this。
您可以在您的基础中使用 SEQUENCE
标识符 class:
@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,只需在构建时通过 persistence.xml
配置文件提供此文件使用 mysql 配置文件的项目:
<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>
就是这样。
我有一个名为 main_project 的项目(使用 spring-boot v2),其中包含所有配置 classes,包括 JPA 配置。 main_project 也有实体 classes(如用户、人员)。
管理实体class在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.
当我在项目 A 中使用 main_project 作为依赖项时,[=44 的实体 class =]A 项目 extends MainEntity<?>
并创建自己的实体 classes 并拥有自己的数据库配置文件。
我的问题是关于 DBMS 的类型和 GenerationType 在 id 属性 in main_project.
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 在运行时使用它并根据数据库类型添加一些注释!对吗?
我也读过,this_post_19875993但没有帮助。
您可以在项目A中使用orm.xml
根据JPA specification覆盖ID列的映射配置:
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
有关示例,请参阅 this and this。
您可以在您的基础中使用 SEQUENCE
标识符 class:
@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,只需在构建时通过 persistence.xml
配置文件提供此文件使用 mysql 配置文件的项目:
<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>
就是这样。