Intellij IDEA jpa console issue select from tables with specific columns - java

We have a project includes Eclipselink and MySQL.
For example if we use simple query:
SELECT a from ExampleTable a
it is transformed to something like this:
SELECT `id`, `code`, `high`, `key`, `name`, `regionalCode` FROM `ExampleTable`
and if I am using JPA Console I am getting something like that:
SELECT id, code, high, key, name, regionalCode FROM ExampleTable
and error message
[42000][1064] 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 'key, name, regionalCode FROM ExampleTable' at line 1
The problem is "key" column but I have no chance to rename it.
I tried to find options to fix that but have no results.
I think if there will be no answer - the good way is to create bug report.
How we get enclosed names of columns?
We are using EntityManager
EntityManager em;
...
TypedQuery = em.createQuery("SELECT et FROM ExampleTable et");
And if we run it we see (in debug mode) that all names in generated query are enclosed with ` symbol.

key is reserved keyword of MySQL database (see MySQL: Reserved Words).
so you should escape reserved keyword in your mapping.
You can do it in the following way:
#Table
#Entity
public class ExampleTable implement Serializable
{
// ...
#Column(name = "'key'") // or #Column(name = "\"key\"")
private String key;
//...
}

Related

how to map boolean fields in model class through hibernate annotations

how to add boolean fields in java model class through hibernate annotations.
I am doing this and its shows me 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 'Like bit' at line 2
My code:
#Column(name="Like")
private boolean like;
#Column(name="Dislike")
private boolean dislike;
#Column(name="Flag")
private boolean flag;
In fact your problem is that you used Like as a column name in your entity, so Hibernate will try to map this column to the name Like while it's a reserved keyword in SQL, that's why you got the exception:
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 'Like bit' at line 2
What you can do here is either to use a different name of the column or escape the name.
For further details and escaping solutions you can check:
Hibernate Tips: How to escape table and column names article.
Creating field with reserved word name with JPA

Calculating age from birthdate with #Formula

I'm trying to calculate the user's age from her birthdate, using #Formula.
According MySQL documentation, I have tried this:
#Entity
#Table(name = "users")
public final class UserProfile {
//this column is called BIRTHDATE in database
private String birthdate;
#Formula("(select TIMESTAMPDIFF(YEAR,BIRTHDATE,CURDATE()) from users)")
private String age;
//more things...
}
But I get an error:
java.sql.SQLSyntaxErrorException: You have an error in your SQL
syntax; check the manual that corresponds to your MariaDB server
version for the right syntax to use near
'userprofil0_.YEAR,userprofil0_.BIRTHDATE,CURDATE()) from users) as
formula0_0_ f' at line 1
If I execute that query in phpMyAdmin, it works properly.
Following this, I have also tried with:
#Formula("date_part('year', age(birthdate))")
private String age; //I tried with int instead of String, too
But I have this error:
java.sql.SQLSyntaxErrorException: FUNCTION
userprofile-service-db.date_part does not exist
This one does not work even in phpMyAdmin...
Any idea?
EDIT
I have just tried with:
#Formula("(TIMESTAMPDIFF(YEAR,BIRTHDATE,CURDATE()))")
private String age;
but is still not working. This is the query that Hibernate shows:
select
userprofil0_.id as id1_1_0_,
userprofil0_.about_me as about_me2_1_0_,
userprofil0_.birthdate as birthdat3_1_0_,
userprofil0_.display_name as display_4_1_0_,
userprofil0_.email as email5_1_0_,
userprofil0_.profile_photo as profile_6_1_0_,
(TIMESTAMPDIFF(userprofil0_.YEAR,
userprofil0_.BIRTHDATE,
CURDATE())) as formula0_0_
from
users userprofil0_
where
userprofil0_.id=?
It looks like Hibernate is taking YEAR as a column, but actually it is a reserved word. If I execute that query in phpMyAdmin replacing userprofil0_.YEAR with just YEAR, it works fine.
Your first attempt was almost right, but you don't need select and from parts since column BITHDATE is in the same table:
#Formula("(TIMESTAMPDIFF(YEAR,BIRTHDATE,CURDATE()))")
private String age;
Also would be useful to turn on the logging of generated SQL query (in Hibernate it's done by setting property show_sql to true), to see the whole query.
UPDATE
As a workaround of the treating YEAR as a column name by Hibernate you can wrap call to TIMESTAMPDIFF in a custom MySQL function and call this function in Formula. Here is the SO answer to a similar problem.
Another solution could be to write a custom dialect resolver, which will treat YEAR as a keyword: SO answer
Try this formula to calculate the difference between current date and BIRTHDATE column stored in the database to get user age in year
#Formula("YEAR(CURDATE()) - YEAR(BIRTHDATE)")
private int age;

Hibernate append table alias in query.

I have this in my user.java:
#Entity
#Table(name="users")
public class Users_Model implements Serializable{
#Id #GeneratedValue
private Long id;
#ColumnTransformer(
read="AES_DECRYPT(userName, 'Hf7p4u6e')",
write="AES_ENCRYPT(?, 'Hf7p4u6e')")
}
I used aes_decrypt to retrieve the values in my database which is encrypted. My problem is it's only decrypt the english characters but not the japanese or chinese characters. The output I get is :Hello ���������� it should be: Hello 한국어/조선말.
I tried to display the query and this is what I got:
select message_mo0_.id as id0_, CONVERT(AES_DECRYPT(message_mo0_.createdBy, 'Hf7p4u6e') message_mo0_.USING message_mo0_.utf8) as userName_, from users message_mo0_
As you can see it appends the table alias in my query in using utf8 so everytime I get error sql syntax correct. My question is there a way to tell the hibernate not to append table alias. I would like to generate a query which looks like this to where the using utf8 is no appended table alias:
select message_mo0_.id as id0_, CONVERT(AES_DECRYPT(message_mo0_.createdBy, 'Hf7p4u6e') USING utf8) as userName_, from users message_mo0_
I've been stuck here for almost 4 days. Please help. Thank you in advance

How to select from an Oracle 11g table called User using HQL

In Oracle, if you name a table User, you must query the table by putting quotes around the word user.
This will not work
select * from User
This will work
select * from "User"
My question is, how do I run a hibernate HQL query on a table named User? I have tried putting "" around User, escaping quotes, single quotes, nothing works. HQL doesn't like those characters and errors out. I have googled and searched for a solution and found nothing.
You need to escape the table name, in your entity mapping:
#Entity
#Table(name="`User`")
public class User {
...
}
The when you write an HQL query like this:
from User
Hibernate will generate an SQL query like this:
select * from "User"

Hibernate generates invalid SQL query with MySQL

I have the following JPA entity classes (example case). A House belongs on a single Street. A Street has many Houses.
#Entity
public class House {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
public Integer id;
public String name
#ManyToOne
public Street street;
}
#Entity
public class Street {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
public Integer id;
#OneToMany(mappedBy="street")
public Set<House> houses;
}
I have the generation type set to identity, which is supposed to auto assign a new ID.
When creating a new House with a new Street, I have to first create and persist Street, followed by House. This is because I do not have CascadeType set to PERSIST, so it has to be done manually [1]. However, while inserting a newly created Street:
Street street = new Street();
entityManager.persist(street);
Hibernate/JPA generates the following SQL query:
insert into Street default values
which MySQL doesn't like.
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 'default values' at line 1
Any ideas why? I'm using Java 6, MySQL 5.0.67 with Hibernate's implementation of JPA (version 3.2.1.ga).
[1] EJB 3 in Action pages 318-319
If you don't have an error in your SQL statement, then you might want to check your table column name as it can contain a predefined name that Mysql uses; for example 'column' which can't be used as a table column name
Standard SQL specifies this optional syntax for INSERT:
INSERT INTO <Table Name> DEFAULT VALUES
This is legal SQL syntax, supported, for example, by Microsoft SQL Server, PostgreSQL, and SQLite, but not by Oracle, IBM DB2, or MySQL.
MySQL supports other syntax that achieve the same result:
INSERT INTO <Table Name> () VALUES ()
INSERT INTO <Table Name> (col1, col2, col3) VALUES (DEFAULT, DEFAULT, DEFAULT)
In Hibernate, you should configure the SQL dialect properly, and it's up to Hibernate to generate valid SQL for the target RDBMS brand.
import org.hibernate.cfg.Configuration;
Configuration cfg = new Configuration();
cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect");
You can also specify properties by placing a file named hibernate.properties in a root directory of the classpath.
Another situation when you might have this exception is when you have reserved words as columns for the table. For example 'to' and 'from' are not suitable clumn names for MySQL. It is obviously bug in Hibernate, that it doesn't check such columns and moreover continues to work with no error even if table is not created.
Make sure spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialecthas correct version of MySQL

Categories

Resources