Change By: Steve Ebersole (19/Nov/12 6:27 PM)
Description: I'm trying to make a select for update that returns only 1 row and in the query there is an order by:



{code:borderStyle=solid}
<query name="msg_m_to_b.select.head.by.userId.appId">

        from MessageMtoB msg

        where msg.userId = ? and msg.applicationId = ? and msg.blockId is null

        order by msg.id asc

</query>





Query query = session.getNamedQuery("msg_m_to_b.select.head.by.userId.appId");

query.setMaxResults(1);

query.setLockMode("msg", LockMode.UPGRADE);

query.setLong(0, userId);

query.setLong(1, appId);

message = (IMessage) query.uniqueResult();



{code}

The query that generates is incorrect:  

 

{code:borderStyle=solid}
select * from (  
 
select messagemto0_.MOAPVKMSGMT_ID as MOAPVKMS1_, messagemto0_.MOAPVUMSGMT_MESSAGE_ID as MOAPVUMS2_6_, messagemto0_.MOAPNFMSGMT_USER_ID as MOAPNFMS3_6_, messagemto0_.MOAPNKMSGMT_LICENSE_ID as MOAPNKMS4_6_, messagemto0_.MOAPVFMSGMT_IN_RESPONSE_OF as MOAPVFMS5_6_, messagemto0_.MOAPNFMSGMT_APPLICATION_ID as MOAPNFMS6_6_, messagemto0_.MOAPDGMSGMT_CREATION_DATE as MOAPDGMS7_6_, messagemto0_.MOAPCVMSGMT_MESSAGE_BODY as MOAPCVMS8_6_, messagemto0_.MOAPVGMSGMT_BLOCK_ID as MOAPVGMS9_6_, messagemto0_.MOAPDGMSGMT_ENQUEUE_DATE as MOAPDGM10_6_  
 
from MOAPTBMSG_M_TO_T messagemto0_  
 
where messagemto0_.MOAPNFMSGMT_USER_ID=? and messagemto0_.MOAPNFMSGMT_APPLICATION_ID=? and (messagemto0_.MOAPVGMSGMT_BLOCK_ID is null)  
 
order by messagemto0_.MOAPVKMSGMT_ID asc )  
 
where rownum <= ? for update of messagemto0_.MOAPVKMSGMT_ID



---> ORA-00904: messagemto0_.MOAPVKMSGMT_ID not a valid identifier


{code}

The field in the "for update" should be MOAPVKMS1_:



{code:borderStyle=solid}
select * from (  
 
select messagemto0_.MOAPVKMSGMT_ID as MOAPVKMS1_, messagemto0_.MOAPVUMSGMT_MESSAGE_ID as MOAPVUMS2_6_, messagemto0_.MOAPNFMSGMT_USER_ID as MOAPNFMS3_6_, messagemto0_.MOAPNKMSGMT_LICENSE_ID as MOAPNKMS4_6_, messagemto0_.MOAPVFMSGMT_IN_RESPONSE_OF as MOAPVFMS5_6_, messagemto0_.MOAPNFMSGMT_APPLICATION_ID as MOAPNFMS6_6_, messagemto0_.MOAPDGMSGMT_CREATION_DATE as MOAPDGMS7_6_, messagemto0_.MOAPCVMSGMT_MESSAGE_BODY as MOAPCVMS8_6_, messagemto0_.MOAPVGMSGMT_BLOCK_ID as MOAPVGMS9_6_, messagemto0_.MOAPDGMSGMT_ENQUEUE_DATE as MOAPDGM10_6_  
 
from MOAPTBMSG_M_TO_T messagemto0_  
 
where messagemto0_.MOAPNFMSGMT_USER_ID=? and messagemto0_.MOAPNFMSGMT_APPLICATION_ID=? and (messagemto0_.MOAPVGMSGMT_BLOCK_ID is null)  
 
order by messagemto0_.MOAPVKMSGMT_ID asc )  
 
where rownum <= ? for update of MOAPVKMS1_



{code}

Now, this query gives the following error:    
   
    ORA-02014:, cannot select FOR UPDATE from view with DISTINCT, GROUP BY, etc.



I think that this is because you can't put an order by in the inner query and a for update in the external query.



I re-write the query, adding the rownum condition to the inner query and eliminating the extenal query:



{code:borderStyle=solid}
select messagemto0_.MOAPVKMSGMT_ID as MOAPVKMS1_, messagemto0_.MOAPVUMSGMT_MESSAGE_ID as MOAPVUMS2_6_, messagemto0_.MOAPNFMSGMT_USER_ID as MOAPNFMS3_6_, messagemto0_.MOAPNKMSGMT_LICENSE_ID as MOAPNKMS4_6_, messagemto0_.MOAPVFMSGMT_IN_RESPONSE_OF as MOAPVFMS5_6_, messagemto0_.MOAPNFMSGMT_APPLICATION_ID as MOAPNFMS6_6_, messagemto0_.MOAPDGMSGMT_CREATION_DATE as MOAPDGMS7_6_, messagemto0_.MOAPCVMSGMT_MESSAGE_BODY as MOAPCVMS8_6_, messagemto0_.MOAPVGMSGMT_BLOCK_ID as MOAPVGMS9_6_, messagemto0_.MOAPDGMSGMT_ENQUEUE_DATE as MOAPDGM10_6_  
 
from MOAPTBMSG_M_TO_T messagemto0_  
 
where messagemto0_.MOAPNFMSGMT_USER_ID=? and messagemto0_.MOAPNFMSGMT_APPLICATION_ID=? and (messagemto0_.MOAPVGMSGMT_BLOCK_ID is null) and rownum <= ?  
 
order by messagemto0_.MOAPVKMSGMT_ID asc

for update of messagemto0_.MOAPVKMSGMT_ID


{code}

this query works



This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira