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