How to escape reseved words from HQL - java

I have a table name Order and since it is a reserved word in Hibernate, it is not letting me to construct desired query. Is there any way by which I can escape table name in HQL?
I got across similar question asking for alias How to escape reserved words in Hibernate's HQL
But this solution is not working for me. Is there any other way by which we can do this? I am using version 4.3 of hibernate.

Have you mapped the table to an entity that is also called Order? If so then I'd suggest renaming the entity as there as the Hibernate team appear to have rejected the request to add keyword escaping to HQL. If the problem is actually with the generated SQL then you can add backticks to the table name to escape it according to the database dialect that is in use.

Related

Is it possible to create a table with the keyword "user"? [duplicate]

It seems PostgreSQL does not allow to create a database table named 'user'. But MySQL will allow to create such a table.
Is that because it is a key word? But Hibernate cannot identify any issue (even if we set the PostgreSQLDialect).
user is a reserved word and it's usually not a good idea use reserved words for identifiers (tables, columns).
If you insist on doing that you have to put the table name in double quotes:
create table "user" (...);
But then you always need to use double quotes when referencing the table. Additionally the table name is then case-sensitive. "user" is a different table name than "User".
If you want to save yourself a lot of trouble use a different name. users, user_account, ...
More details on quoted identifiers can be found in the manual: http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
It is possible to specify tablename with JPA with next syntax:
#Table(name="\"user\"")
We had this same issue time ago, and we just changed the table name from user to app_user. Due to the use of Hibernate/JPA. We thought it would be easier this way.
Hope this little fix will help someone else.
You can create a table user in a schema other than public.
The example:
CREATE SCHEMA my_schema;
CREATE TABLE my_schema.user(...);
Trailing underscore
The SQL standard explicitly promises to never use a trailing underscore in any keyword or reserved word.
So, to avoid conflicts with any of the over a thousand keywords and reserved words used by various database engines, I name all my database identifiers with a trailing underscore. (Yes, really, over a thousand keywords reserved — I counted them.)
Change this:
CREATE TABLE user ( … ) ;
… to this:
CREATE TABLE user_ ( … ) ;
I do this as a habit for all database names: schemas, tables, columns, indexes, etc.
As an extra benefit, this practice makes quite clear in documentation, email, and such when referring to a programming language variable named user versus the database column user_. Anything with a trailing underscore is obviously from the database side.

Usage of ? in native SQL query on jsonb

I need to fire a select query against Postgres jsonb column:
entityManager.createNativeQuery(
"select * from table where jsonbcol -> 'usernames' ? :un"
).setParameter("un", userName).getResultList()
Upon running the Exception is thrown:
org.hibernate.engine.query.ParameterRecognitionException: Mixed parameter strategies -
use just one of named, positional or JPA-ordinal strategy
I tried escaping like \\? and ?? but that didn't help.
How to do that call properly?
The proper escape sequence makes the query like this:
entityManager.createNativeQuery(
"select * from table where jsonbcol -> 'usernames' \\?\\? :un"
).setParameter("un", userName).getResultList()
The backslashes escape hibernate parameter detection, and the two question-marks are the JDBC escape.
There is an alternative solution that can turn out to be an elegant workaround. Postgres operator ? is based on the jsonb_exists() function, so instead of
where jsonbcol -> 'usernames' \\?\\? :un
you can use
where jsonb_exists(jsonbcol -> 'usernames', :un)
As the documentation says:
In JDBC, the question mark (?) is the placeholder for the positional parameters of a PreparedStatement. There are, however, a number of PostgreSQL operators that contain a question mark. To keep such question marks in a SQL statement from being interpreted as positional parameters, use two question marks (??) as escape sequence.

How to force Hibernate-Envers to use quotes around fields name?

I have a table with properties defined like this :
#Column(name="\"SERIAL#\"")
When Hibernate inserts data, everything works fine.
But it comes to Hibernate-Envers(HE), HE forgets to surround the field name with doublequotes.
How can i force it to use the doublequotes aroud the fields ?
Do you want to use double quotes, or do you want to escape the name? If you just want to escape, use backticks (`) and Hibernate will convert it to whatever mechanism your database uses for escaping. So, your example would be:
#Column(name="`SERIAL#`")
Just out of curiosity: why do you need a # in a column name? I always thought that special chars are a bad idea in identifiers :-)
For solving the problem, i manage to not use the '#' in the field name thus neither Hibernate nor Hibernate Envers have to escape the field name.
EDIT:
In fact it's a bug in Hibernate Envers 3.6.2.Final. It should be solved later.
EDIT 2:
The bug has been fixed in Hibernate Envers 3.6.3 and Hibernate Envers 4.0.0Alpha.
EDIT 3:
The bug has been fixed in Hibernate Core 3.6.4.Final.

Problems with escaping table and field names in Derby and Hsqldb

I'm having a problem with my ORMLite package. When I generate the schema for a table, I thought it would be a good practice to escape all entity names. This would protect some Java class or field name from being a SQL reserved word:
CREATE TABLE "footable" ("stuff" VARCHAR(255))
I'm now adding "raw" query support so that ORMLite can help users perform their own queries. However, I find that with Derby and Hsqldb, the entity names cannot be used without escaping. For example, the following query:
SELECT * FROM footable
generates the following errors:
Derby: ERROR 42X05: Table/View 'FOOTABLE' does not exist.
Hsqldb: Table not found in statement [select * from footable]
It works fine if the select table is also escaped as "footable". The other databases supported by ORMLite work fine with or without the escaping: MySQL, Postgres, Microsoft SQL Server, H2, and Sqlite.
Are there better ways to escape reserved words in Derby and Hsqldb? Other ideas about how to do this in a portable manner?
Thanks.
So kudos to Bryan for leading me down the path although his answer wasn't quite right.
Turns out that because I am creating the database as "footable" then, as Bryan states, it will be create case sensitively. However, when I did the select on footable (without quotes) Derby and Hsqldb are promoting it to be all uppercase so I'm in effect doing:
SELECT * FROM FOOTABLE
It's not about being case insensitive without the quotes (which would have worked) but about promoting the entity names to be all capitals when there are no quotes and then matching by case. I'd argue there was a bug here...
In any case, I've changed my Derby and Hsqldb to capitalize all entity names in ORMLite and things are working. Ugly IMO, but working.
You just have to make sure that the case matches.
So if it's:
create table "Footable" ("Stuff" varchar (25))
Then it has to be:
insert into "Footable" ("Stuff") values 'hi mom'
If the table/column name is in double quotes, the case is preserved as is.
If the table/column name is not in double quotes, then Derby handles it insensitive to case.

How to escape SQL keywords in JPAQL

I would like to have an entity named "GROUP" in my JPA setup. Now I get problems when I try to perform JPA queries, like "select count(group_.id) from Group group_".
JPA thinks this is a misplaced GROUP BY attempt and complains. Is there a way I can escape "Group", or do I have to rename my table?
Thx!
please don't do it!
rename your table to something else, you'll thank me in the long run. Don't use any reserved words for table or column names!
name it something like EmployeeGroup, JobGroup or ObjectGroup, etc...

Categories