lallemand created CAY-2879:
------------------------------
Summary: Negative number for non parameterized ObjectSelect query
not processed correctly
Key: CAY-2879
URL: https://issues.apache.org/jira/browse/CAY-2879
Project: Cayenne
Issue Type: Bug
Components: Core Library
Affects Versions: 4.2.1
Environment: Windows 11 Java 17
Reporter: lallemand
Fix For: 4.2.2
*Description:*
Since upgrading from {*}4.1.1 to 4.2.1{*}, negative numbers are no longer
processed correctly when executing queries. The issue occurs in
{*}performQuery{*}, where negative values are unexpectedly converted into their
positive counterparts.
----
*Affected Code:*
{code:java}
public static RiskScoreTemplate getForName(String pm_name, String pm_zoneId)
{
ObjectSelect<RiskScoreTemplate> query =
ObjectSelect.query(RiskScoreTemplate.class,
ExpressionFactory.exp(NAME.getName() + " = '" + pm_name + "' and " +
DELETED.getName() + " = 0 and " + ZONE.getName() + " = " + pm_zoneId));
//query.setName("RiskScoreTemplateListQuery");
query.setCacheStrategy(QueryCacheStrategy.NO_CACHE);
ObjectContext context = BaseContext.getThreadObjectContext();
List<?> items = context.performQuery(query);
return (!items.isEmpty()) ? (RiskScoreTemplate)items.get(0) : null;
}{code}
*Generated SQL Query:*
{{}}
{code:java}
exec sp_executesql N'SELECT t0.application_id, t0.deleted, t0.last_update,
t0.name, t0.type, t0.zone_id, t0.id FROM dbo.tRiskScoreTemplate t0 WHERE (
t0.name = @P0 ) AND ( t0.deleted = @P1 ) AND ( t0.zone_id = ( @P2 ) )', N'@P0
nvarchar(4000),@P1 int,@P2 int', N'SYSTEM', 0, 1{code}
{{}}
*Function Input Values:*
{{}}
{code:java}
pm_name = SYSTEM
pm_zoneId = -1
{code}
{{}}
----
*Issue:*
Since version {*}4.2.1{*}, the negative value *pm_zoneId = -1* is being
converted to a *positive value (1)* when the query is executed. This results in
incorrect query results.
----
*Workaround:*
Using a parameterized query prevents the issue, as shown in the following
corrected code:
{{}}
{code:java}
public static RiskScoreTemplate getForName(String pm_name, String pm_zoneId)
{
Map<String, Object> parameters = new HashMap<>();
parameters.put("name", pm_name);
parameters.put("deleted", 0);
parameters.put("zone_id", new BigInteger(pm_zoneId));
ObjectSelect<RiskScoreTemplate> query =
ObjectSelect.query(RiskScoreTemplate.class,
ExpressionFactory.exp(NAME.getName() + " = $name and " + DELETED.getName() + "
= $deleted and " + ZONE.getName() + " = $zone_id").params(parameters));
//query.setName("RiskScoreTemplateListQuery");
query.setCacheStrategy(QueryCacheStrategy.NO_CACHE);
ObjectContext context = BaseContext.getThreadObjectContext();
List<?> items = context.performQuery(query);
return (!items.isEmpty()) ? (RiskScoreTemplate)items.get(0) : null;
} {code}
{{}}
While the solution above correctly handles negative values, our application
contains approximately *2,200 queries* that use the legacy implementation.
Since this method is still supported in the current version, the unexpected
behavior should be investigated and fixed rather than requiring a full
migration.
----
*Expected Behavior:*
* Queries using the legacy approach should continue to handle negative values
correctly, as they did in version {*}4.1.1{*}.
* Negative numbers should not be converted to positive values during
*performQuery* execution.
*Steps to Reproduce:*
# Use the original query method from version {*}4.1.1{*}.
# Pass a negative value for {{pm_zoneId}} (e.g., {{{}-1{}}}).
# Observe that the generated SQL query incorrectly converts {{-1}} to
{{{}1{}}}.
# Compare behavior with {*}4.1.1{*}, where negative values were preserved.
*Impact:*
* The issue affects *2,200+ queries* in our application, leading to incorrect
database results.
* Migration to parameterized queries would require significant refactoring.
* Potential data integrity and filtering issues.
*Suggested Fix:*
* Investigate changes in *4.2.1* related to {{performQuery}} and numeric value
handling.
* Ensure that the legacy query method correctly preserves negative values.
* If necessary, provide a configuration option to enforce legacy behavior
until a full migration is feasible.
* Investigate why ASTNegate node are incorrectly processed although expression
has identified it correctly.
----
*Additional Notes:*
* If a fix cannot be provided in a timely manner, documentation should clearly
state that legacy queries are no longer reliable for handling negative values.
* Any workarounds should be suggested to developers who are unable to migrate
immediately.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)