Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQL: select for update with uniqueResult #327

Closed
ssaarela opened this issue Jan 17, 2013 · 4 comments
Closed

SQL: select for update with uniqueResult #327

ssaarela opened this issue Jan 17, 2013 · 4 comments
Milestone

Comments

@ssaarela
Copy link
Contributor

@ssaarela ssaarela commented Jan 17, 2013

Select for update with AbstractSQLQuery.uniqueResult produces illegal SQL on Oracle:

select * from (
  select ...
  from ...
  where ...
  for update
) where rownum <= ?

-> ORA-00907: missing right parenthesis

Putting the "for update" at the end of the query should work

select * from (
  ...
) where rownum <= ?
for update

Anyhow, I'm not quite sure I like that uniqueResult (as well as singleResult) wrap the actual query with rownum-wrapper-select. It would probably be safer and at least more transparent if it would use the query as such and then process only the first row. Using those methods implies that user knows there is only one relevant match.

@timowest
Copy link
Member

@timowest timowest commented Jan 18, 2013

Both singleResult and uniqueResult have implied limits in all modules. singleResult implies that the user is interested only in the first row and uniqueResult that only a single row result is valid.

@ssaarela
Copy link
Contributor Author

@ssaarela ssaarela commented Jan 18, 2013

Thanks for the fix!

I agree about the semantics of those methods, just not the implementation as it modifies the request in a way that may even break the query. It would be easy enough to achieve the same semantics without query modification:

singleResult(x)
  iter = iterate(x)
  return iter.hasNext() ? iter.next() : null
  // close
}
uniqueResult(x)
  // as singleResult but throws an exception if iter.hasNext() after the first next() call
@timowest
Copy link
Member

@timowest timowest commented Jan 18, 2013

I agree about the semantics of those methods, just not the implementation as it modifies the request in a way that may even break the query.

It doesn't break anymore and is a valid optimization that is also utilized in JPA implementations. The forUpdate() case was broken for explicit and implied limit/offset cases, not only for uniqueResult and singleResult.

@timowest
Copy link
Member

@timowest timowest commented Feb 20, 2013

Released in 3.0.0.BETA2

@timowest timowest closed this Feb 20, 2013
@timowest timowest added this to the 3.0.0 milestone Apr 14, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants