In my application there is an entity:
#Entity
#Table(schema = "hr", name = "personal_data")
public class PersonalData {
}
and connection string defined in Spring's application.properties:
spring.datasource.url=jdbc:mysql://localhost/mobile?UseUnicode=true&characterEncoding=utf8
If I invoke the following code:
TypedQuery<E> typedQuery = em.createQuery("from PersonalData pd where pd.employeeId = ?1", PersonalData.class);
typedQuery.setParameter(1, 123);
return typedQuery.getSingleResult();
it will result in this SQL:
select * from personal_data personalda0_ where personalda0_.employee_id=?
Which will fail with the exception
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'mobile.personal_data' doesn't exist
because the table personal_data is defined in the hr database and there is no such table in mobile.
This was working fine(i.e. table name in SQL was prefixed with database name) in Hibernate 4.3.13 and stopped when the application was migrated to Spring Boot 2.0 which uses Hibernate 5.2.14. Is there any way to achieve the old behaviour in Hibernate 5.x?
I can say that there is a misunderstanding between Hibernate 5 and MySQL, a long story here Hibernate 5.0.6 Ignores schema in MySQL
One Solution is proposed is to use the name of schema in the place of catalog so instead of :
#Table(schema = "hr", name = "personal_data")
^^^^^^
You can use :
#Table(catalog = "hr", name = "personal_data")
^^^^^^^
Also take a look at this :
5.0 Migration Guide
Related
I have a project to do integration with snowflake database using ORM like JPA/Hibernate
but for the resultset from snowflakes always returns fields in UPPERCASE which conflicts with JPQL default behevior.
Example below is a select query using JPQL as you can see all fields are in lowercase
select podioitem0_.ID as id1_0_0_, podioitem0_.JSON as json2_0_0_ from INLIFE_MARK.PUBLIC.podio_item podioitem0_ where podioitem0_.ID=?
The Resultset from snowflake returns Uppercase columns
Given the samples above I get this error
o.h.engine.jdbc.spi.SqlExceptionHelper : Column not found: json2_0_0_
Its because when trying to map json2_0_0_ column from resultset the mapper cant find it because the columns from resultset are on uppercase.
So Question, is there a way to tell JPQL or jpa/hibernate to generate the JPQL query in Uppercase? at least for the column names so I hope it would look like this?
select podioitem0_.ID as ID1_0_0_, podioitem0_.JSON as JSON2_0_0_ from INLIFE_MARK.PUBLIC.podio_item podioitem0_ where podioitem0_.ID=?
Additional details below
properties
spring.jpa.show-sql=true
spring.jpa.database=SQL_SERVER
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.naming.implicit-
strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
spring.jpa.hibernate.naming.physical-
strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServerDialect
Sample Entity Class
#ToString
#Entity
#Table(schema = "PUBLIC", catalog = "INLIFE_MARK", name = "podio_item")
public class PodioItem {
#Id
#Column(name = "id")
public Long id;
#Column(name = "json", columnDefinition="varbinary")
public byte[] json;
}
I am using CrudRepository to save and find objects
#Repository
public interface PodioItemRepository extends
CrudRepository<PodioItem, Long> {
}
I was hoping maybe somekind of property as a solution but any suggestion is welcome.
Please see: How to add quotes to aliases in generated sql via Hibernate?
Just add &CLIENT_RESULT_COLUMN_CASE_INSENSITIVE=true to your snowflake connection string.
I have a spring boot application and need to create a model class that accesses a database table.
Due to permissions configurations in the db, a SELECT only works using the username in front of the table name or using an Oracle Synonym.
In SQL Developer:
SELECT * FROM MYTABLE; // This doesn't work - ORA-00942: table or view does not exist
SELECT * FROM MYUSER.MYTABLE; // This works
SELECT * FROM MYTABLE_SYNONYM; // This works
In Oracle, MYTABLE_SYNONYM is a Public SYNONYM to MYTABLE.
So the two last SELECTS above are acessing the same MYTABLE table.
In the application:
#Entity
//#Table(name = "MYTABLE") // This doesn't work - ORA-00942: table or view does not exist
//#Table(name = "MYUSER.MYTABLE") // This DOESN'T work - ORA-00942: table or view does not exist
#Table(name = "MYTABLE_SYNONYM") // This works
public class MyClass implements Serializable {
....
}
My question is why #Table(name = "MYUSER.MYTABLE") is generating the "ORA-00942" error if SELECT * FROM MYUSER.MYTABLE works fine in SQL Developer?
In the application, the only way it works is using the Public SYNONYM.
But I wouldn't like to use a Synonym because it can cause confusion and difficulties for the application maintenance as the name is different from the actual table name.
Thanks.
The annotation #Table(name = "MYTABLE") doesn't work because the user that you are using to access the database has access to another schema as the default schema.
The annotation #Table(name = "MYUSER.MYTABLE") doesn't work because this is not the right syntax to access a table in a different schema. You need to use the annotation #Table(name="MYTABLE", schema="MYUSER") that explicitly says to use the schema MYUSER and search for a table named MYTABLE in that schema. This syntax is explained in the javadoc of the annotation Table:
(Optional) The schema of the table.
Defaults to the default schema for user.
The last annotation #Table(name = "MYTABLE_SYNONYM") because somebody defined a synonim MYTABLE_SYNONYM to access the table MYTABLE on the schema MYUSER. This is transparent from the point of view of the user accessing the db.
I have a moderate size project using Spring Boot, and I am trying to create my first DataJpaTest with embedded H2, but I am getting the following exception:
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "drop table project.project.driver if exists" via JDBC Statemen
Caused by: org.h2.jdbc.JdbcSQLException: Schema "PROJECT" not found; SQL statement:
I have tried this and using a schema.sql, also this and using a test.properties in test/resources, and this other answer. But nothing worked. I am really baffled; this is the first time I face an issue in Spring Boot that I am not able to figure it out.
My entity classes are defined as:
#Entity
#Table(name = "table_name", schema = "project", catalog = "project")
#Lombok.Data
public class TableNameEntity { }
Any suggestion of how to force Hibernate to create the schema in H2?
You can pass a sql script which create schema in h2`s url:
jdbc:h2:mem:somedb;DB_CLOSE_DELAY=-1;INIT=RUNSCRIPT FROM 'classpath:create_schema.sql'
And in create_schema.sql would be something like this
CREATE SCHEMA IF NOT EXISTS project;
I have two tables with the same name in different schemas and I am trying to create an entity using both these tables and #SecondaryTable. It gives me the following error
InFlightMetadataCollector$DuplicateSecondaryTableException: Table with that name [EMPLOYEE] already associated with entity
Here is my code
#Entity
#Table(name = "EMPLOYEE", schema = "S1", catalog = "")
#SecondaryTable(name = "EMPLOYEE", schema = "S2", catalog = "", pkJoinColumns = {#PrimaryKeyJoinColumn(name = "EID", referencedColumnName = "ENO")})
public class Employee {
It seems this is a bug in Hibernate, Hibernate ORM team says on the ticket HHH-12423 that this is fixed and will be available from hibernate version 5.3.0
name needs to be unique in order to be referenced inside the column annotation ... I have two ideas which I didn't try .... you can make an alias to one database table if you have privelege to do and then refer to this alias (i don't know if it works or no) .... or you can define the table name as "s1.employee" and "s2.employee" , some providers allow it but i am not sure if hibernate does or no ... if any of these worked with u please let us know
I have just recently decided to redesign my database and I used annotated objects instead of hbm files. The problem is that now I am unable to build a configuration in order to check my queries. Any ideas?
edit: By hibernate perspective I mean the Hibernate Console Perspective you can find in 3.9.1 of the following link:
http://docs.jboss.org/tools/2.1.0.Beta1/hibernatetools/html/plugins.html
You can define named queries like this
#Entity
#Table(name = "yourTable")
#NamedNativeQueries(value = {
#NamedNativeQuery(name="nativeSelectName",
query = "select blah blah blah", resultClass = YourEntityClass.class)
})
#NamedQueries(value = {
#NamedQuery(name = "hqlQuery",
query = "from YourEntityClass where ...")