-
-
Notifications
You must be signed in to change notification settings - Fork 260
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Duplicated entities in findMany when a ManyToOne relation is fetched (Postgresql) #3466
Comments
Ok, that sucks. I presume you have added in an orderBy clause at this stage for a workaround. |
Are you able to produce some sort of test case? Or the query with the issue? Ideally with the SQL generated? As in, a ManyToOne [or OneToOne] only produces one [or none] rows for the join ... so I'm thinking there must have also been a ToMany involved in the query? |
So looking at this again, I think we need more information.
ManyToOne relationship is fetched using a join on the root query, ebean
handles the deduplication
This is not quite the correct diagnosis. That ordering on the root level
beans is relevant when there are ToMany paths included in the query [and we
have not yet seen that] ... so I suspect there is some other issue here.
…On Sun, 1 Sept 2024, 1:37 am Arnaud Pflieger, ***@***.***> wrote:
Expected behavior
When a ManyToOne relationship is fetched using a join on the root query,
ebean handles the deduplication of the rows so Finder.query().findList()
returns uniques entities by their ids. This is done here
https://github.com/ebean-orm/ebean/blob/master/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java#L433
(I spent some time to debug this)
This code assumes that rows with the same root id avec grouped. But... I
have a case where postgres doesn't respect that.
Actual behavior
findList() returns duplicated entities is such case.
I narrowed down the request done by ebean:
select a.id,
t4.id,
p.idfrom attendance a
left join ticket t4 on t4.id = a.ticket_id
left join payment p on p.ticket_id = t4.idwhere (teacher_amount > 0 and transfer_method = 'UNDEFINED')
And postgres returns this:
Capture.d.ecran.2024-08-31.a.15.27.44.png (view on web)
<https://github.com/user-attachments/assets/69f4c85e-433a-41bf-8561-b122c398473c>
Versions
We use Postgresql 16.4
Ebean 15.5.0
Some context
This problem appeared suddenly, I can't find what triggered it. We didn't
upgrade postgres around these dates nor Ebean...
It is actually quite critical, it messed up or payment system, customers
got billed multiple times for the same item 😬
—
Reply to this email directly, view it on GitHub
<#3466>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABTATOGBWVF6EZNVZD4VIDZUHBJ3AVCNFSM6AAAAABNN4LNIGVHI2DSMVQWIX3LMV43ASLTON2WKOZSGQ4TQOBUHE4TEMI>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Right, it's a ToMany that is eagerly fetched. Here are the entities concerned: class Ticket {
@OneToMany
private List<Payment> payments;
} This is the query. (The fetch group is a bit more complex because there are more ToOne paths new Finder<>(Attendance.class).query()
.select(FetchGroup.of(Attendance.class)
.fetch("ticket", FetchGroup.of(Ticket.class)
.fetch("payments", FetchGroup.of(Payment.class)
.build())
.build())
.build())
.where()
.and()
.gt("teacher_amount", 0)
.eq("transfer_method", EPaymentMethod.UNDEFINED)
.endAnd()
.findList(); The SQL generated is what I wrote in the first message. I just removed many columns and the other ToOne joins. There's no ordering. It's like Postgres changed the ordering suddenly. |
When there is a ToMany path, Ebean should automatically add an orderBy clause if one is not already defined, and if one is defined it will check that it includes the That is, we should see an The internal code that does this is the There are a couple of odd things in the query above.
Instead I would expect to see:
|
Definitely a bug here though ... |
Noted for the column names. I'll debug a bit more with this in mind. Thank you. |
Postgres ordering could've been changed due to a different SQL plan triggering. Anyway, yes, sounds like Ebean bug. SQL without "order by" of course doesn't guarantee any order. @rbygrave I think FetchGroup usage that @apflieger provided here is just an expanded version for the sake of this ticket. Likely they instead reference it by |
Yes.
If I understand the code correctly, this behaviour seems to consider ToMany relationships only on the root entity of the query. In my case, it's not on the root. We have Attendance -> ToOne ticket -> ToMany Payment. Thus |
…fetched (Postgresql) Internally in OrmQueryDetail.markQueryJoins() the SpiQueryManyJoin is determined and returned. This change uses this and effectively removes the code from OrmQueryRequest.determineMany() and BeanDescriptor.manyProperty() which was the source of this issue (performing a similar task but not correctly taking the full path into account and hence the source of this bug).
#3466 - Duplicated entities in findMany when a ManyToOne relation is fetched
That was quick. Thank you very much |
Yes, you were understanding that all correctly etc. Good stuff!! |
Expected behavior
When a ManyToOne relationship is fetched using a join on the root query, ebean handles the deduplication of the rows so
Finder.query().findList()
returns uniques entities by their ids. This is done here https://github.com/ebean-orm/ebean/blob/master/ebean-core/src/main/java/io/ebeaninternal/server/query/CQuery.java#L433 (I spent some time to debug this)This code assumes that rows with the same root id avec grouped. But... I have a case where postgres doesn't respect that.
Actual behavior
findList()
returns duplicated entities is such case.I narrowed down the request done by ebean:
And postgres returns this:
Versions
We use Postgresql 16.4
Ebean 15.5.0
Some context
This problem appeared suddenly, I can't find what triggered it. We didn't upgrade postgres around these dates nor Ebean...
It is actually quite critical, it messed up our payment system, customers got billed multiple times for the same item 😬
The text was updated successfully, but these errors were encountered: