Using “join fetch” together with getResultStream delivers incomplete entities (multiplie times) depending on the order of the db result rows. How to reproduce Setup: Entites:
@Getter
@Setter
@Entity
@Table(name = "notification_list")
@ToString
public class NotificationListEntity {
@Id
@Column(name = "id")
private UUID id;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "notificationList")
private Set<RoomEntity> roomIds;
}
@Getter
@Setter
@Entity
@Table(name = "notification_list_room")
@ToString
public class RoomEntity {
@Id
@Column(name = "room_id")
UUID roomId;
@ManyToOne
@JoinColumn(name = "notification_list_id")
@ToString.Exclude
NotificationListEntity notificationList;
}
Prefill the db with:
insert into notification_list (id, name) values ('99006f27-a59f-491f-b7f8-7e83b8fc02b0', 'A');
insert into notification_list (id, name) values ('d5d3bbcc-1c00-4aa5-af80-4ecd2aedfb99', 'B');
insert into notification_list (id, name) values ('73af7a07-1a6b-4f65-b77f-ab1613e7849d', 'C');
insert into notification_list_room (notification_list_id, room_id) values ('99006f27-a59f-491f-b7f8-7e83b8fc02b0', '8f2890bb-79ef-4b09-9f04-1d1a2024cfe1');
insert into notification_list_room (notification_list_id, room_id) values ('99006f27-a59f-491f-b7f8-7e83b8fc02b0', 'ec7f587d-13c7-4f1f-105d-312ee5d655e8');
insert into notification_list_room (notification_list_id, room_id) values ('d5d3bbcc-1c00-4aa5-af80-4ecd2aedfb99', '31197476-222e-47ef-87e2-4f0fefb0b97a');
insert into notification_list_room (notification_list_id, room_id) values ('99006f27-a59f-491f-b7f8-7e83b8fc02b0', '92b12b36-8c00-4951-10db-263facfcb214');
insert into notification_list_room (notification_list_id, room_id) values ('73af7a07-1a6b-4f65-b77f-ab1613e7849d', 'd3acc6a1-e223-421d-a135-4142f159d548');
insert into notification_list_room (notification_list_id, room_id) values ('99006f27-a59f-491f-b7f8-7e83b8fc02b0', 'b0b12a45-0e1b-4b0d-9fb1-fab948835605');
insert into notification_list_room (notification_list_id, room_id) values ('99006f27-a59f-491f-b7f8-7e83b8fc02b0', '8be1d3b3-2f1d-48b2-9982-77814003ce97');
insert into notification_list_room (notification_list_id, room_id) values ('99006f27-a59f-491f-b7f8-7e83b8fc02b0', 'df2ba159-92b5-4e78-1008-b181e5406a91');
Methods:
public List<NotificationListEntity> streamAll() {
return entityManager
.createQuery(
"""
SELECT nle FROM NotificationListEntity nle
JOIN fetch nle.roomIds
""",
NotificationListEntity.class)
.getResultStream();
}
public List<NotificationListEntity> listAll() {
return entityManager
.createQuery(
"""
SELECT nle FROM NotificationListEntity nle
JOIN fetch nle.roomIds
""",
NotificationListEntity.class)
.getResultList();
}
Result: Calling the “listAll()” delivers correct entities:
Calling the “streamAll()” delivers wrong entities:
When adding a “order by nle.id” it also works correctly with the steam. So the getResultStream should somehow handle this correctly or warn that fetch is not allowed. |