I have a java spring boot project which needs to be run on both MySQL and Oracle databases. The project has multiple entities with primary keys set to auto-increment in the db.
I have identified that Hibernate's #GenericGenerator in native strategy will support both MySQL (as IDENTITY) and Oracle (as SEQUENCE) in terms of auto-increment depending on the type of db. But I can't seem to find how to set the allocationSize in the GenericGenerator, for an oracle sequence. I want the allocationSize to be set to 1.
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator="gen")
#GenericGenerator(name = "gen", strategy = "native")
#Column(name = "id", nullable = false)
private Long id;
//Getter and Setter
#GenericGenerator is a hibernate annotation used to denote a custom generator, which can be a class or shortcut to a generator supplied by Hibernate. increment is a shortcut to a Hibernate generator.
check this link below: - Hibernate, #SequenceGenerator and allocationSize
Related
We have a Java program using Hibernate 5 that can be installed using different DB Engines: Oracle, PostgreSQL or SQL Server. Now we are introducing MySql.
The entities have a Generated Value AUTO identifier.
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
This worked fine until now. Oracle and PostgreSQL installations are using HIBERNATE_SEQUENCE sequence to generate the id values and SQL Server is using a table generated id (IDENTITY).
With MySQL we would like to use also the table generated id, but Hibernate 5 GenerationType.AUTO on MySQL tries the TABLE generator instead of the IDENTITY generator.
I found this solution by Vlad Mihalcea where using a native generator makes Hibernate to select IDENTITY for MySQL:
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
#GenericGenerator(name = "native", strategy = "native")
protected Long id;
That's nice for MySQL, but then the application is no longer working in Oracle (ORA-02289: sequence does not exist). I think Hibernate is then searching for a sequence called native in the Oracle DB.
Is there a solution to keep the ID generation the same for all the other DB engines (Oracle, PostgreSQL and SQL Server) and use the IDENTITY for MySQL?
If not the only solution I can see is to implement the TABLE ID generation in MySQL, but it seems not to have a good performance.
I almost had it in the question, but in case somebody falls in the same situation: calling the generator HIBERNATE_SEQUENCE will make it backwards compatible with Oracle and PostgreSQL (SQL Server will continue using IDENTITY).
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "HIBERNATE_SEQUENCE")
#GenericGenerator(name = "HIBERNATE_SEQUENCE", strategy = "native")
protected Long id;
Hey this question/answer got me on the road to the answer. I am using Hibernate core 5.4.30 with MSSQL SQLServer2012Dialect and Oracle Oracle12cDialect. I needed to use the #GenericGenerator annotation as well for it's native strategy. maybe I could have used this directly with #GeneratedValue? anyway...
I found Oracle did not come with a sequence named HIBERNATE_SEQUENCE, and even when I added one, hibernate was still giving me sequence not found errors, seemingly having to do with my schema... So you can make things more specific like this:
#Id
#GenericGenerator(name = "MY_SEQUENCE", strategy = "native",
parameters = {
#org.hibernate.annotations.Parameter(name = "schema", value="MY_SCHEMA"),
#org.hibernate.annotations.Parameter(name = "sequence_name", value="MY_SEQUENCE")
}
)
#GeneratedValue(generator = "MY_SEQUENCE")
private Long id;
Hypothetically the name of the #GenericGenerator only has to match the generator name in the #GeneratedValue, but I made it the same as my actual database sequence for simplicity.
I'm trying to use a defined sequence generation in Oracle JPA, along with GenerationType.AUTO like this:
#Id
#SequenceGenerator(name = "MY_GEN_NAME", sequenceName = "MY_SQ_NAME")
#GeneratedValue(strategy = GenerationType.AUTO, generator = "MY_GEN_NAME")
#Column(name = "ID", nullable = false)
private Long id;
After running the hibernate validation it throws an error:
Schema validation: missing sequence [hibernate_sequence]
I guess, it is ignoring my MY_GEN_NAME and trying to use that global sequence for id generation.
When I switch to GenerationType.SEQUENCE, it uses SequenceHiLoGenerator and it works fine.
Why is that happening, and is it possible to make the GenerationType.AUTO work with given sequence for Oracle (possibility to switch to other db)?
AUTO says to the JPA provider, "choose what you want", and it will not use the "generator" attribute in that case.
If you want to use a SEQUENCE then set the strategy to SEQUENCE! That way it will use the sequence definition you have defined
Though hibernate-sequence-on-oracle-generatedvaluestrategy-generationtype-auto suggests that this will work, it appears that it is broken for some versions of Hibernate, see HHH-10656.
Edit: Broken in 5.2.0, unbroken in 5.2.8.
I am using JPA 2.1 with Hibernate 4.3.8. on Oracle, MySQL, PostgreSQL and MS SQL. For creating numeric primary keys I have used the following code :
#Id
#Column(name = "ID")
#GeneratedValue(strategy = GenerationType.AUTO, generator = "t_gen")
#SequenceGenerator(name = "t_gen", sequenceName = "T_SEQ")
private long id;
So far so good. But I need to generate only positive values of IDs under all conditions. How can I force Hibernate to generate only positive ID's on each database (MS SQL, MySQL, PostgreSQL, Oracle) ?
Hope this helps;
If allocationSize is not declared on the entity side, as default allocation size is 50 ALL sequences MUST declare INCREMENT BY 50 on the DB side.
Reference Link:
http://skay-dev.blogspot.in/2013/09/hibernate-sequence-and-negative.html
we are currently migrating from MSSQL to Oracle and we dont want to use the hibernate_sequence for all tables. Each table should have its own Sequence.
We already did the change in our testenvironment but I'd like to get some additional info if our solution is safe to use..
Most of our classes are extending from baseentities but we also have a couple of stand-alone entities.
What we changed:
-baseentities(#MappedSuperclass):
changed: #GeneratedValue(strategy = GenerationType.AUTO)
to: #GeneratedValue(strategy = GenerationType.AUTO, generator = "HIBERNATE_GENERATOR")
-extending entities:
added after the #Table annotation:
#SequenceGenerator(name = "HIBERNATE_GENERATOR", sequenceName = "${TABLENAME}_SEQ")
-stand-alone entities:
added after the #Table annotation:
#SequenceGenerator(name = "HIBERNATE_GENERATOR", sequenceName = "${TABLENAME}_SEQ")
changed : #GeneratedValue(strategy = GenerationType.AUTO)
to: #GeneratedValue(strategy = GenerationType.AUTO, generator = "HIBERNATE_GENERATOR")
So we are using always the same generatorname "HIBERNATE_GENERATOR", only the sequenceNames are different.
Our applications seems to work fine, but is it safe to use always the same generatorname?
No, it's not safe. My guess is that all your generated values are generated by the same sequence. Indeed, the javadoc says:
Defines a primary key generator that may be referenced by name when a generator element is specified for the GeneratedValue annotation. A sequence generator may be specified on the entity class or on the primary key field or property. The scope of the generator name is global to the persistence unit (across all generator types).
(emphasis mine)
Each entity should define its own generator.
I have an entity which has an ID field:
#Id
#Column(name = "`U##ID_VOIE`")
#GeneratedValue(generator = "VOIE_SEQ")
private String id;
The class has the sequence generator defined as well:
#SequenceGenerator(name = "VOIE_SEQ", sequenceName = "VOIE_SEQ")
and the Oracle schema has the requisite sequence present. Everything works okay.
We also have tests, which uses an in-memory HSQLDB. Before running the tests, all the tables are created based on the Hibernate entity classes.
However the table for this particular class is not being created. And error pops up, because ID is a String and the SequenceGenerator in HSQLDB returns an INT / LONG / Numeric value.
The application is using a legacy Oracle database and ID_VOIE column must remain a String / Varchar.
Any solutions?
Using H2 instead.