[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-759?page=co...
]
Frederic Leitenberger commented on HHH-759:
-------------------------------------------
Hello again, i have serous trouble with this.
I need to use ORDER BY, MAXROWS and FOR UPDATE in one query.
e.g.:
Criteria criteria = getSession().createCriteria(MyClass.class)
.add(Restrictions.eq("myField", false))
.add(Order.desc("oderField"))
.setLockMode(LockMode.UPGRADE)
.setMaxResults(1);
What i want form this query is:
- select the rows for my restricitions
- order the result
- limit the result
- lock the result
What it currently get (simplified) is:
select * from (
select *
from myClass
where myField = 0
order by usage desc
) where rownum <= ?
for update of this_.id
As we already know this doesn't work:
org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.loader.Loader.doList(Loader.java:2223)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
at org.hibernate.loader.Loader.list(Loader.java:2099)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:94)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1569)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:283)
at
de.iccs.api.facades.ResellerBlockFacade.listResellerFreeBlocksForAssignment(ResellerBlockFacade.java:245)
at
de.iccs.api.facades.ResellerBlockFacade.allocateNumbersInternal(ResellerBlockFacade.java:1095)
at
de.iccs.api.facades.GeoNumberFacade.allocateGeoNumbersInternal(GeoNumberFacade.java:979)
at
de.iccs.api.facades.GeoNumberFacade.reserveGeoNumbersInternal(GeoNumberFacade.java:938)
at
de.iccs.api.facades.GeoNumberFacade.allocateGeoNumbersForAllocateEleven(GeoNumberFacade.java:798)
at
de.iccs.api.facades.GeoNumberFacade$$EnhancerByCGLIB$$cf19ce9a.CGLIB$allocateGeoNumbersForAllocateEleven$2(<generated>)
at
de.iccs.api.facades.GeoNumberFacade$$EnhancerByCGLIB$$cf19ce9a$$FastClassByCGLIB$$2ccb1367.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:167)
at
de.iccs.api.facades.interceptors.FacadeInterceptor.intercept(FacadeInterceptor.java:17)
at
de.iccs.api.facades.interceptors.HibernateFacadeInterceptor.intercept(HibernateFacadeInterceptor.java:82)
at
de.iccs.api.facades.GeoNumberFacade$$EnhancerByCGLIB$$cf19ce9a.allocateGeoNumbersForAllocateEleven(<generated>)
at
de.iccs.api.facades.GeoNumberFacadeTest.testAllocateGeoNumbersForAllocateEleven(GeoNumberFacadeTest.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at
org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.sql.SQLException: ORA-00904: "THIS_"."ID": invalid
identifier
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:125)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:305)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:272)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:623)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:181)
at
oracle.jdbc.driver.T4CPreparedStatement.execute_for_describe(T4CPreparedStatement.java:420)
at oracle.jdbc.driver.OracleStatement.execute_maybe_describe(OracleStatement.java:896)
at
oracle.jdbc.driver.T4CPreparedStatement.execute_maybe_describe(T4CPreparedStatement.java:452)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:986)
at
oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:2888)
at
oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:2929)
at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1787)
at org.hibernate.loader.Loader.doQuery(Loader.java:674)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.doList(Loader.java:2220)
... 33 more
When i change the setMaxRows-call to:
if (maxResults > 0) criteria.add(sqlRestriction("rownum <= ?", maxResults,
new IntegerType()));
... or simply ...
criteria.add(Restrictions.sqlRestriction("rownum <= 1"));
... the following is generated:
select *
from myClass
where myField = 0
and rownum <= ?
order by usage desc
for update of this_.id
The statement can be executed, but does the following (in exaclty this order):
- select the rows for my restricitions
- limit the result (unordered)
- order the result (the one selected row)
- lock the result
For comparison again what i wanted form this query:
- select the rows for my restricitions
- order the result
- limit the result
- lock the result
Any idea how to solve this?
I had an idea of selecting and locking only an id, but i am still not sure if that solves
the problem in any way.
Another idea was to drop the setMaxRows part and user iterate to get as many rows as
needed an then close the iterator and cursor with Hibernate.closeIterator(iter).
But HB-308 and HHH-249 indicate that this will not be available very soon considering the
comments and the last-modified timestamps.
And since it would we somewhat difficult and stupid to bypass the critera-functionality i
am stuck here.
Any help would be great !
problem for mixxing setmaxresults and setlockmode
-------------------------------------------------
Key: HHH-759
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-759
Project: Hibernate3
Issue Type: Bug
Affects Versions: 3.0.2
Environment: Client:windows2000 professional,jre1.4.2,
oracle8client,eclipse3.1-RC3,hibernate-tools 3.0 alpha4a,JBossIDE1.5M1
Server:Solaris 2.8, oracle 8.1.7
Reporter: johnhua
Priority: Minor
there is a problem for mixxing setmaxresults and setlockmode.
the problem is that "ORA-00904: invalid column name".
The error info is as the below:
Hibernate: select * from ( select idmapp0_.RI as col_0_0_ from PCTMNGT.IDMAP_P idmapp0_
where idmapp0_.STATUS=? ) where rownum <= ? for update of idmapp0_.RI
14:21:54,076 DEBUG AbstractBatcher:AbstractBatcher.java:365 - preparing statement
14:21:54,082 DEBUG AbstractBatcher:AbstractBatcher.java:285 - about to close
PreparedStatement (open PreparedStatements: 1, globally: 1)
14:21:54,083 DEBUG AbstractBatcher:AbstractBatcher.java:403 - closing statement
14:21:54,090 WARN JDBCExceptionReporter:JDBCExceptionReporter.java:71 - SQL Error: 904,
SQLState: 42000
14:21:54,091 ERROR JDBCExceptionReporter:JDBCExceptionReporter.java:72 - ORA-00904:
invalid column name
The source code is as the below:
//query an unused emid for new tone
query = av_session.createQuery("select v_idmap from IdmapP as v_idmap where
v_idmap.status=:v_status");
query.setCharacter("v_status",EMID_STATUS.UNUSED.charValue());
query.setMaxResults(1);
query.setLockMode("v_idmap",LockMode.UPGRADE);
it = query.iterate();
if( !it.hasNext() )
{
tx.rollback();
lv_err = "addRing::doAddRingFile: no unused EMID for new tone in idmap.
toneid="+av_tone;
throw new InterfaceErrException(lv_err,INTERFACE_RETCODE.SYSTEM_ERR);
}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira