OpenJPA
  1. OpenJPA
  2. OPENJPA-1381

IllegalStateException on query method call after named query is created twice.

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0.0
    • Fix Version/s: 2.0.0-beta
    • Component/s: kernel
    • Labels:
      None

      Description

      When a query method is called (e.g. setLockMode) on a named query that has been created twice, an IllegalStateException is thrown:

      Query q1 = em.createNamedQuery("xxxx");
      ,,,,
      Query q2 = em.createNamedQuery("xxxx");
      q2.setLockMode(READ);

      11078 test TRACE [Thread-4] Tests - Caught exception and continue: java.lang.IllegalStateException: Query is neither a JPQL SELECT nor a Criteria API query.
      11078 test TRACE [Thread-4] DumpStack - java.lang.IllegalStateException: Query is neither a JPQL SELECT nor a Criteria API query.
      at org.apache.openjpa.persistence.QueryImpl.assertJPQLOrCriteriaQuery(QueryImpl.java:377)
      at org.apache.openjpa.persistence.QueryImpl.setLockMode(QueryImpl.java:396)
      at org.apache.openjpa.persistence.QueryImpl.setLockMode(QueryImpl.java:1)
      at org.apache.openjpa.persistence.lockmgr.SequencedActionsTest.launchCommonSequence(SequencedActionsTest.java:409)

        Activity

        Hide
        Albert Lee added a comment -

        Pinaki,

        The fix works for setLockMode() but still need implementation to protect getLockMode(). See my previous comment.

        Thanks for getting this in so quickly.
        Albert Lee.

        Show
        Albert Lee added a comment - Pinaki, The fix works for setLockMode() but still need implementation to protect getLockMode(). See my previous comment. Thanks for getting this in so quickly. Albert Lee.
        Hide
        Pinaki Poddar added a comment -

        Albert, see if this works. Otherwise I will reopen.

        Show
        Pinaki Poddar added a comment - Albert, see if this works. Otherwise I will reopen.
        Hide
        Albert Lee added a comment -

        The IllegalStateException semantics also apply to the Query.getLockMode() method call, per spec. Similar usage of the ignorePreparedQuery() can be applied to getLockMode(), however it will lose the effectiveness of the cache (i.e. invalidate and rebuild) since getLockMode does not change the query's structure.

        Show
        Albert Lee added a comment - The IllegalStateException semantics also apply to the Query.getLockMode() method call, per spec. Similar usage of the ignorePreparedQuery() can be applied to getLockMode(), however it will lose the effectiveness of the cache (i.e. invalidate and rebuild) since getLockMode does not change the query's structure.
        Hide
        Albert Lee added a comment -

        The limitation/requirement of using the query cache is documented in the manual.

        The query cache is enabled by default, which is a problem for a JPA compliance application that has the reported usage pattern.

        Pinaki agrees using this JIRA to either:

        • make the Query cache disabled by default.
        • invalidate the cache at the appropriate call path
        • potentially using QueryImpl.ignorePreparedQuery() to automatically by-pass the problem.

        Albert Lee.

        Show
        Albert Lee added a comment - The limitation/requirement of using the query cache is documented in the manual. The query cache is enabled by default, which is a problem for a JPA compliance application that has the reported usage pattern. Pinaki agrees using this JIRA to either: make the Query cache disabled by default. invalidate the cache at the appropriate call path potentially using QueryImpl.ignorePreparedQuery() to automatically by-pass the problem. Albert Lee.
        Hide
        Albert Lee added a comment -

        Work around of this limitation is to specify query hint "openjpa.hint.IgnorePreparedQuery" to true.

        What is the reason cached query is treated as SQL and subsequently does not allow query methods that requires JPQL/Criteria API as the source language?

        Show
        Albert Lee added a comment - Work around of this limitation is to specify query hint "openjpa.hint.IgnorePreparedQuery" to true. What is the reason cached query is treated as SQL and subsequently does not allow query methods that requires JPQL/Criteria API as the source language?
        Hide
        Albert Lee added a comment -

        The problem is in PreparedQueryImpl, in which getLanauge() always return QueryLanguages.LANG_PREPARED_SQL regardless of the source of the cached Query. It is not sensitive to the query source.

        In EntityManagerImpl.createNamedQuery:

        public OpenJPAQuery createNamedQuery(String name) {
        try {
        ....
        PreparedQuery pq = JPQLParser.LANG_JPQL.equals(meta.getLanguage())
        ? getPreparedQuery(qid) : null;
        org.apache.openjpa.kernel.Query del = (pq == null)
        ? _broker.newQuery(meta.getLanguage(), meta.getQueryString())
        : _broker.newQuery(pq.getLanguage(), pq);

        The first time the named query is created, there is no query cached, a new Query is created using the metadata's language attribute (i.e. JPQL). The second time the named query is created, it is found in query cache, and the preparedQuery's language is used, which is ALWAYS SQL, that caused the ISEx when tested in the setLockMode() call path.

        Show
        Albert Lee added a comment - The problem is in PreparedQueryImpl, in which getLanauge() always return QueryLanguages.LANG_PREPARED_SQL regardless of the source of the cached Query. It is not sensitive to the query source. In EntityManagerImpl.createNamedQuery: public OpenJPAQuery createNamedQuery(String name) { try { .... PreparedQuery pq = JPQLParser.LANG_JPQL.equals(meta.getLanguage()) ? getPreparedQuery(qid) : null; org.apache.openjpa.kernel.Query del = (pq == null) ? _broker.newQuery(meta.getLanguage(), meta.getQueryString()) : _broker.newQuery(pq.getLanguage(), pq); The first time the named query is created, there is no query cached, a new Query is created using the metadata's language attribute (i.e. JPQL). The second time the named query is created, it is found in query cache, and the preparedQuery's language is used, which is ALWAYS SQL, that caused the ISEx when tested in the setLockMode() call path.

          People

          • Assignee:
            Pinaki Poddar
            Reporter:
            Albert Lee
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development