I'm trying to annotate ID generators in Hibernate for an Oracle DB,
I've tried this so far:
a) #GeneratedValue(strategy=GenerationType.AUTO)
says id cannot be null when I try to persist the table
b) #GeneratedValue(strategy=GenerationType.SEQUENCE)
says Oracle doesn't support sequences (or something like that)
c) #GeneratedValue(strategy=GenerationType.IDENTITY)
says id cannot be null when I try to persist the table.
How should I annotate ID generators in Hibernate for an Oracle DB?
You can add generation strategy as Sequence and add sequence generator to your entity:
#SequenceGenerator(name = "GEN_TABLE_NAME", sequenceName = "SEQ_TABLE_NAME")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "GEN_TABLE_NAME")
private Long id;
If you are not using hbm2dll.auto settings, you need to create sequence in your oracle database and specify it's name to "sequenceName" property.
Related
I'm stuck in some problem: I need to use sequences in PostgreSQL for generating ids. But when I save new object in table, it says that id is null
org.postgresql.util.PSQLException: ERROR: null value in column "id" violates not-null constraint
I use these annotations:
#SequenceGenerator(name = "fooGen", sequenceName = "FOO_SEQ", allocationSize = 1)
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "fooGen")
#Column(columnDefinition = "numeric")
private BigInteger id;
And this worked fo Oracle. I've watched a lot of questions, but most used GenerationType.AUTO or GenerationType.IDENTITY, and solution was to use GenerationType.SEQUENCE. But I'm already using it.
I got this exception when trying to save my entity with repository method
fooRepository.saveAndFlush(entity);
My database is PostgreSQL 9.6.1.
I use
org.hibernate.dialect.PostgreSQL9Dialect
Sequence exists, I checked it. And hibernate.hbm2ddl.auto=validate would give me exception if it wouldn't be there.
Please, help me, where did I make a mistake?
I am using database schema:
<prop key="hibernate.default_schema">${jdbc.postgresql.schema}</prop>
maybe, this cause some problems?
Thanks in advance
Try to change type for id to Long like
#SequenceGenerator(name = "fooGen", sequenceName = "FOO_SEQ", allocationSize = 1)
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "fooGen")
#Column(columnDefinition = "numeric")
private Long id;
This table has many-to-many relation, and table that connected two entities has its own id field. Hibernate had no mapped Java class for this table, and didn't set this id. And solution was to remove this field.
I saw this post (JPA Entity Lifecycle Events vs database trigger), but it didn't ask quite as explicitly as I am here:
Am I required to have a sequence AND a trigger for when I insert a row with a PK with a value of (null)?
Or will JPA somehow interpret the sequence annotations as a signal to grab .nextVal?
If you define a sequence on your primary key (#Id annotated field) and you map the sequence using the annotations #GeneratedValue and #SequenceGenerator, you can persist an entity with a null primary key. JPA will automatically call the sequence to get the next value (or get it from its cache).
The primary key declaration should look like.
#Id
#Column(name = "TABLE_PK")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQUENCE_GENERATOR_NAME")
#SequenceGenerator(name = "SEQUENCE_GENERATOR", sequenceName = "SEQUENCE_NAME")
private Integer id;
I have a table with id like below, but hibernate uses org.hibernate.id.SequenceGenerator instead of SequenceHiLoGenerator for GenerationType.AUTO, how can I tell hibernate to use SequenceHiLoGenerator?
#Id
#SequenceGenerator(name="admin_seq", sequenceName="unique_id")
#GeneratedValue(strategy=GenerationType.AUTO, generator="admin_seq")
private Long id
If I use GenerationType.SEQUENCE, hibernate will use SequenceHiLoGenerator, but I need to use GenerationType.AUTO for compatibility with MySQL.
I have tried using #GenericGenerator, it works for Oracle but will be complained by MySQL: org.hibernate.dialect.MySQLDialect does not support sequences.
#GenericGenerator(name = "admin_seq", strategy = "org.hibernate.id.SequenceHiLoGenerator",
parameters = {
#Parameter(name = "sequence", value = "unique_id"),
#Parameter(name = "max_lo", value = "50") })
#GeneratedValue(strategy=GenerationType.AUTO, generator="admin_seq")
private Long id
I also tried using SequenceStyleGenerator by setting hibernate.id.new_generator_mappings=true in hibernate properties. It doesn't work either.
If you set hibernate.id.new_generator_mappings=true which uses SequenceStyleGenerator, it would work with Oracle. We have similar configuration in our project which works fine.
If you want to achieve bulk id retrieval(like 50 each time) to speed up the persist/save, the quirk here is you need to set allocationSize to 50 and also set your sequence Increment By to 50. 50 here is just a random number I choose, if you have massive persist, you can assign larger number. The most important thing here is the allocationSize in code and the Increment By in Database should MATCH.
The Oracle sql is something like
ALTER SEQUENCE YOUR_SEQUENCE_NAE INCREMENT BY 50;
The JPA entity ID field is like:
#SequenceGenerator(name = "YOUR_ID_GEN", sequenceName = "SEQ_YOUR_ID", allocationSize=50)
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "YOUR_ID_GEN")
#Column(name = "YOUR_ID")
public Long getYourId() {
return this.yourId;
}
strategy = GenerationType.AUTO should work against MySQL with an identity column even though you've configured a sequence too. The sequencegenerator will be used when running against Oracle, but ignored when running against MySQL.
In your persistence.xml you should also switch your hibernate.dialect property between the correct values for a Oracle dialect and a MySQL dialect.
In my project we are using Oracle and we want to give support for MYSQL also. Oracle have sequence support but MYSQL don't have. which GenerationType is good if we want to support ORACLE and MYSQL with same code base using Hibernate persistence provider among AUTO,IDENTITY & TABLE(or Any other way)?, can any one give brief description about these please?
Ex:
Class POJO{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
------
#GeneratedValue(strategy = GenerationType.IDENTITY)
-----
#GeneratedValue(strategy = GenerationType.TABLE)
------
(or Any other best approch?)
}
You can use
#GeneratedValue(generator = GenerationType.TABLE)
It will work for both Oracle and mySql
Since MySQL supports auto_increment use GenerationType.AUTO for its corresponding POJOs.
For the POJOs for Oracle database you could create a sequence for each and use it in your POJOs as illustrated below.
Sequence creation
CREATE SEQUENCE MY_SEQ
INCREMENT BY 1
START WITH 1
NOMAXVALUE
NOCYCLE
NOCACHE;
Generation type
I suppose the primary key is labeled ID in your Oracle table.
#Id
#GeneratedValue(generator = "mySeq")
#SequenceGenerator(name = "mySeq", sequenceName = "MY_SEQ", allocationSize = 1)
#Basic(optional = false)
#NotNull
#Column(name = "ID")
private Long id;
You may want to look into configuring all the database-dependant stuff in an xml configuration file. I haven't used xml files to configure hibernate for years and I've never mixed it with annotations. But the way I understand it: Your xml configuration will overwrite this specific configuration from your annotations in your POJO.
So you could leave your POJO with your oracle-specific ID Generator, and in case you deploy it for a MySQL, you would need to add an xml configuration with your MySQL-specific ID Generators.
I can't give you any details on this though. sorry.
I'm using hibernate with a MySQL database in my spring MVC project. I have used the #GeneratedValue annotation to set auto-incremenet on my id fields. So all my entities have this piece of code and everything is working as expected:
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
At this time, I want to switch to an Oracle database. Now, I have two questions here:
1. What's the best solution to set auto-increment field in oracle? I used this code, but is not working:
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "id_Sequence")
#SequenceGenerator(name="id_Sequence", allocationSize=1)
2(More important question). Is there any way to use a unique annotation to set auto-increment that will work for both MySQL and Oracle?
1:
If you define your own generator, your have to use the generator attribute in #GeneratedValue. And if you have created your own sequence you have to define the name with sequenceName otherwise hibernate will create one for you.
#SequenceGenerator(name="some_gen", sequenceName="Emp_Seq")
#GeneratedValue(generator="some_gen")
2:
The most flexible (and portable) way is to use the TABLE strategy
#GeneratedValue(strategy=GenerationType.TABLE)
or more explicit
#GeneratedValue(generator="some_gen")
#TableGenerator(name="some_gen",
table="ID_GEN",
pkColumnName="GEN_NAME",
valueColumnName="GEN_VAL")
This will generate (if schema generation is enabled) a table ID_GEN with the columns GEN_NAME, GEN_VALUE, if schema generation is not available you have to create this table on your own.
You find more complete information from hibernate docs here: http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch05.html#mapping-declaration-id-generator