We have a legacy app which uses Hibernate 3.0.3. We do unit testing with HSQLDB. One of the queries that is generated by Hibernate looks like this:
select
transactio0_.REASON_ID as REASON1_0_,
transactio0_.DESCRIPTION as DESCRIPT2_93_0_,
transactio0_.REASON_NAME as REASON3_93_0_
from APPS.MTL_TRANSACTION_REASONS transactio0_
where transactio0_.REASON_ID=54
and transactio0_.NVL (transactio0_.disable_date, NOW() + 1 DAY) > NOW()
Note that the schema name "transactio0_" is prepended to the NVL function. Why? How can we configure Hibernate so that does not do that?
The next question deals with the version of HSQLDB that we are using. We're currently using HSQLDB 2.2.8 and would like to move up to HSQLDB 2.3.2.
The above query works fine with HSQLDB 2.2.8 but fails in HSQLDB 2.3.2 with an "invalid schema name" error. Is there any way that we can configure HSQLDB 2.3.2 so that it can successfully execute the query like HSQLDB 2.2.8 does?
The generated SQL looks strange and is certainly incorrect SQL. The transactio0_ is a table alias and shouldn't be prepended to any function name.
Perhaps the selected Hibernate dialect is not the HSQLDB dialect.
In any case, this is an old version of Hibernate and needs to be used with a version of HSQLDB that is closer to its time of release.
Regarding configuring HSQLDB to accept the malformed name, it shouldn't be possible as the original behavior was fixed because it was too lax and accepted incorrect SQL.
I had a similiar problem. To fix this you need to put "()" together with the function name. For example:
and NVL (transactio0_.disable_date, NOW() + 1 DAY) > NOW()
change to
and NVL(transactio0_.disable_date, NOW() + 1 DAY) > NOW()
in another words, remove the space character.
Related
After upgrading H2 database version from 1.3.171 to 1.4.187, my select statement failing with the jdbc error code [90022-187]. I'm, using Spring 4 and Hibernate 4.3.5.
Error Trace :
Function "BUS_ENTY_GUID" not found; SQL statement:
select * from ( select consumerin0_.CNSMR_INTNT_SID as CNSMR_IN1_0_0_, busentity1_.BUS_ENTY_SID as BUS_ENTY1_4_1_, intentuser2_.USR_SID as USR_SID1_10_2_ where consumerin0_.OWNR_ENTY_NM=busentity1_.BUS_ENTY_GUID(+) and consumerin0_.USR_EXTRNL_ID=intentuser2_.MAG_GUID(+) and lower(consumerin0_.ORD_ID)=lower(?) and lower(intentuser2_.USR_LAST_NM)=lower(?) ) where rownum <= ? [90022-187]
Kindly help in resolving the issue
H2 no longer supports the "old style" Oracle outer join syntax. You will have to use "outer join" instead.
Thanks Thomas for you help!
I was using org.hibernate.dialect.OracleDialect, hence conversion of the query has older style joins. Now I have changed it to Oracle10gDialect which is working fine.
Use -Dh2.oldStyleOuterJoin=true to support older syntax.
Visit http://www.h2database.com/javadoc/org/h2/engine/SysProperties.html
storing filedata via a hibernate (using postgresql or oracle 10g/11g) property mapped as
<property name="fileData" type="binary">
<column name="fileData" length="104857600" />
</property>
from a java application i need to access the length of the field from the db (i do not want to load whole the object, for performance reasons). i did not find any hibernate (hql) solution to query that information, so i decided to search for features of the different databases that were used. for postgresql i found:
select BIT_LENGTH(filedata) from table
which works perfectly (and astonishing fast). now i need something similar for the use with oracle. i already tried
select utl_raw.length(filedata) from table
and
select DBMS_LOB.GETLENGTH(filedata) from table
which both results in the error msg:
"Error: ORA-00997: illegal use of LONG datatype"
is there any possibilty to query the length of that hibernate property on an oracle db without selecting the object itself?
(hibernate creates a "long raw" field on oracle, and a "bytea" field on postgresql)
thx in advance
(addition: statement will be used in a migration-context, newly created filedata entities will get a filesize property programatically)
Well, looks like i found an answer here:
https://community.oracle.com/thread/2137593
create table temp_deleteme as select to_lob(<long raw field>) obj from <tablename>;
select dbms_lob.getlength(obj) from temp_deleteme;
after creating the tempTable i can select the filedatalength from it, write it to my entities, and delete the table again. still not really good performance, but that let the db do the work and i will not have to transfer entities to my server for only calculating the needed information.
I am currently learning JPA with Hibernate, using maven as well.
It happens so that I need to use named query's in my orm.xml with a input parameter in the set-clausule of an update statement. It gives me an error that a parameter can only be used in the WHERE or HAVING clausule.
After reading several pages I found out that JPA 2.0 does not support it, but JPA 2.1 does.
See this, bulletpoint 4.6.4
So I changed my orm.xml and persistence.xml to the 2.1 schemes as well, but it still gives and error. Although it still runs perfectly, I hate seeing error signs.
Anyone Any idea? I am using Eclipse Kepler 4.3.2
Pictures of orm.xml, persistence.xml, pom.xml and my project properties can be found here
I have the same problem, code works fine and it should with JPA 2.1 (Final Release)
http://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf In chapter4.6.4 (page 182) find this text (my highlight):
"Input parameters can only be used in the WHERE clause or HAVING clause of a query or as the new value for an update item in the SET clause of an update statement. "
But eclipse validation still take input parameter in update query as an error...
Maybe we should raise a bug against org.eclipse.persistence.jpa.jpql
The following query should work:
<named-query name = "Artikel.findByWord">
<query>
UPDATE Artikel a
SET a.verkoopprijs = a.verkoopprijs * :percentage
</query>
</named-query>
with the corresponding java code:
em.createNamedQuery("Artikel.findByWord")
.setParameter("percentage", 10)
.executeUpdate();
I am using JPA, Eclipse link, Oracle.
I am trying to introduce a condition in my JPA query equivalent to following oracle expression
current_timestamp - NUMTODSINTERVAL(10, 'SECOND')
I have tried several queries similar to following
select u from User u where (current_timestamp - FUNC('NUMTODSINTERVAL', :offset, 'SECOND')) > u.birth_date
but to no avail. All result in syntax errors. I want to avoid native query as well as calculating values using java.
I found following on some oracle website.
Use the add_months function in Oracle, and use simple math to convert the month value to seconds.
If above is possible then I'll be able to use following
Query query = entityManager.createQuery("select u"
+ " from User u"
+ " where"
+ " FUNC('add_months', CURRENT_TIMESTAMP, :offset) > u.birth_date "//)"//
);
query.setParameter("offset", getOffSet());
Edit: I need some Eclipse link JPA way of doing this or Oracle way using which add_months can be used to add/deduct seconds.
(Standard JPA 2.1) JPQL allows "FUNCTION" to be included in WHERE clauses. Nowhere is there a "FUNC", except maybe in some vendor extension, and people are always advised to avoid those particularly where there is a standard
I have the following hibernate query:
Query query = session.createQuery("from MyHibernateClass");
List<MyHibernateClass> result = query.list();// executes in 7000ms
When logging the sql being executed in MySQL I see
select
myhibernat0_.myFirstColumn as myfirstcolumn92_,
myhibernat0_.mySecondColumn as mysecondcolumn92_,
myhibernat0_.mythirdcolumn as mythirdcolumn92_,
myhibernat0_.myFourthColumn as myfourthcolumn92_
from MyHibernateClass myhibernat0_
where (1=1);
When measurering the java code in the jvm on a small dataset of 3500 rows in MyHibernateClass database table this takes about 7000ms.
If I on the otherhand uses direct jdbc as follows:
Statement statement = session.connection().createStatement();
ResultSet rs = statement.executeQuery("select * from MyHibernateClass");// 7ms
List<MyHibernateClass> result = convert(rs);// executes in 20ms
I see the same sql going into the database but now the time spend in the java code in the jvm is 7ms.
The MyHibernateClass is a simple java bean class with getters and setters, I use no special resulttransformers as can be seen in the example. I only need a read-only instance of the class, and it doesn't need to be attached to the hibernate session.
I would rather like to use the hibernate version but cannot accept the execution times.
Added information:
After adding hibernate logging I see
[2011-07-07 14:26:26,643]DEBUG [main] [logid: ] -
org.hibernate.jdbc.AbstractBatcher.logOpenResults(AbstractBatcher.java:426) -
about to open ResultSet (open ResultSets: 0, globally: 0)
followed by 3500 of the following log statements
[2011-07-07 14:26:26,649]DEBUG [main] [logid: ] -
org.hibernate.loader.Loader.getRow(Loader.java:1197) -
result row: EntityKey[com.mycom.MyHibernateClass#1]
followed by 3500 log statements like
[2011-07-07 14:27:06,789]DEBUG [main] [logid: ] -
org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:130) -
resolving associations for [com.mycom.MyHibernateClass#1]
[2011-07-07 14:27:06,792]DEBUG [main] [logid: ] -
org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:226) -
done materializing entity [com.mycom.MyHibernateClass#1]
What does this mean?
What is Hibernate doing in the first implementation, how can I find out?
Adding a constructor with all attributes of the class did the trick, now the execution times are 70ms for the hibernate query. Previously the class only had a default constructor without arguments and a constructor with the entity id argument.
Based on the new information I felt I should provide another answer. The difference looks like that you have a one-to-many association specified for a List or Set property in your bean.
You are probably specifying that lazy=false which will turn off lazy loading. With lazy loading turned off it will fetch every associated record for every MyHibernateClass entity and this is why it is taking so long to execute.
Try setting lazy=true and this will perform much faster and then only retrieve the associated entities when explicitly requesting them from the entity.
If you utilize Log4j in your application you can set a variety of different logging options specific to Hibernate to get a better picture of what is going on behind the scenes in Hibernate.
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/session-configuration.html#configuration-logging
My guess is that this is the typical initial load time that occurs when first calling an HQL query in an application. Subsequent HQL queries should be noticeably and considerably faster after this first one.
I know this thread is old, but to update I ran into the same problem but with SQL Server and it turns out to be that SQL being printed by Hibernate and SQL Sent using the driver is different. Using MSSQL Driver by default sends the queries as stored procedures as RPC calls it's because the driver tries to optimize the query plan for MSSQL Standards , so it sends the queries something like
Hibernate Query:
select c.col1,c.col2 from customer c where c.name like #param1 and c.country like #param2
Actual Driver Sent Query:
#param1=somevalue, #param2=somevalue
declar sp ....
select c.col1,c.col2 from customer c where c.name like #param1 and c.country like #param2
go
Note: This Query I got through SQL Profiler Tool directly listening on DB
It turns out to be that sp_exec optimizations on the MSSQL tend to produce good Query plans that's get cached, but this would result in 'parameter sniffing' to know more about this problem read here...
So to overcome this I had following options:
Change my HQL to native Queries and add OPTION RECOMPILE FOR SOME PARAM
Use Direct query values instead of prepared statements so there will be no translation for param values and queries will not be modified as Stored Procedures by the Driver
Change the driver settings to not send the stored procedures (this is still bad because now the query plans in MSSQL server will be specific to this query, this is same as Option:2 but outside the code)
I didn't want to use OPTION 1 & 2 since that eliminates the whole purpose of using ORM Frameworks and I end up using OPTION 3 for now
So I changed the JDBC URL to send option prepareStatement=false
After setting this I had one more problem the query being sent like
Select * from customer c where c.name like **N**'somename' and c.country=**N**'somevalue'
Here there is a prefix before the values which states that to convert the encoding scheme , so I disable the JDBC url to sendUnicode = false
This all I did in JTDS driver options.. As far as I am concerned now the application is up and running fast. I have also introduced second level caches to cache it for some time..
Hope this helps for someone, if you have any good suggestion please let me know.
I had an incident where my application was always using every row in the result set of a query. I found a 40-fold increase in speed by setting my fetch size using the setFetchSize method below. (The performance improvement includes the addition of the count query.)
Long count = getStoreCount(customerId);
Query query = session.getNamedQuery("hqlGetStoresByCustomerId")
.setString("i_customerid",customerId)
.setFetchSize(count.intValue());
Be careful while doing this; my data set had about 100 rows, and it was scoped to a the life of a web request. If you have larger data sets, you will be eating Java Heap for the duration of the existence of that data, prior to returning it to the Java Heap.
I know this is an old question but here is what fixed it for me...
In your hibernate.cfg.xml make sure you have the correct !DOCTYPE... it should be as follows:
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
Anyone else who is facing a similar issue with SQL Server can use sendStringParametersAsUnicode=false in the JDBC Query String as shown in this answer:
JPA (Hibernate) Native Query for Prepared Statement SLOW
If you're not using Unicode for your prepared statement parameters and want to utilize the index on the varchar field which you're using as a parameter for the prepared statement, this can help.
It took me 10 seconds to execute a simple select all query before I found out that DOCTYPE tag is written wrongly in hibernate.cfg.xml and *mapping object*.hbm.class
Make sure that hibernate.cfg.xml start with
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
And mapping xml.class with
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
Now it took me 1-2 seconds to execute any queries.