Hibernate HQL query with boolean attibute and SAP HANA DB - java

Goodmoring
I have the following situation.
I have a model with a boolean attribute
#Column(name = "ELIMINATO")
private Boolean eliminato;
and the following HQL query on it
Query q = session.createQuery("from Sottoscrittore where eliminato = false");
Hibernate generates the following SQL query
select
... all fields ...
from
SOTTOSCRITTORE modulounic0_
where
modulounic0_.ELIMINATO=0
When I run this query the following error is returned
SAP DBTech JDBC: [266]: inconsistent datatype: INT type is not comparable with BOOLEAN type.
The problem is that in SAP HANA DB the correct query is the following
select
... all fields ...
from
SOTTOSCRITTORE
where
ELIMINATO=FALSE;
To set the right value of the query I tried to set the hibernate property
"hibernate.query.substitutions" in "hibernate.cfg.xml" in this way
<property name="hibernate.query.substitutions">true TRUE, false FALSE</property>
but I had the same error.
It could be a Hibernate framework bug?
How can I solve the problem?
Thanks
Regards

just add following property in your persistence.xml file:
<property name="hibernate.dialect.hana.use_legacy_boolean_type" value="false"/>

Related

Execute Normal SQL Query in Hibernate

I'm using Hibernate for Database connection. My user has the right to get the open_mode (select open_mode from v$database).
I wanted to execute the query in hibernate using the existing hibernate DB configuration Also I do not want to create a JDBC connection codes in my java file like the below
String url = "jdbc:oracle:thin:#192.179.9.31:1521:db1";
Connection conn = DriverManager.getConnection(url,"user","password");
Statement stmt = conn.createStatement();
ResultSet rs;
rs = stmt.executeQuery("select openmode from v$database");
while ( rs.next() ) {
String lastName = rs.getString("openmode");
Since this v$database is not a real table in our schema, I am thinking we cannot create a entity class for v$database and execute the query using hql.
Anyone how I can execute the above query and get a result using my existing config.
Here is my hibernate configuration detail.
<property name="dialect"> org.hibernate.dialect.Oracle9Dialect</property>
<property name="connection.url"> jdbc:oracle:thin:#192.179.9.31:1521:db1
</property>
<property name="connection.username">user</property>
<property name="connection.password">passsword</property>
<property name="connection.driver_class"> oracle.jdbc.driver.OracleDriver
</property>
<property name="myeclipse.connection.profile"> Oracle 9i Connector
</property>
You can create native queries in Hibernate for tables which don't have mapped entities.
Create a hibernate session as you do generally and then create native query referring below snippet.
String sqlQuery = "select openmode from v$database";
Query q = session.createNativeQuery(sqlQuery);
List<Object[]> listResults = query.getResultList();
This will return list of arrays. You need to iterate over this list and parse the output to any POJO in your domain.
An example is provided on this page.
You can also used overloaded version of this method for entities mapped with tables to take benefit of DB specific features such as hints or CONNECT BY.
Update
Another way which OP tried was to use createSQLQuery. Scalar is used to map the columns with Hibernate type.
String sqlQuery = "select open_mode from v$database";
SQLQuery query = session.createSQLQuery(sqlQuery).addScalar("open_mode", Hibernate.STRING);
List result = q.list();
String open_mode = result.get(0).toString();
You could use session.doWork(...) method.
This is meant for allowing users to perform JDBC related work using the Connection managed by this Session.
session.doWork(new Work() {
#Override
public void execute(Connection connection) throws SQLException {
//Perform JDBC statement, resultset etc here.
}
});

Hibernate dialect

I am using Hibernate to accessing data from sql server 2008.while executing the following code
Session session = sessionFactory.openSession();
String qry="select Form_Id,SUBSTRING(
(SELECT ( '' + t2.Form_Layout_Txt) FROM Form_Layout_Info t2
WHERE t1.Form_Id = t2.Form_Id " +
" GROUP BY Form_Layout_Txt FOR XML path('') ), 1,1000000000)
FROM Form_Layout_Info t1 GROUP BY Form_Id";
SQLQuery query = session.createSQLQuery(qry);
recordList = query.list();
My Hibernate properties is
hibernate.connection.driver_class=com.microsoft.sqlserver.jdbc.SQLServerDriver
hibernate.connection.url=jdbc:sqlserver://localhost:1433;databaseName=abc;integratedSecurity=false;
hibernate.dialect=org.hibernate.dialect.SQLServerDialect
hibernate.connection.username=sa
hibernate.connection.password=p123asc
i received the following error
No Dialect mapping for JDBC type: -9
How to fix the issue.
You need to provide hibernate.dialect=org.hibernate.dialect.SQLServerDialect in configuration for sql server.
Either provide it in hibernate.cfg.xml as :
<hibernate-configuration>
<session-factory name="session-factory">
.....
<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
....
</session-factory>
</hibernate-configuration>
or in properties file as :
hibernate.dialect=org.hibernate.dialect.SQLServerDialect
I don't know which way you are using, so posted both I know.
I found 2 solutions for your problem here:
try changing your driver to jTDS
using the ms sql server jdbc driver provided by microsoft can cause this issue while jTDS does not give this complaint.
you may need to explicitly “addScalar” to your hibernate query. You might have something like this:
sess.createSQLQuery("SELECT * FROM CATS");
// try changing to:
sess.createSQLQuery("SELECT * FROM CATS")
.addScalar("ID", Hibernate.LONG)
.addScalar("NAME", Hibernate.STRING)
.addScalar("BIRTHDATE", Hibernate.DATE)
This issue is related to type mapping done while returning data. And mapping for that particular data type not exists in Dialect.
https://forum.hibernate.org/viewtopic.php?f=1&t=959583
Hibernate Data types -
http://docs.jboss.org/hibernate/orm/3.6/javadocs/org/hibernate/type/StandardBasicTypes.html
The error means hibernate doesn’t know how to map the JDBC type “NVARCHAR” to a hibernate type.
Solution 1:
Using addScalar like this:
Session session = sessionFactory.openSession();
String qry="select Form_Id,SUBSTRING(
(SELECT ( '' + t2.Form_Layout_Txt) as formLayoutTxt FROM Form_Layout_Info t2
WHERE t1.Form_Id = t2.Form_Id " +
" GROUP BY Form_Layout_Txt FOR XML path('') ), 1,1000000000)
FROM Form_Layout_Info t1 GROUP BY Form_Id";
SQLQuery query = session.createSQLQuery(qry).addScalar("formLayoutTxt", StringType.INSTANCE);
recordList = query.list();
Solution 2: Register the Hibernate Type in Dialect
public class MySQLServerDialect extends SQLServerDialect {
public MySQLServerDialect() {
super();
// Register mappings
registerHibernateType(Types.NVARCHAR, StringType.INSTANCE.getName());
}
}
For more details, check out this.

Getting org.hibernate.MappingException: No Dialect mapping for JDBC type: -4 exception?

I am getting following exception at query.list() line:
org.hibernate.MappingException: No Dialect mapping for JDBC type: -4
at org.hibernate.dialect.TypeNames.get(TypeNames.java:56)
at org.hibernate.dialect.TypeNames.get(TypeNames.java:81)
at org.hibernate.dialect.Dialect.getHibernateTypeName(Dialect.java:369)
at org.hibernate.loader.custom.CustomLoader$Metadata.getHibernateType(CustomLoader.java:559)
at org.hibernate.loader.custom.CustomLoader$ScalarResultColumnProcessor.performDiscovery(CustomLoader.java:485)
at org.hibernate.loader.custom.CustomLoader.autoDiscoverTypes(CustomLoader.java:501)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1787)
at org.hibernate.loader.Loader.doQuery(Loader.java:662)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.doList(Loader.java:2211)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2095)
at org.hibernate.loader.Loader.list(Loader.java:2090)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:289)
at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1695)
at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:142)
at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:152)
following is my configuration file:
<property name="hibernate.connection.driver_resource">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">mysql</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mydatabase</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.default_schema">mydatabase</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
When I am trying to run application into Eclipse IDE then this exception is not coming but when I create jar of application and run then only I am getting it.
thanks in advance...
Sometimes database returns results of custom SQL queries in strange types that cannot be mapped to Hibernate types (especially when you use expressions under select).
You need to find an offending query and add an explicit cast to it.
For example
Object o = session.createSQLQuery("select 2*2").uniqueResult();
may cause such a problem. You may fix it as follows:
Object o = session.createSQLQuery("select cast(2*2 as int)").uniqueResult();
Got the solution:
Just change the Query, I am fetching whole record instead of select specific.
e.g. from table and then get respective field (here script) value from table Object instead of using select script from table, It is working fine now.

No Dialect mapping for JDBC type: -102

i have a problem. Some sql in my program could be written by the user. So I don't know which table or which columns are in this sql. Therefore i want to detect which column names are in the sql. But if a date is in the sql i get the No Dialect mapping for JDBC type: -102 error.
How could i handle that? I am using hibernate 3.6 or 4.1.3 with java. My database is an oracle database. The dialect is org.hibernate.dialect.Oracle10gDialect.
I really don't know what is in the sql.
Here is my code:
SQLQuery q=session.createSQLQuery("SELECT * FROM tbl WHERE id = 2");
q.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE);
List<Map<String,Object>> aliasToValueMapList=q.list();
for(Map<String,Object> map : aliasToValueMapList){
System.out.println(map.keySet());
break;
}
I hope anyone knows a solution for this problem.
Greetz
Your query is attempt to return a column that the JDBC ResultSetMetaData is reporting a type (-102) which Hibernate does not know how to read. You need to register the type for that column with the query using org.hibernate.SQLQuery#addScalar or you may not be able to use that transformer and actually define the entire result set mapping to your entity org.hibernate.SQLQuery#addRoot/org.hibernate.SQLQuery#addEntity. See the docs for usage
If you use session.createQuery() this will use your dialect to talk to the database using Hibernate Query Language. but if you use createSQLQuery() you have to use PL/SQL to talk to the oracle.

Hibernate update not working

I am new with hibernate and I was trying to update a mapped object with the following code, but it does not update
factory = config.buildSessionFactory();
session = factory.getCurrentSession();
Transaction t = session.beginTransaction();
String hql = "UPDATE "+tableName+" SET "+columnName+" = '"+columnValue+"' WHERE id ="+id+";";
Query query=session.createSQLQuery(hql);
t.commit();
Am I missing something? It do not crash nor update the record.
NOTE: I am using Hibernate3 and Mysql
You're missing query.executeUpdate();
Also, if you're updating a mapped object I would recommend you to make the changes to the java object, and let Hibernate do the update for you. Or at least use a hql query, not a native one.
Make sure that your persistence.xml file has show_sql set to true and watch the log to see if the update is executed.
<property name="hibernate.show_sql" value="true"/>
You need to use query.executeUpdate() to run the query.
Also it is suggested that you use parameters instead of inline arguments. For eg. if the columnName = O'Reilly then the whole query will go wrong.
Also if it is a mapped object you can use HQL rather than SQL query
Instead you can use this
//entity is your hibernate entity obj
String hql = "UPDATE " + entity.getClass().getName + " as entity SET entity." + fieldName + "= :columnValue WHERE entity = :entity";
Query query=session.createQuery(hql).setParameter("columnValue", columnValue).setParameter("entity", entity);
query.executeUpdate();
Notice that you don't need to use single quotes. setParameter handles it.

Categories

Resources