r3056 - in trunk/topia-persistence/src: main/java/org/nuiton/topia/persistence test/java/org/nuiton/topia/persistence
Author: tchemit Date: 2014-04-09 15:47:26 +0200 (Wed, 09 Apr 2014) New Revision: 3056 Url: http://forge.nuiton.org/projects/topia/repository/revisions/3056 Log: fixes #3143: HqlAndParameterBuilder.addWhereClause fails because of parameters collision Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/HqlAndParametersBuilder.java trunk/topia-persistence/src/test/java/org/nuiton/topia/persistence/HqlAndParametersBuilderTest.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-04-08 15:36:22 UTC (rev 3055) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/persistence/HqlAndParametersBuilder.java 2014-04-09 13:47:26 UTC (rev 3056) @@ -201,11 +201,30 @@ public void addWhereClause(String whereClause, Map<String, Object> hqlParameters) { Preconditions.checkNotNull(hqlParameters); - boolean noCollision = Sets.intersection(parameters.keySet(), hqlParameters.keySet()).isEmpty(); - Preconditions.checkArgument(noCollision, "given arguments " + hqlParameters.keySet() + " contains a conflicting name with the already defined parameters of the query (" + parameters.keySet() + "). You should changes the names of given arguments."); + Set<String> collisiontParameterNames = Sets.newHashSet(Sets.intersection(parameters.keySet(), hqlParameters.keySet())); + boolean noCollision = collisiontParameterNames.isEmpty(); + if (noCollision) { + parameters.putAll(hqlParameters); + } else { + + // add all parameters with no collision + Set<String> noCollisiontParameterNames = Sets.difference(hqlParameters.keySet(), collisiontParameterNames); + for (String parameterName : noCollisiontParameterNames) { + Object parameterValue = hqlParameters.get(parameterName); + parameters.put(parameterName, parameterValue); + } + // resolve all collision parameters + for (String parameterName : collisiontParameterNames) { + Object parameterValue = hqlParameters.get(parameterName); + + // resolved parameter name + String newParameterName = putHqlParameterWithAvailableName(parameterName, parameterValue); + + // replace the :parameterName (with no next alphanumeric caracter) + whereClause = whereClause.replaceAll(":" + parameterName + "(?!\\w)", ":" + newParameterName); + } + } addWhereClause(whereClause); - // FIXME brendan 25/03/14 use putHqlParameterWithAvailableName to prevent conflict - parameters.putAll(hqlParameters); } public void setWhereClauses(Set<String> whereClauses) { Modified: trunk/topia-persistence/src/test/java/org/nuiton/topia/persistence/HqlAndParametersBuilderTest.java =================================================================== --- trunk/topia-persistence/src/test/java/org/nuiton/topia/persistence/HqlAndParametersBuilderTest.java 2014-04-08 15:36:22 UTC (rev 3055) +++ trunk/topia-persistence/src/test/java/org/nuiton/topia/persistence/HqlAndParametersBuilderTest.java 2014-04-09 13:47:26 UTC (rev 3056) @@ -31,6 +31,7 @@ import java.util.Collection; import java.util.Collections; +import java.util.Map; public class HqlAndParametersBuilderTest { @@ -131,21 +132,34 @@ public void testPreventRemoveParameters() { ImmutableMap<String, String> hqlParameters = - ImmutableMap.of("myParameter1", "aRandomValue"); + ImmutableMap.of("myParameter", "aRandomValue", + "myParameter1", "aRandomValue1", + "myParameter2", "aRandomValue2"); ImmutableMap<String, String> conflictingHqlParameters = - ImmutableMap.of("myParameter1", "anotherRandomValue"); + ImmutableMap.of("myParameter", "anotherRandomValue", + "myParameter1", "anotherRandomValue1", + "myParameter2", "anotherRandomValue2", + "myParameter20", "aSafeValue"); - hqlAndParametersBuilder.addWhereClause("myProperty = :myParameter1", hqlParameters); + hqlAndParametersBuilder.addWhereClause("myProperty = :myParameter, myProperty = :myParameter1, myProperty2 = :myParameter2||", hqlParameters); - try { - hqlAndParametersBuilder.addWhereClause("myOtherProperty = :myParameter1", conflictingHqlParameters); - Assert.fail("an exception should have been raised"); - } catch (IllegalArgumentException e) { - Assert.assertTrue( - "the exception message must contains the conflicting argument name", - e.getMessage().contains("myParameter1")); - } + hqlAndParametersBuilder.addWhereClause("myOtherProperty = :myParameter, myOtherProperty1 = :myParameter1, myOtherProperty2 = :myParameter2, myOtherProperty20 = :myParameter20", conflictingHqlParameters); + Map hqlParameters1 = hqlAndParametersBuilder.getHqlParameters(); + String hql = hqlAndParametersBuilder.getHql(); + Assert.assertEquals(7, hqlParameters1.size()); + Assert.assertEquals("aRandomValue", hqlParameters1.get("myParameter")); + Assert.assertEquals("aRandomValue1", hqlParameters1.get("myParameter1")); + Assert.assertEquals("aRandomValue2", hqlParameters1.get("myParameter2")); + Assert.assertEquals("aSafeValue", hqlParameters1.get("myParameter20")); + Assert.assertEquals("anotherRandomValue", hqlParameters1.get("myParameter0")); // myParameter resolved + Assert.assertEquals("anotherRandomValue1", hqlParameters1.get("myParameter10")); // myParameter1 resolved + Assert.assertEquals("anotherRandomValue2", hqlParameters1.get("myParameter21")); // myParameter2 resolved + + // first sql (not modified) + Assert.assertTrue(hql.contains("myProperty = :myParameter, myProperty = :myParameter1, myProperty2 = :myParameter2||")); + // second sql (with resolved properties) + Assert.assertTrue(hql.contains("myOtherProperty = :myParameter0, myOtherProperty1 = :myParameter10, myOtherProperty2 = :myParameter21, myOtherProperty20 = :myParameter20")); } }
participants (1)
-
tchemit@users.nuiton.org