I have an application that should support oracle and mysql databases.
I will get different configuration for different database.
But i want all HSQL used in the code to be intact.
But i am not able to do so bcoz of below :
I have created a query like below:
String SQL_QUERY = "select count(log) from dbtable where created_date='"+ givenDate
Query query = session.createQuery(SQL_QUERY);
query.uniqueResult();
This works very well in mysql
but not in oracle
because oracle db expects formatting the value of created_date column with
to_date(givenDate,"yyyy-MM-dd")
so i have to change the above query as :
String SQL_QUERY = "select count(log) from dbtable where created_date=to_date('"+ givenDate+","yyyy-MM-dd")
Can I avoid this multiple query declarations in any way for mysql and oracle ??
Create a java.sql.Date out of that String and pass it to the query; don't embed the conversion in the database.
Better yet, bind the String to a Date long before it gets to the persistence tier. Java's an object-oriented language; think in terms of objects.
Related
I'm using Spring Data JPA + QueryDSL. I create my dynamic queries like this:
JPAQuery<Foo> query = jpaQueryFactory.select(...);
I have found this old article that shows how to retrieve programatically the native sql string: https://antoniogoncalves.org/2012/05/24/how-to-get-the-jpqlsql-string-from-a-criteriaquery-in-jpa/ but it doesn't work for me.
I have tried this:
String queryString1 = query.createQuery().unwrap(org.hibernate.query.Query.class).getQueryString();
String queryString2 = query.createQuery().unwrap(org.eclipse.persistence.jpa.JpaQuery.class).getDatabaseQuery().getSQLString();
The first doesn't returns me the the native sql but the JPQL string and the second fails to unrwap org.hibernate.query.internal.QueryImpl to org.eclipse.persistence.jpa.JpaQuery.
PS: I've tested before and after fetching the query.
If you need native SQL query generated by Querydsl, then you need to use SQLQueryFactory instead JPAQueryFactory. Your JPQL query returned by JPAQueryFactory is transformed to SQL by JPA not by Querydsl.
In my company we are performing a database migration. For lots of reasons we cannot use a database migration tool, so we had to develop our migration tool to copy from a DB to another all rows contained in some specific tables. We have developed a tool using JDBC of multiple database. At the moment, we are migrating from DB2 to Oracle, with an intermediate step to H2. Same tables ha a Clob column. When we export this column from DB2 to H2 we get no errors or issues, but when we try to copy the Clob from H2 to Oracle using JDBC we get the following exception:
ClassCastException: cannot cast from org.h2.jdbc.JdbcClob to oracle.jdbc.Clob
Is there a way or a procedure to perform this kind of conversion? Something like a ClobCopy utility within different Clob types? Unfortunately we can do this task only using Java and Jdbc, no JPA or DB migration tools due to customer specifications.
This is an example of what I'm trying to do:
public class CopyTable {
public void doCopy(){
Connection h2 = getH2Connection(); //suppose this exists and works
Connection oracle = getOracleConnection(); //suppose this exists and works
String sqlSelect = "select * from tabletoexport";
String sqlInsert = "insert into tabletofill(ID, DATA) values (?,?)";
PreparedStatement select = h2.prepareStatement(sqlSelect);
PreparedStatement insert = oracle.prepareStatement(sqlInsert);
ResultSet rs = select.executeQuery();
while (rs.next()){
insert.setLong(1, rs.getLong("ID"));
insert.setClob(2, rs.getClob("DATA")); //this throws an exception
insert.executeUpdate();
}
}
}
The Clob interface has a getCharacterStream() method which returns a Reader, and the PreparedStatement interface has a setClob() method which takes a Reader. All you need to do to get the copy working is to use these methods.
In other words, replace the line
insert.setClob(2, rs.getClob("DATA")); //this throws an exception
with
insert.setClob(2, rs.getClob("DATA").getCharacterStream());
As for why the import from DB/2 to H2 didn't complain, perhaps the H2 JDBC driver doesn't assume that Clob values passed in to setClob come from H2, but the Oracle JDBC driver does assume that Clobs passed in in the same way are from Oracle. However, the Oracle JDBC can't reasonably make any such assumptions about a Reader, as these could come from anywhere
I have a PreparedStatement intended to be run both on ORACLE and on MYSQL.
But I cannot figure out how to handle the CAST(NULL AS ...)
On Oracle the following works (but not on Mysql):
SELECT TIMB_INS,
CAST(NULL AS TIMESTAMP) AS TIMB_CLO
FROM TOPS
On Mysql the following works (but not on Oracle):
SELECT TIMB_INS,
CAST(NULL AS DATETIME) AS TIMB_CLO
FROM TOPS
(Please note that the first column selected, "TIMB_INS", returns the correct data type for target database type in both cases, i.e. TIMESTAMP for Oracle and DATETIME for MySql.)
There is a way to put it so that it works for both?
I.E. Can i make it db-indipendent in some way?
Thanks
Marco
Based on the tags I can see you're calling this statement from some java code. There are several ways doing so:
Use the DAO pattern. I.e. for each SQL flavor provide a java file that contains the SQL-s.
Use an ORM like Hibernate or JPA. That will take care of this kind of differences.
As a quick hack, you can edit the SQL manually, like in the snippet below. But then you have to determine somehow if the underlying database is Oracle or MySQL
String SQL_PATTERN = "... CAST(NULL AS %s) AS TIMB_CLO ...";
String SQL = String.format(SQL_PATTERN, isOracle ? "TIMESTAMP" : "DATETIME");
I'm using hibernate 3.6.4.Final and sql server 2008 r2 and got a query on a table with more than 20 million records. Criteria api does unfortunatly generate sub-optiomal queries when paging (select top 100010 from ... for result 100000 - 100010 ) when using firstResult / maxResult so I've reverted to native sql.
This queries run blazingly fast in sql studio but using named or positional parameters in hibernate those queries crawl painfully slow. Googling along I couldn't find any solution so I'm currently concatenating parameters which allows sql injections, but this is of course no option for production!
Now I'm wondering if there's something I've overlooked or at least some hibernate api or library I'm not aware of which I could use to sanitize parameters before rolling my own and probably failing to catch some edge case...
Unfortunately, Criteria API is the best way to avoid sql injection, but it is so slow, the best way is to use normal Hibernate Queries with dynamic parameters, i mean For ex:
String stringQuery ="select * from User as u where id = :id";
Query query=session.createQuery(stringQuery);
query.setParameter("id",12);
OR u can make your query more dynamic by creating a new Class MyQueryBuilder
public class myQueryBuilder(){
public Query buildQuery(int id){
String stringQuery ="select * from User as u where u.id = :id";
Query query=session.createQuery(stringQuery);
query.setParameter("id",12);
return query;
}
public Query buildQuery(int id,String name){
String stringQuery ="select * from User as u where u.id = :id and u.name = :name";
Query query=session.createQuery(stringQuery);
query.setParameter("id",12);
query.setParameter("name",name);
return query;
}
...
//Later you can call the query builder methods as you want depending on your params
}
and remember that it is always safe using setParameter() Method
I got very typical issue. My dynamically generated query like this...
UPDATE Templates t SET t.TEMPLATE_DATA = replace(t.TEMPLATE_DATA, 'Test\'s Test', 'Kent"s Test'), t.TEMPLATE_DATA = replace(t.TEMPLATE_DATA, 'Test"s Test', 'Kent"s Test'), UPDATE_DATE = NOW() where PRACTICE_ID = 1 AND CATEGORY_ID IN (1)
This works perfect when I explictily fire this query in db. but by using hibernate's session.createQuery(-- my query --) if thwows an error QueryTranslatorException.
Database : Mysql 5.3
Have any one faced this issue?
Thanks in advance.
Try to run this in Hibernate as native SQL query:
session.createSQLQuery(-- query text --);
Because if you use
session.createQuery(-- query text --);
Hibernate will try to execute it as HQL query which differs from usual SQL query.
HQL is object oriented query language. It operates in terms of objects rather then in terms of tables. Here posted a brief description of difference between SQL and HQL. But if you have time better to read appropriate sections of hibernate's documentation about HQL and Native SQL usage.
If you want to execute SQL Query in hibernate, Use : session.createSQLQuery(String query);