Postgresql JPA Hibernate create Database - java

I'm having trouble with Postgresql with JPA Hibernate.
My code :
#Transactional
public void createDatabase(User user) {
Query q = em.createNativeQuery("CREATE USER \"" + user.getEmail()
+ "\" WITH PASSWORD '" + user.getPasswordHash() + "' ;");
q.executeUpdate();
Query q1 = em.createNativeQuery("CREATE DATABASE " + user.getDb() + ";");
q1.executeUpdate();
Query q2 = em.createNativeQuery("GRANT ALL PRIVILEGES ON " + user.getDb()
+ " TO '" + user.getEmail() + "';");
q2.executeUpdate();
}
I'm having the following Error.
Hibernate: CREATE USER "test" WITH PASSWORD 'test' ;
Hibernate: CREATE DATABASE test;
2015-05-08 15:15:49.531 WARN 1952 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 25001
2015-05-08 15:15:49.531 ERROR 1952 --- [nio-8080-exec-6] o.h.engine.jdbc.spi.SqlExceptionHelper : ERREUR: CREATE DATABASE cannot be created in a transaction bloc
2015-05-08 15:15:49.545 ERROR 1952 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not execute statement] with root cause
org.postgresql.util.PSQLException: ERREUR: CREATE DATABASE cannot be created in a transaction bloc
If i delete the Transaction Annotation i get the following error :
javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:71)
at com.esisa.pfe.business.DefaultUserService.createDatabase(DefaultUserService.java:56)
at com.esisa.pfe.controllers.ClientController.addAbonnement(ClientController.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

The JPA EntityManager is not the object to create new databases or users. see documentation what for entity manager is used. If you want to create a new database from java you can do this with simple JDBC - here some example code:
// without db name
public static final String HOST = "jdbc:postgresql://localhost:5432/";
Statement stmt = conn.createStatement();
stmt.executeUpdate("CREATE DATABASE JavaDB");
stmt.executeUpdate("CREATE USER java_user WITH PASSWORD \'java\'");
// ...

JPA 2.1 allows you to create the datastore tables etc (and optionally schema too depending on JPA implementation and datastore) when creating the EntityManagerFactory.

Related

How to write SQL query in Java to get data from Snowflake

I am trying to write this Snowflake query into Java code:
copy into s3://snowflake171
from USER_TABLE
storage_integration = s3_int
file_format = CSV_TEST;
I am writing it like this:
String q ="COPY INTO s3://snowflake171\n" +
" FROM \"TEST\".\"PUBLIC\".\"USER_TABLE\"WHERE\"ID\\\"=?\"\n" +
" storage_integration = s3_int\n" +
" file_format = CSV_TEST";
But I am getting this error:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [COPY INTO s3://snowflake171
FROM "TEST"."PUBLIC"."USER_TABLE"WHERE"ID\"=?"
storage_integration = s3_int
file_format = CSV_TEST]; nested exception is net.snowflake.client.jdbc.SnowflakeSQLException: SQL compilation error:
syntax error line 1 at position 5 unexpected '<EOF>'.
What am I missing?
As the latest error message is "SQL access control error: Insufficient privileges to operate on integration 'S3_INT'", can you try to grant USAGE permission on s3_int to your role? Are you sure you set the correct role when connecting?
String url = "jdbc:snowflake://<account_identifier>.snowflakecomputing.com";
Properties prop = new Properties();
prop.put("user", "<user>");
prop.put("privateKey", PrivateKeyReader.get(PRIVATE_KEY_FILE));
prop.put("db", "<database_name>");
prop.put("schema", "<schema_name>");
prop.put("warehouse", "<warehouse_name>");
prop.put("role", "<role_name>");

Spring Boot Data JPA NativeQuery throws Syntax-Error on Query working in MySQL Workbench

I am using Spring Boot Data JPA and want to query data from my MySQL database. I wrote a query in MySQL workbench that works out perfectly fine in it and now I'd like to use exactly that query in my Repository as a native query.
This is the query working my MySQL Workbench:
SELECT s.* FROM fips.schedule s
inner join lecture_object lo on s.id_lecture_object = lo.id_lecture_object
inner join lecture_semester ls on lo.id_lecture_semester = ls.id_lecture_semester
inner join lecture_semester_has_possible_lecturers ll on ls.id_lecture_semester = ll.id_lecture_semester
where s.id_scenario = 1 and ll.id_lecturer=103 and ll.status="fixed";
This is the line in my Repository:
#Repository
public interface ScheduleRepository extends CrudRepository<Schedule, Integer> {
#Query(value="SELECT s.* FROM fips.schedule s " +
"inner join lecture_object lo on s.id_lecture_object = lo.id_lecture_object " +
"inner join lecture_semester ls on lo.id_lecture_semester = ls.id_lecture_semester " +
"inner join lecture_semester_has_possible_lecturers ll on ls.id_lecture_semester = ll.id_lecture_semester" +
"where s.id_scenario = :scenarioId " +
"and ll.id_lecturer = :lecturerId " +
"and ll.status = \"fixed\"", nativeQuery = true)
List<Schedule> getAllByFixedLecturerAndScenario(#Param("lecturerId") int lecturerId, #Param("scenarioId") int scenarioId);
}
Now upon execution I get the following error:
2020-09-22 18:02:15.607 DEBUG 7156 --- [nio-8081-exec-4] org.hibernate.SQL : SELECT s.* FROM fips.schedule s inner join lecture_object lo on s.id_lecture_object = lo.id_lecture_object inner join lecture_semester ls on lo.id_lecture_semester = ls.id_lecture_semester inner join lecture_semester_has_possible_lecturers ll on ls.id_lecture_semester = ll.id_lecture_semesterwhere s.id_scenario = ? and ll.id_lecturer = ? and ll.status = "fixed"
2020-09-22 18:02:15.608 WARN 7156 --- [nio-8081-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1064, SQLState: 42000
2020-09-22 18:02:15.608 ERROR 7156 --- [nio-8081-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : 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 's.id_scenario = 1 and ll.id_lecturer = 103 and ll.status = "fixed"' at line 1
2020-09-22 18:02:15.610 ERROR 7156 --- [nio-8081-exec-4] c.v.flow.server.DefaultErrorHandler :
could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
It seems like there is something wrong with the WHERE-clause, but it is exactly the same statement that works in MySQL WB. Am I missing something on the native queries? I also tried changing the " around fixed to ', which did not change the outcome (the same goes for replacing the status = "fixed" by status LIKE "fixed".
You need a space in the end of the string before "where". Change
on ls.id_lecture_semester = ll.id_lecture_semester"
to
on ls.id_lecture_semester = ll.id_lecture_semester "

PostgreSQL Full Text Search with Hibernate Query Language cannot execute query

I am developing a full text search service. I use PostgreSQL's built-in FTS query syntax. As you know, I need to use ## characters to use it. But, this characters are not recognized by HQL, you cannot directly write it like inside the sql. One option is to use nativeQuery, which I used to use. But, due to software's requirements, now I need to use HQL. For this purpose, I tried to implement this implementation.
In that implementation first you create a PostgreSQLFTSFunction class. For me it is:
public class BFTSFunction implements SQLFunction {
#Override
public boolean hasArguments() {
return true;
}
#Override
public boolean hasParenthesesIfNoArguments() {
return false;
}
#Override
public Type getReturnType(Type type, Mapping mapping) throws QueryException {
return new BooleanType();
}
#Override
public String render(Type type, List list, SessionFactoryImplementor sessionFactoryImplementor)
throws QueryException {
if (list.size() != 2) {
throw new IllegalArgumentException("The function must be passed 3 args");
}
String field = (String) list.get(0);
String value = (String) list.get(1);
String fragment = null;
fragment = "( to_tsvector(coalesce(" + field + ",' ')) ## " + "plainto_tsquery('%" +
value + "%')) ";
return fragment;
}
}
Then need to create CustomPostgreSQLDialect:(I have, for sure, added dialect configuration onto application.yml file)
public class FTSPostgresDialect extends PostgisDialect {
public FTSPostgresDialect() {
super();
registerFunction("fts", new BFTSFunction());
}
}
Lastly I created HQL in my RepositoryImp
Query<Long> q = session.createQuery(
"select b.id from B b where (fts(b.name,:searched) = true )",Long.class).setParameter("searched",searched);
List<Long> listResults = q.getResultList();
But the query created by hibernate cannot be executed. Full error will be given below, but I should say that, logged query in the console (created by Hibernate) can be executed in pgAdmin. Therefore, Query creation process is correct. Then, where can be the error is?
Full error is given:
rg.springframework.dao.DataIntegrityViolationException: could not execute query; SQL [select b0_.id as col_0_0_ from bs b0_ where ( b0_.deleted=false) and ( to_tsvector(coalesce(b0_.name,' ')) ## plainto_tsquery('%?%')) =true]; nested exception is org.hibernate.exception.DataException: could not execute query
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:261) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:223) ~[spring-orm-5.0.9.RELEASE.jar:5.0.9.RELEASE]
...
Caused by: org.hibernate.exception.DataException: could not execute query
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:118) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
...
Caused by: org.postgresql.util.PSQLException: The column index is out of range: 1, number of columns: 0.
at org.postgresql.core.v3.SimpleParameterList.bind(SimpleParameterList.java:65) ~[postgresql-42.2.5.jar:42.2.5]
at org.postgresql.core.v3.SimpleParameterList.setStringParameter(SimpleParameterList.java:128) ~[postgresql-42.2.5.jar:42.2.5]
2019-07-16 10:08:59.328 ERROR 8248 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute query; SQL [select b0_.id as col_0_0_ from bs b0_ where ( b0_.deleted=false) and ( to_tsvector(coalesce(b0_.name,' ')) ## plainto_tsquery('%?%')) =true]; nested exception is org.hibernate.exception.DataException: could not execute query] with root cause
org.postgresql.util.PSQLException: The column index is out of range: 1, number of columns: 0.
at org.postgresql.core.v3.SimpleParameterList.bind(SimpleParameterList.java:65) ~[postgresql-42.2.5.jar:42.2.5]
at org.postgresql.core.v3.SimpleParameterList.setStringParameter(SimpleParameterList.java:128) ~[postgresql-42.2.5.jar:42.2.5]
at org.postgresql.jdbc.PgPreparedStatement.bindString(PgPreparedStatement.java:996) ~[postgresql-42.2.5.jar:42.2.5]
If additional info is needed, I will fastly send it. Thanks in advance.
Interestingly, as the error suggests, hibernate cannot bind the parameters onto sql. I couldn't make it happen. But in my situation, I could just concatenate as string, therefore problem is resolved by changing HQL from:
Query<Long> q = session.createQuery(
"select b.id from B b where (fts(b.name,:searched) = true )",Long.class)
.setParameter("searched",searched);
to:
Query<Long> q = session.createQuery(
"select b.id from B b where (fts(b.name,"+searched+") = true )",Long.class);
The problem is unnecessary quotes in a plainto_tsquery call:
fragment = "( to_tsvector(coalesce(" + field + ",' ')) ## " + "plainto_tsquery('%" +
value + "%')) ";
It should be:
fragment = "( to_tsvector(coalesce(" + field + ",' ')) ## " + "plainto_tsquery(" +
value + ")) ";
I removed those % too, because it won't work like that. value won't have an actual parameter value, it would have ? in it to create a query, that will be reused for actual executions. If you want to wrap the given value into %, you'll have to do it with SQL, not Java code.

Hibernate #SQLInsert insert where not exists Postgres

I`m trying to make this work:
#SQLInsert(sql =
"INSERT INTO table" +
"(colum1,colum2,colum3,colum4,colum5)" +
" SELECT ?,?,?,?,?" +
" WHERE" +
" NOT EXISTS (" +
"SELECT id FROM table WHERE " +
"colum1 = ? " +
"AND colum2 = ? " +
"AND colum3 = ? " +
"AND colum4 = ? " +
"AND colum5 = ? " +
")",
check = ResultCheckStyle.COUNT)
But I'm getting exception:
ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; nested exception is
org.hibernate.exception.DataException: could not execute statement] with root cause
org.postgresql.util.PSQLException: No value specified for parameter 18.
And I'm starting to think that this functionality is impossible to be achieved using the #SQLInsert annotation. Witch is unfortunate because should it work it seems pretty clean approach on the issue.

"Not mapped" exception while updating the table in Hibernate

I am new to Hibernate, I am trying to update the table column like below, but it's giving an exception - table is not mapped exception.
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlUpdate = "UPDATE TEST_TABLE SET LAST_REFRESH_DATE = :dateToday";
Query query = session.createQuery(hqlUpdate);
query.setParameter("dateToday", new UtilityDate().getTodayDate());
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);
Exception
SEVERE: Servlet.service() for servlet [springmvc] in context with path
[/TEST] threw exception [Request processing failed; nested exception
is org.hibernate.hql.ast.QuerySyntaxException: TEST_TABLE is not
mapped [UPDATE TEST_TABLE SET LAST_REFRESH_DATE = :dateToday]] with
root cause org.hibernate.hql.ast.QuerySyntaxException: TEST_TABLE is
not mapped [UPDATE TEST_TABLE SET LAST_REFRESH_DATE = :dateToday] at
org.hibernate.hql.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:181)
at
org.hibernate.hql.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:110)
at
org.hibernate.hql.ast.tree.FromClause.addFromElement(FromClause.java:94)
I've verified all related questions already in Stack Overflow.
In hibernate once after defining the table mappings we always communicate with system in terms of Object and Classes. As per the snippet you posted it seems you are using the database table name and its column name in the HQL which is wrong. Instead of this you need to specify the mapped table class name and its property name in place of table column name.
if table TEST_TABLE is mapped with Java class TestTable and lastRefreshDate is the property of this class mapped to LAST_REFRESH_DATE column then below should be the code.
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hqlUpdate = "UPDATE TestTable SET lastRefreshDate = :dateToday";
Query query = session.createQuery(hqlUpdate);
query.setParameter("dateToday", new UtilityDate().getTodayDate());
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);

Categories

Resources