Custom criteria in hibernate

    In a previous article, I talked about how to teach Hibernate to store custom data types. Now let's try to use this data when filtering samples. We will declare the result we want to get:
    1. String filteringTag = "habr";
    2. Session session = ...;
    3. Criteria criteria = session.createCriteria(StringArrayContainer.class);
    4. criteria.add(new StringArrayContainsCriterion("tags", filteringTag));
    5. List containers = criteria.list(); //Получаем список контейнеров, содержащих тег "habr"
    6. ...


    First, we write a universal implementation of the search criteria. To do this, make a small change to the StringArrayCustomType.nullSafeGet and StringArrayCustomType.nullSafeSet methods, namely, surround the value stored in the column with spaces. (Changes in lines 7 and 25)
    1. @Override
    2. public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
    3.     String value = (String) Hibernate.TEXT.nullSafeGet(rs, names[0]);
    4.     if (value == null) {
    5.         returnnull;
    6.     } else {
    7.         String[] array = StringUtils.split(value.trim(), ' ');
    8.         for (int i = 0; i < array.length; i++) {
    9.             array[i] = WhitespaceEscapeUtil.unescape(array[i]);
    10.         }
    11.         return array;
    12.     }
    13. }
    14.  
    15. @Override
    16. publicvoid nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
    17.     if (value == null) {
    18.         Hibernate.TEXT.nullSafeSet(st, null, index);
    19.     } else {
    20.         String[] array = (String[]) value;
    21.         String[] copy = new String[array.length];
    22.         for (int i = 0; i < array.length; i++) {
    23.             copy[i] = WhitespaceEscapeUtil.escape(array[i]);
    24.         }
    25.         Hibernate.TEXT.nullSafeSet(st, ' '+StringUtils.join(copy, ' ')+' ', index);
    26.     }
    27. }

    Now we carefully implement the org.hibernate.criterion.Criterion interface.
    1. publicclass GenericStringArrayContainsCriterion extends LikeExpression {
    2.     public GenericStringArrayContainsCriterion(String propertyName, String value) {
    3.         super(propertyName, "% "+WhitespaceEscapeUtil.escape(value) + " %")
    4.     }
    5. }
    Clear business that implementation through like is not very effective from the point of view of productivity. For optimization purposes, we will write the same thing using the capabilities of PostgreSQL 8.x.
    1. publicclass PostgresStringArrayContainsCriterion implements Criterion {
    2.  
    3.     privatefinal String propertyName;
    4.     privatefinal String value;
    5.  
    6.     privatefinal String TEMPLATE = "to_tsvector('simple', {column}) @@ plainto_tsquery('simple', ?)";
    7.     privatestaticfinalchar TAG_SEPARATOR = ' ';
    8.  
    9.     public PostgresStringArrayContainsCriterion(String propertyName, String value) {
    10.         this.propertyName = propertyName;
    11.         this.value = WhitespaceEscapeUtil.escape(value);
    12.     }
    13.  
    14.     public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
    15.         return StringHelper.replace(TEMPLATE, "{column}", criteriaQuery.getColumn(criteria, propertyName));
    16.     }
    17.  
    18.     public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
    19.         returnnew TypedValue[]{new TypedValue(Hibernate.STRING, value, EntityMode.POJO)};
    20.     }
    21. }
    And using the “strategy” template, we will choose the implementation depending on the current dialect:
    1. publicclass StringArrayContainsCriterion implements Criterion {
    2.      
    3.     privatefinal String propertyName;
    4.     privatefinal String value;
    5.  
    6.      
    7.     public StringArrayContainsCriterion(String propertyName, String value) {
    8.         this.propertyName = propertyName;
    9.         this.value = value;
    10.     }
    11.  
    12.     public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
    13.         return getStrategy(criteriaQuery.getFactory().getDialect()).toSqlString(criteria, criteriaQuery);
    14.     }
    15.  
    16.     public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
    17.         return getStrategy(criteriaQuery.getFactory().getDialect()).getTypedValues(criteria, criteriaQuery);
    18.     }
    19.    
    20.     public Criterion getStrategy(Dialect dialect) {
    21.         if (dialect instanceof PostgreSQLDialect) {
    22.             returnnew PostgresStringArrayContainsCriterion(propertyName, value);
    23.         } else {
    24.             returnnew GenericStringArrayContainsCriterion(propertyName, value);
    25.         }    
    26.     }    
    27. }
    28.  


    Well, that's all. Now we can save and filter custom types.

    ______________________
    The text is prepared in the Blog Editor by © SoftCoder.ru

    Also popular now: