[
https://issues.apache.org/jira/browse/CAY-2879?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17923221#comment-17923221
]
lallemand commented on CAY-2879:
--------------------------------
Thanks for the fix and the information.
I might have mixed up versions, but from what I remember, it was previously
impossible to upgrade Tomcat from version 9 to version 10 because Cayenne was
returning old Java EE Faces instead of Jakarta Faces. This caused our product
to be incompatible with Tomcat 10, which was a requirement from a customer.
This was without using the JAR provided by Tomcat that allows translating a WAR
from version 9 to 10.
I would need to delve into it again to provide more specifics on the issue.
> 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
> Assignee: Nikita Timofeev
> Priority: Major
> 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)