Search code examples
javaplayframeworkormuuidebean

Ebean - Find by part of UUID in UUID column Type


from Historical reasons we have ORM Model as bellow with several UUID values. Yes, I know.. We have to implement new frontend for users, where user can write only part of UUID (printed on boxs, papers etc..) Its used for manual verification (Q&A in Factory). Normally this is done with the QR reader, but in some cases it is not possible to scan it. So user can write first 10 chars or 6 last chars...

!! -> And we cannot change anything on this model. (Corporation...)

public class Model_OrderCross {

   public UUID id;
   public UUID order_a;
   public UUID order_b;
   public UUID order_c;
   public UUID order_e;
}

Why I am Asking. We have Exception with wrong argument types from Ebean when we are trying to find list of objects with this part of UUID

Caused by: org.postgresql.util.PSQLException
Cause message: ERROR: function lower(uuid) does not exist
  Rada: No function matches the given name and argument types. You might need to add explicit type casts.

I am using ORM query:

Query<Model_OrderCross > query = Ebean.find(Model_OrderCross.class);

// Where order_b is something like "f223274c-51" from Full UUID "f223274c-51ca-4489-a5b2-7d3b29887cfb" 
if (request.order_b != null) {       
    query.where().icontains("order_b", request. order_b);
}

if (request.order_c != null) {       
    query.where().icontains("order_c", request. order_c);
}
  • And for normal String or Text values ..icontains(..) work

Solution

  • According to the PostgreSQL documentation Section 9.4. String Functions and Operators (Table 9.8), the function lower(string) accepts string literals and "Converts [a] string to lower case" representation.

    As the exception message says,

    ERROR: function lower(uuid) does not exist.

    So you have to formulate the criteria queries to take a string representation of the UUID values, e.g.:

    query.where().icontains("order_b", request. order_b.toString());
    

    This should do the trick. Note well the toString() at the end which conducts the conversion to a string literal. The details of the conversion is described in the JavaDoc of UUID.toString().

    For reference, I add the link to the JavaDoc of the ExpressionList.icontains() method which you applied in the code snippet. Internally, it "uses a lower() function to make the expression case insensitive".

    Hope it helps.