OpenJPA
  1. OpenJPA
  2. OPENJPA-586

Binding Query parameter fails validation for Externalized field

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.2.0
    • Component/s: None
    • Labels:
      None

      Description

      OpenJPA supports a field f of declared type <T> be persisted in database corresponding to a different type <S> when f specifies a two-way transformation between <S> and <T>. For example, a field f can be declared as java.net.URL but stored in database as String (i.e. VARCHAR).

      Now the question is:
      When an 'externalized' field f occurs in query predicate and is bound by a parameter p what should be the runtime type of p?

      The documentation [1] says p can be of either <T> or <S>.

      But the code breaks during parameter validation if Class(p) = <T> and with data conversion error if Class(p) = <S>

      Example:
      1. Declare a persistent field f of type java.util.UUID externalized to java.lang.String with a pair of transformer functions

      @Persistent
      @Externalizer("toString")
      @Factory("UUID.fromString")
      private UUID uuid;

      2. Use the field f in a Query with a binding parameter:
      String jpql = "SELECT p FROM ExternalValues p WHERE p.uuid=:uuid";
      Query query = em.createQuery(jpql);

      3. Try to set parameter on the query:
      a) query.setParameter("uuid", new UUID(1,2)); // parameter type equals declared type of f
      or
      b) query.setParameter(1, new UUID(1,2).toString()); // parameter type equals externalized type of f

      4. Either of step 3a or 3b will result in runtime exception

      [1] http://openjpa.apache.org/docs/latest/manual/manual.html#ref_guide_pc_extern

      1. patch-586.1.txt
        6 kB
        Pinaki Poddar

        Activity

        Hide
        Pinaki Poddar added a comment -

        This patch includes
        a) source code modification: The binding parameter types are changed to declared type of the fields instead of their externalized types
        b) test cases are added to verify the changes

        Show
        Pinaki Poddar added a comment - This patch includes a) source code modification: The binding parameter types are changed to declared type of the fields instead of their externalized types b) test cases are added to verify the changes
        Hide
        Pinaki Poddar added a comment -

        Here is snippet from Section 4.6.4.1 "Positional Parameters" of JPA 1.0 Spec:
        "An input parameter evaluates to the abstract schema type of the corresponding parameter defined in the signature of the finder or select method with which the query is associated. It is the responsibility of the persistence provider to map the input parameter to the appropriate abstract schema type value".

        Subjected to our interpretaion of "evaluates", the above directive seems to suggest that, for the given example, the runtime type of the binding parameter can be either java.util.UUID or java.lang.String. And OpenJPA documentation also seems to agree.

        However, with current implementation, it may be non-trivial to validate the query parameter at JPA-façade layer for both types. It is rather prudent to restrict the user-supplied binding parameter be of declared type only (i.e. java.util.UUID) and not the externalized type (i.e. java.lang.String).
        That is what the attached patch (patch-586.1.txt) does.

        Show
        Pinaki Poddar added a comment - Here is snippet from Section 4.6.4.1 "Positional Parameters" of JPA 1.0 Spec: "An input parameter evaluates to the abstract schema type of the corresponding parameter defined in the signature of the finder or select method with which the query is associated. It is the responsibility of the persistence provider to map the input parameter to the appropriate abstract schema type value". Subjected to our interpretaion of "evaluates", the above directive seems to suggest that, for the given example, the runtime type of the binding parameter can be either java.util.UUID or java.lang.String. And OpenJPA documentation also seems to agree. However, with current implementation, it may be non-trivial to validate the query parameter at JPA-façade layer for both types. It is rather prudent to restrict the user-supplied binding parameter be of declared type only (i.e. java.util.UUID) and not the externalized type (i.e. java.lang.String). That is what the attached patch (patch-586.1.txt) does.

          People

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

            Dates

            • Created:
              Updated:
              Resolved:

              Development