Hibernate Identity differences when moving from Oracle To Postgres - java

I am switching a Java application using Hibernate from Oracle to Postgres and encountering a issue with Id GeneratedValues.
The Domain objects have Ids configured like this:
#Id #GeneratedValue(strategy = GenerationType.AUTO) #Column(name = "id")
private Long id;
Under Oracle there was a sequence called "HIBERNATE_SEQUENCE" that provided this. I have created this sequence in Postgres like this:
CREATE SEQUENCE HIBERNATE_SEQUENCE MINVALUE 1 MAXVALUE 9223372036854775807 INCREMENT BY 1 START WITH 50000 CACHE 20 NO CYCLE ;
However, when persisting an object I'm getting an error of:
org.postgresql.util.PSQLException: ERROR: missing FROM-clause entry for table "hibernate_sequence"
I have tried:
switching the "GenerationType" to "SEQUENCE"
creating the sequence in lower case (hibernate_sequence)
But I get the same error in both cases.

You have to configure Hibernate to speak the PostgreSQL dialect of SQL.
In Oracle you get the next value of a sequence with a pseudo-column (hibernate_sequence.nextval), while in PostgreSQL you use a function (nextval(hibernate_sequence)). Using the Oracle syntax with PostgreSQL will cause the error you quote.

The main problem I had was not setting the hibernate.dialect property correctly.
It was
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
and changing it to
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL95Dialect"/>
fixed it and started using the correct sequence function as Laurenze Able pointed out

Related

Unique constraint violated - debug

We have an application which is working for years and we are using same oracle database too. But migrated our database from one host to another host.
DB: ORACLE
Now all of the sudden we are getting following exception,
“org.springframework.dao.DataIntegrityViolationException: ORA-00001: unique constraint (YYY.XXX_LOG_PK) violated;
SQL [n/a]; constraint [YYY.XXX_LOG_PK]; nested exception is org.hibernate.exception.ConstraintViolationException: ORA-00001: unique constraint (YYY.XXX_LOG_PK) violated”
code:
#SequenceGenerator(name = "TT_SEQUENCE_GENERATOR", sequenceName = "YYY.XXX_LOG_SEQ")
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TT_SEQUENCE_GENERATOR")
#Column(name = "ID")
public Long getId() {
return this.id;
}
Sequence in DB:
CREATED 07-NOV-17
LAST_DDL_TIME 07-NOV-17
SEQUENCE_OWNER TT
SEQUENCE_NAME YYY.XXX_LOG_SEQ
MIN_VALUE 1
MAX_VALUE 999999999999999999999999999
INCREMENT_BY 1
CYCLE_FLAG N
ORDER_FLAG N
CACHE_SIZE 0
LAST_NUMBER 75305
Problem:
When we are trying to insert some record through JPA code we are getting the above exception but when I try to insert some record into the DB using sequence.nextval, it is not giving any exception.
Is there anyway I can debug to find out what would be the exception ? I also tried show_sql - I couldn't able to find the solution with this too, as this doesn't print the next sequence number in the console
Please point me in right direction, if you know the solution.
The most common scenario in which a self-augmented sequence encounters a unique constraint conflict is when the data is migrated, causing the maximun value of the data to exceed the sequence value.
Firstly query the sequanence current values:
SELECT seqname.CURRVAL FROM dual
And then modify the sequence value to make sure the sequence's nextval exceeds the current maximum value of the data.
ALTER SEQUENCE seqname INCREMENT BY XXXXXX;
SELECT seqname.NEXTVAL FROM dual;
I found the solution for the problem which we faced.
The problem is from the database end. We found that by reviewing the migration documents and by checking the files.
#Edwin: Thanks for your help, your query also helped me in finding where is the problem residing.
While doing migration the sequences haven't copied from old server to new server. When we copied to new server, everything worked fine.
Thanks everyone.

ID jumping Issue With MSSQL and Hibernate

I have problem with MSSQL ID jumping feature.
My Requirement is like,I need to generate a sequence number say,starting from 1000 and increment one by one and my application is hosted in multiple servers and points to same DB.Multiple host are balanced with Nginx.
For this, wrote an Entity Class with SequenceGenerator
#Entity
#SequenceGenerator(name = "IdSequence",
sequenceName = " ID_GEN",
allocationSize = 1)
public class Example implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(generator = " IdSequence ")
private long id ;
}
And it works fine. When I restarted the DB, the next ID is jumped to current+1000
To resolve this I add a hibernate property, and its work fine against the ID jumping.
<property name="hibernate.id.new_generator_mappings" value="true"/>
The real problem now is already existing entities with Auto generation strategy has getting exception like
Cannot insert explicit value for identity column in table ‘USER' when
IDENTITY_INSERT is set to OFF.
Is there any way to resolve the ID jumping issue in JPA/Hibernate
How can I avoid the IDENTITY_INSERT is set to OFF if am going with
same fix.
Could you please suggest a better option to generate sequence number
that should be unique.
Thanks in advance
It sounds like what you're experiencing is this, rather than anything related to Hibernate.
In SQL Server Configuration Manager, right-click on your instance name on the right pane and click Properties then Startup Parameters
On the "specify a startup parameter" enter -T272 to set the 272 trace flag.
I get your confusion and frustration, but ultimately, you shouldn't really need to worry about what your next identity value will be.
There's also a closed Microsoft Connect post indicating that this is the way it is with some other possible workarounds.
in sql server, you may not insert a value for an identity column unless you specify SET IDENTITY_INSERT <yourTableName> ON before your insert statement.

Using UTF-8 query not working in hibernate

I have this user_model.java below:
public class User_Model implements Serializable {
#Id #GeneratedValue
private Long id;
#ColumnTransformer(
read="AES_DECRYPT(username, 'Hf7p4u6e') USING utf8))",
write="AES_ENCRYPT(?, 'Hf7p4u6e')")
The above code is working when I remove USING utf8) but when I put it again I get this error
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.USING user_mo0_.UTF-8).
I don't want to remove the utf8 because I used it for korean language.
I also put a utf8 setting in my hibernate.xml
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydb?UseUnicode=true&characterEncoding=utf8</property>
<property name="hibernate.connection.CharSet">utf8</property>
<property name="hibernate.connection.characterEncoding">utf8</property>
<property name="hibernate.connection.useUnicode">true</property>
But still, it's not work at all.How can I make my query work? any help
Two things:
Maybe you ned to use 'USING utf8' with CONVERT function (https://dev.mysql.com/doc/refman/5.0/en/charset-convert.html)
CONVERT(_latin1 AES_DECRYPT(username, 'Hf7p4u6e') USING utf8)
utf8 has nothing to do with your already created tables if they are not in UTF-8. This only forces newly created tables to use UTF-8. Existing tables remain as they are.

MySQL LONGTEXT with h2 embedded database

I am trying to make my application run on MySQL (for production) and H2 (for dev/testing). My (Flyway) script to create the tables is almost identical now, except for a column that needs to be declared 'LONGTEXT' for MySQL. If I also use this for H2 (which is running in MySQL compatibility mode), I get:
Wrong column type in public.public.customer_license for column license.
Found: clob, expected: varchar(65535)
The Java code of my entity:
#Column(name = "license", length = 65535)
private String m_license;
If I change the column declaration to VARCHAR(65535), then it works for H2, but not for MySQL:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Column length too big for column 'license'
(max = 21845); use BLOB or TEXT instead
How can I make it work for both?
I had the same problem. I solved it by using the #Lob Annotation. This validates ok with LONGTEXT in a mysql table. When using an H2 in-memory, a CLOB field is created.
import javax.persistence.Lob;
...
#Lob
private String lotsOfText;
That is one of the reasons there is orm.xml, so you can have one mapping for one datastore, and one for a different datastore, and hence no need to recompile the code between runs

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'sequence_next_hi_value' in 'field list

Anybody can tell what cause this error?
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
Unknown column 'sequence_next_hi_value' in 'field list
I am connecting to a mysql database using hibernate. I was able to connect to the database and everything was working fine till I change the persistence.xml and added a datasource.
The problem is related to the used identifier generation type for your entities.
Make sure you've provided following annotations and parameters:
#GeneratedValue(strategy = GenerationType.TABLE, generator="name_of_the_generator")
#TableGenerator( name = "name_of_the_generator", table = "table_with_keys", pkColumnName = "PK_NAME", valueColumnName = "PK_VALUE")
My guess is that you have mixed valueColumnName with pkColumnValue.
I have same problem , my solution is change GenerationType from #GeneratedValue strategy on Primary Keys to GenerationType.IDENTITY on hibernate 5 and MySQL as DB

Categories

Resources