[ 
https://issues.apache.org/jira/browse/CAY-2895?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

lallemand updated CAY-2895:
---------------------------
     Attachment: image-2025-09-15-14-02-55-828.png
                 image-2025-09-15-14-00-38-120.png
    Description: 
Dears,

 

In the latest stable version ({*}4.2.2{*}), we are encountering an issue with 
the *Lazy implementation* based on {{ObjectSelect<T>.pageSize()}} when the 
table’s *primary key* is of type {*}BIGINT{*}.

 
----
*Steps to Reproduce:*
 # Use {{ObjectSelect<T>}} with pagination ({{{}pageSize{}}}) on a table where 
the primary key column is of type {*}BIGINT{*}.
 # Allow the {{IncrementalFaultList}} in *cayenne-server* to populate elements.
 # Insert a new item into the dataset.

----
*Technical Details:*
 * The issue occurs in {*}{{IncrementalFaultList.class}}{*}, specifically 
within the {{fillIn}} method, which initializes {{{}protected final List 
elements{}}}.

 * When processing a *BIGINT* database PK mapping, the type defaults to 
{*}{{Long}}{*}.

 * This works fine until a new item is added. At that point, the method 
{{updateWithResolvedObjectInRange}} is called, which in turn calls 
{{replacesObject}} (for one of six implementations).

In our case, the class *{{SimpleIdIncrementalFaultList}}* is used.

Example:
 * {{objectInTheList}} → value: {{{}137{}}}, type: *Long*

 * {{idSnapshot.get(pk.getName())}} → value: {{{}137{}}}, type: *BigInteger*

*!image-2025-09-01-14-24-18-956.png!*

Because of the type mismatch, the comparison fails, leading to the following 
exception:
!image-2025-09-01-14-24-41-442.png!
As a result, the list contains a *Long* object instead of the expected 
*ObjEntity* inside our lazy implementation{*}.{*}
----
*Proposed Fix / Workaround:*

I modified the {{replacesObject}} method to handle *BigInteger* correctly.

!image-2025-09-01-14-26-02-296.png!
 * *First modification (blue section in my test code):*
_Not recommended._ This forces replacement regardless of match. I added it only 
to bypass an unrelated bug I observed occasionally. This may indicate a deeper 
issue in the pagination implementation that requires further investigation.

 * *Second modification (red section in my test code):*
_Required for correctness._ This ensures that *BigInteger* primary keys are 
compared properly with Long values.
While this fix works, I believe a more elegant solution should exist within 
Cayenne’s type handling logic.

----
*Test Configuration:*
 * *Databases:*

Oracle 

!image-2025-09-01-14-26-35-313.png!

SQL Server

!image-2025-09-01-14-26-45-722.png!
 * *Entities:*

{{DbEntity}}

!image-2025-09-01-14-27-12-756.png!

ObjEntity !image-2025-09-01-14-27-27-432.png!
----
*Impact:*

This is a {*}critical issue{*}: pagination becomes completely unusable when the 
primary key is of type {*}BIGINT{*}.
----
*Edit 1:*

I’ve discovered that the result of this function can sometimes be inconsistent 
if not enough time is allowed for it to complete. This behavior seems to be the 
root cause of the issue highlighted in blue in my previous review.

!image-2025-09-15-14-00-38-120.png!

Called by 

!image-2025-09-15-14-02-55-828.png!

When I introduce a slight slowdown in the code execution, the behavior appears 
more stable during the first load. This is related to the issue “First 
modification (highlighted in blue in my test code)" section.

My environment:
 * Arch Linux

 * Containerized databases (Oracle / SQL Server)

The problem seems to be that the execution is sometimes “too fast,” which leads 
to certain items not being matched during the initial load. I’ve spent hours 
debugging but haven’t been able to identify the exact culprit. The only 
reliable observation so far is that slowing execution slightly improves 
stability (though this is clearly not a recommended fix).

This suggests there may be an underlying timing, synchronization, async or 
readiness issue. Further investigation into the root cause would be helpful.

 

*Best regards,*

Anton L.

  was:
Dears,

 

In the latest stable version ({*}4.2.2{*}), we are encountering an issue with 
the *Lazy implementation* based on {{ObjectSelect<T>.pageSize()}} when the 
table’s *primary key* is of type {*}BIGINT{*}.

 
----
*Steps to Reproduce:*
 # Use {{ObjectSelect<T>}} with pagination ({{{}pageSize{}}}) on a table where 
the primary key column is of type {*}BIGINT{*}.
 # Allow the {{IncrementalFaultList}} in *cayenne-server* to populate elements.
 # Insert a new item into the dataset.

----
*Technical Details:*
 * The issue occurs in {*}{{IncrementalFaultList.class}}{*}, specifically 
within the {{fillIn}} method, which initializes {{{}protected final List 
elements{}}}.

 * When processing a *BIGINT* database PK mapping, the type defaults to 
{*}{{Long}}{*}.

 * This works fine until a new item is added. At that point, the method 
{{updateWithResolvedObjectInRange}} is called, which in turn calls 
{{replacesObject}} (for one of six implementations).

In our case, the class *{{SimpleIdIncrementalFaultList}}* is used.

Example:
 * {{objectInTheList}} → value: {{{}137{}}}, type: *Long*

 * {{idSnapshot.get(pk.getName())}} → value: {{{}137{}}}, type: *BigInteger*

*!image-2025-09-01-14-24-18-956.png!*

Because of the type mismatch, the comparison fails, leading to the following 
exception:
!image-2025-09-01-14-24-41-442.png!
As a result, the list contains a *Long* object instead of the expected 
*ObjEntity* inside our lazy implementation{*}.{*}
----
*Proposed Fix / Workaround:*

I modified the {{replacesObject}} method to handle *BigInteger* correctly.

!image-2025-09-01-14-26-02-296.png!
 * *First modification (blue section in my test code):*
_Not recommended._ This forces replacement regardless of match. I added it only 
to bypass an unrelated bug I observed occasionally. This may indicate a deeper 
issue in the pagination implementation that requires further investigation.

 * *Second modification (red section in my test code):*
_Required for correctness._ This ensures that *BigInteger* primary keys are 
compared properly with Long values.
While this fix works, I believe a more elegant solution should exist within 
Cayenne’s type handling logic.

----
*Test Configuration:*
 * *Databases:*

Oracle 

!image-2025-09-01-14-26-35-313.png!

SQL Server

!image-2025-09-01-14-26-45-722.png!
 * *Entities:*

{{DbEntity}}

!image-2025-09-01-14-27-12-756.png!

ObjEntity !image-2025-09-01-14-27-27-432.png!
----
*Impact:*

This is a {*}critical issue{*}: pagination becomes completely unusable when the 
primary key is of type {*}BIGINT{*}.
----
 

*Best regards,*

Anton L.


> Incorrect Lazy Pagination Comparison for BigInteger PK
> ------------------------------------------------------
>
>                 Key: CAY-2895
>                 URL: https://issues.apache.org/jira/browse/CAY-2895
>             Project: Cayenne
>          Issue Type: Bug
>          Components: Core Library
>    Affects Versions: 4.2.2
>            Reporter: lallemand
>            Priority: Critical
>             Fix For: 4.2.3, 5.0-M2
>
>         Attachments: image-2025-09-01-14-24-18-956.png, 
> image-2025-09-01-14-24-41-442.png, image-2025-09-01-14-26-02-296.png, 
> image-2025-09-01-14-26-35-313.png, image-2025-09-01-14-26-45-722.png, 
> image-2025-09-01-14-27-06-177.png, image-2025-09-01-14-27-12-756.png, 
> image-2025-09-01-14-27-27-432.png, image-2025-09-15-14-00-38-120.png, 
> image-2025-09-15-14-02-55-828.png
>
>
> Dears,
>  
> In the latest stable version ({*}4.2.2{*}), we are encountering an issue with 
> the *Lazy implementation* based on {{ObjectSelect<T>.pageSize()}} when the 
> table’s *primary key* is of type {*}BIGINT{*}.
>  
> ----
> *Steps to Reproduce:*
>  # Use {{ObjectSelect<T>}} with pagination ({{{}pageSize{}}}) on a table 
> where the primary key column is of type {*}BIGINT{*}.
>  # Allow the {{IncrementalFaultList}} in *cayenne-server* to populate 
> elements.
>  # Insert a new item into the dataset.
> ----
> *Technical Details:*
>  * The issue occurs in {*}{{IncrementalFaultList.class}}{*}, specifically 
> within the {{fillIn}} method, which initializes {{{}protected final List 
> elements{}}}.
>  * When processing a *BIGINT* database PK mapping, the type defaults to 
> {*}{{Long}}{*}.
>  * This works fine until a new item is added. At that point, the method 
> {{updateWithResolvedObjectInRange}} is called, which in turn calls 
> {{replacesObject}} (for one of six implementations).
> In our case, the class *{{SimpleIdIncrementalFaultList}}* is used.
> Example:
>  * {{objectInTheList}} → value: {{{}137{}}}, type: *Long*
>  * {{idSnapshot.get(pk.getName())}} → value: {{{}137{}}}, type: *BigInteger*
> *!image-2025-09-01-14-24-18-956.png!*
> Because of the type mismatch, the comparison fails, leading to the following 
> exception:
> !image-2025-09-01-14-24-41-442.png!
> As a result, the list contains a *Long* object instead of the expected 
> *ObjEntity* inside our lazy implementation{*}.{*}
> ----
> *Proposed Fix / Workaround:*
> I modified the {{replacesObject}} method to handle *BigInteger* correctly.
> !image-2025-09-01-14-26-02-296.png!
>  * *First modification (blue section in my test code):*
> _Not recommended._ This forces replacement regardless of match. I added it 
> only to bypass an unrelated bug I observed occasionally. This may indicate a 
> deeper issue in the pagination implementation that requires further 
> investigation.
>  * *Second modification (red section in my test code):*
> _Required for correctness._ This ensures that *BigInteger* primary keys are 
> compared properly with Long values.
> While this fix works, I believe a more elegant solution should exist within 
> Cayenne’s type handling logic.
> ----
> *Test Configuration:*
>  * *Databases:*
> Oracle 
> !image-2025-09-01-14-26-35-313.png!
> SQL Server
> !image-2025-09-01-14-26-45-722.png!
>  * *Entities:*
> {{DbEntity}}
> !image-2025-09-01-14-27-12-756.png!
> ObjEntity !image-2025-09-01-14-27-27-432.png!
> ----
> *Impact:*
> This is a {*}critical issue{*}: pagination becomes completely unusable when 
> the primary key is of type {*}BIGINT{*}.
> ----
> *Edit 1:*
> I’ve discovered that the result of this function can sometimes be 
> inconsistent if not enough time is allowed for it to complete. This behavior 
> seems to be the root cause of the issue highlighted in blue in my previous 
> review.
> !image-2025-09-15-14-00-38-120.png!
> Called by 
> !image-2025-09-15-14-02-55-828.png!
> When I introduce a slight slowdown in the code execution, the behavior 
> appears more stable during the first load. This is related to the issue 
> “First modification (highlighted in blue in my test code)" section.
> My environment:
>  * Arch Linux
>  * Containerized databases (Oracle / SQL Server)
> The problem seems to be that the execution is sometimes “too fast,” which 
> leads to certain items not being matched during the initial load. I’ve spent 
> hours debugging but haven’t been able to identify the exact culprit. The only 
> reliable observation so far is that slowing execution slightly improves 
> stability (though this is clearly not a recommended fix).
> This suggests there may be an underlying timing, synchronization, async or 
> readiness issue. Further investigation into the root cause would be helpful.
>  
> *Best regards,*
> Anton L.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to