Hibernate #Formula / ERROR: schema "FOO" does not exist - java

I'm updating old libraries from a legacy system. Just now i'm trying to update Hibernate 3.4.0.GA to 4.3.11.Final, i just needed to change small things in the code, everything was fine. But when i put the system to run, i'm receiving a "schema "FOO" does not exist" while execute a query. Trying to isolate the problem, i discovered this happen from Hibernate 3.5.1 to 3.5.2 and the reasons.
Hibernate when generating the sql, is adding schema to functions. I show now the difference in two versions.
protocolo_1 is the alias of main schema, this is a subquery added by #Formula in Protocolo.java, the name of schema is protocolo too.
#Formula
select max (pm2.id) from protocolo.protocolomovimento pm2 where pm2.id_protocolo = id
Hibernate 3.5.1 SQL generated
select max (pm2.id) from protocolo.protocolomovimento pm2 where pm2.id_protocolo = protocolo1_.id
Hibernate 3.5.2 SQL generated
select protocolo_1.max (pm2.id) from protocolo.protocolomovimento pm2 where pm2.id_protocolo = protocolo1_.id
I'm using PostgreSQL 9.4.12 with respective driver and org.hibernate.dialect.PostgreSQLDialect (in this versions of hibernate, it's the unique dialect to PostgreSQL)
I found another guy with similar problem here Why is Hibernate adding schema name to Hsql functions? but i think its only similar, it's not my case.
Why is Hibernate doing this? How can i fix this?

Looks like hibernate don't understand space character between max and ( in expression max (pm2.id), so it thinks that max is column name and adds table alias there.
Removing space will solve the problem.

Related

org.hibernate.loader.custom.NonUniqueDiscoveredSqlAliasException: Encountered a duplicated sql alias [] during auto-discovery of a native-sql query

I am upgrading my application from Hibernate 3 to Hibernate 4. In some of the queries I am returning empty string "" in select statement without any alias.
This works fine with Hibernate 3. When I upgrade it to Hibernate 4, then I get the exception:
org.hibernate.loader.custom.NonUniqueDiscoveredSqlAliasException: Encountered a duplicated sql alias [] during auto-discovery of a native-sql query
If I give aliases to them then it works fine, but I have to change it across many places, which is tedious job. Please let me know if there is any other way to resolve it?
I know we should have unique aliases for all the select attributes, but in my case application is very vast, and can't change it manually

Oracle NUMBER(precision,scale) in HSQLDB

In a unit test I am trying to generate a table in an in-mem HSQLDB, the table contains a column with the definition: #Column(name = "xxx", columnDefinition="NUMBER(10,0) default 0"). NUMBER is not recognized by HSQLDB (version 2.3.3), so I have added a script running this statement first: CREATE TYPE NUMBER AS NUMERIC;. Now it seems to recognize NUMBER, but I get the error unexpected token: ( instead. I cannot edit the column definition, so wow do I correctly map Oracle NUMBER(10,0) to NUMERIC? If I remove the precision and scale from NUMBER it seems to work.
You do not need to define the NUMBER type, as it is supported by HSQLDB.
HSQLDB supports Oracle syntax in one of its compatibility modes. Run this statement to enable it:
SET DATABASE SQL SYNTAX ORA TRUE

Liquibase + H2 + Junit Primary Key Sequence starts over

I managed to integrate Liquibase into our Maven build to initialize a H2 inmemory database with a few enrys. Those rows have the primary key generated using a sequence table which works as expected (BigInt incremented values starting from 1).
My issue is that when i try to persist a new entity into that table from within a Junit integration test i get a "unique key constraint violation" because that new entity has the same primary key as the very first row inserted using the Liquibase changelog-xmls.
So the initialisation works perfectly fine as expected. The maven build uses the liquibase changelog-xmls
For now i just wipe the according tables completly before any integration tests with an own Runner... but that wont be a possibility in the furture. Its currently quite a chalange to investigate such issues since there is not yet much specific information on Liquibase available.
Update Workaround
While id prefer below answer using H2 brings up the problem that below changeset wont work because the required minValue is not supported.
<changeSet author="liquibase-docs" id="alterSequence-example">
<alterSequence
incrementBy="1"
maxValue="371717"
minValue="40"
ordered="true"
schemaName="public"
sequenceName="seq_id"/>
As a simple workaround i now just drop the existing sequence that was used to insert my testdata in a second changeSet:
<changeSet id="2" author="Me">
<dropSequence
sequenceName="SEQ_KEY_MY_TBL"/>
<createSequence
sequenceName="SEQ_KEY_MY_TBL"
incrementBy="1"
startValue="40"/>
</changeSet>
This way the values configured in the changelog-*.xml will be inserted using the sequence with an initial value of 1. I insert 30 rows so Keys 1-30 are used. After that the sequence gets dropped and recreated with a higher startValue. This way when persisting entities from within a Junit based integration Test the new entities will have primary keys starting from 40 and the previous unique constraint problem is solved.
Not H2 will probably soon release a version supporting minValue/maxValue since the according patch already exists.
Update:
Maybe we should mention this still is just a Workaround, anyone knows if H2 supports a Sequence with Liquibase that wont start over after DB-Init?
You should instruct liquibase to set the start value for those sequences to a value beyond those you have used for the entries you created. Liquibase has an alterSequence element for this. You can add such elements at the end of your current liquibase script.

Why is Hibernate generating this SQL query?

I'm using Hibernate and a MySql server. I use multiple databases as "namespaces" (e.g. users, transactions, logging etc.).
So, I configued Hibernate to NOT connect to a particular database :
url = jdbc:mysql://127.0.0.1/
The databases where tables are located are defined in the hbm files through the catalog attribute :
<class name="com.myApp.entities.User" table="user" schema="" catalog="users"> ...
When I want to load some data, everything works fine and Hibernate seems to generate the expected SQL queries (by using the catalog prefix in the table names) e.g. :
select id from users.user
However, when I try to add a new record, Hibernate don't use the from [catalog].[table_name] syntax anymore. So I get a MySQL error 'No database selected'.
select max(id) from user
Hibernate is trying the get the future id to create a new record, but it doesn't specify in which database is located the table, it should be :
select max(id) from users.user
Why is Hibernate generating this invalid query ? Have someone ever experienced this problem ?
You need to specify the schema for the generator. See this question on SO for a more detailed answer.

Removing quotes in openjpa generated sql for sybase

I need to be able to refer to a table on a different schema, using OpenJPA to access a Sybase db.
So, for example, I need to select as follows:
SELECT name FROM SHARE.dbo.PROVINCE;
However, the generated SQL is:
SELECT name FROM "SHARE.dbo".PROVINCE;
which Sybase rejects. Without the quotes it works fine.
I'm using the following annotations on the class:
#Entity
#Table(name="PROVINCE", schema="SHARE.dbo")
using schema="SHARE" doesn't work, although it generates the sql without any quotes. (Sybase requires schema.owner.table, so SCHEMA.PROVINCES is an unknown object)
Any thoughts on how to resolve this issue?
Try concatenating the schema to the table name: #Table(name="SHARE.dbo.PROVINCE")
This is a bit of a shot in the dark, but you could try to disable delimited identifier support?
openjpa.DBDictionary=sybase(SupportsDelimitedIdentifiers=false)

Categories