addIn(property, <collection vide>) ?
On a eu des soucis récemment sur l'ENC avec PostreSQL. Notamment, on a dû faire ceci (cf commit ci-dessous) : addInOrNotIn(String property, Collection<?> values) { Preconditions.checkArgument(StringUtils.isNotEmpty(property)); Preconditions.checkNotNull(values); String aliasedProperty = alias + "." + property; int valuesSize = values.size(); if (valuesSize == 0) { if (in) { whereClauses.add(" 0 = 1 "); } else { whereClauses.add(" 1 = 1 "); } } C'est à dire faire un trick pour quand la collection passé en paramètre en vide. Pour moi, il y une grouille dans Hibernate qui ne dit rien alors qu'on passe une collection vide et que ça n'a pas l'air de le gêner. En plus, le dialecte hibernate pour PG génère bien xxx in () et il est content... alors que ça pète une syntax error. Selon vous, que faut-il faire, laisser ce hack dans topia ? Interdire de passer une collection vide en paramètre ? Autre chose ? -------- Message original -------- Sujet: [Topia-commits] r3026 - trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence Date : Thu, 27 Feb 2014 14:56:35 +0100 (CET) De : bleny@users.nuiton.org Répondre à : topia-commits@list.nuiton.org Pour : topia-commits@list.nuiton.org Author: bleny Date: 2014-02-27 14:56:34 +0100 (Thu, 27 Feb 2014) New Revision: 3026 Url: http://nuiton.org/projects/topia/repository/revisions/3026 Log: fixes #3101 redo 'x is null or x in (...)' instead of 'x in (NULL)', remove useless braces when a single where clause is present Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/HqlAndParametersBuilder.java Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/HqlAndParametersBuilder.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/HqlAndParametersBuilder.java 2014-02-27 12:30:37 UTC (rev 3025) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/HqlAndParametersBuilder.java 2014-02-27 13:56:34 UTC (rev 3026) @@ -25,6 +25,7 @@ */ import com.google.common.base.Preconditions; +import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.apache.commons.collections4.CollectionUtils; @@ -100,31 +101,52 @@ } public void addIn(String property, Collection<?> values) { - Preconditions.checkArgument(StringUtils.isNotEmpty(property)); - Preconditions.checkNotNull(values); - // TODO brendan 02/10/13 if value is instanceof TopiaEntity, we can check type - // TODO brendan 02/10/13 do not use HQL parameters of Object are primitive - if (values.isEmpty()) { - whereClauses.add(" 1 = 0 "); - } else { - String aliasedProperty = alias + "." + property; - String hqlParameterName = putHqlParameterWithAvailableName(property, values); - String whereClause = String.format(" %s IN ( :%s ) ", aliasedProperty, hqlParameterName); - whereClauses.add(whereClause); - } + addInOrNotIn(property, values, true); } public void addNotIn(String property, Collection<?> values) { + addInOrNotIn(property, values, false); + } + + /** + * @param in true if property value must be in given collection, false if value must not be in given collection + */ + protected void addInOrNotIn(String property, Collection<?> values, boolean in) { Preconditions.checkArgument(StringUtils.isNotEmpty(property)); Preconditions.checkNotNull(values); // TODO brendan 02/10/13 if value is instanceof TopiaEntity, we can check type - // TODO brendan 02/10/13 do not use HQL parameters of Object are primitive - if (values.isEmpty()) { - whereClauses.add(" 1 = 1 "); + String aliasedProperty = alias + "." + property; + int valuesSize = values.size(); + if (valuesSize == 0) { + // XXX brendan 27/02/14 workaround to prevent generating "in ()" which in not supported by PostegreSQL (syntax error) + if (in) { + whereClauses.add(" 0 = 1 "); + } else { + whereClauses.add(" 1 = 1 "); + } + } else if (valuesSize == 1) { + // if there is only one possible value, replace "in" clause by a "=" clause + Object onlyElement = Iterables.getOnlyElement(values); + if (in) { + addEquals(property, onlyElement); + } else { + addNotEquals(property, onlyElement); + } } else { - String aliasedProperty = alias + "." + property; + boolean propertyMayBeNull = values.contains(null); String hqlParameterName = putHqlParameterWithAvailableName(property, values); - String whereClause = String.format(" %s NOT IN ( :%s ) ", aliasedProperty, hqlParameterName); + String whereClause; + if (in) { + whereClause = String.format(" %s in ( :%s ) ", aliasedProperty, hqlParameterName); + if (propertyMayBeNull) { + whereClause += " or " + aliasedProperty + " is null"; + } + } else { + whereClause = String.format(" %s not in ( :%s ) ", aliasedProperty, hqlParameterName); + if (propertyMayBeNull) { + whereClause += " and " + aliasedProperty + " is not null"; + } + } whereClauses.add(whereClause); } } @@ -198,7 +220,10 @@ public String getHql() { StringBuilder hqlStringBuilder = new StringBuilder(); hqlStringBuilder.append("from ").append(entityClass.getCanonicalName()).append(" ").append(alias); - if (!whereClauses.isEmpty()) { + if (whereClauses.size() == 1) { + String whereClause = Iterables.getOnlyElement(whereClauses); + hqlStringBuilder.append(" where ").append(whereClause); + } else if (!whereClauses.isEmpty()) { hqlStringBuilder.append(" where (").append(StringUtils.join(whereClauses, ") and (")).append(")"); } if (CollectionUtils.isNotEmpty(orderByArguments)) { _______________________________________________ Topia-commits mailing list Topia-commits@list.nuiton.org http://list.nuiton.org/cgi-bin/mailman/listinfo/topia-commits
participants (1)
-
Brendan Le Ny