英文:
Will accessing an element within a list annotated with @LazyCollection(LazyCollectionOption.EXTRA) cause initializing the entire list?
问题
我有以下的Chat类:
@Data
@Entity
@NoArgsConstructor
public class Chat extends BaseEntity {
@ManyToOne
@JoinColumn(name = "user1_id")
private User user1;
@ManyToOne
@JoinColumn(name = "user2_id")
private User user2;
@LazyCollection(LazyCollectionOption.EXTRA)
@OrderBy("sentAt DESC")
@OneToMany(mappedBy = "chat", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<Message> messages = new ArrayList<>();
public Chat(User user1, User user2) {
this.user1 = user1;
this.user2 = user2;
}
}
关于messages
字段,我只对访问第一个元素感兴趣,这是最新的消息在这种情况下。
执行以下语句:chat.getMessages().get(0)
会导致整个messages
列表被初始化吗?如果是的话,那么最佳实践是什么?
英文:
I have the following Chat class:
@Data
@Entity
@NoArgsConstructor
public class Chat extends BaseEntity {
@ManyToOne
@JoinColumn(name = "user1_id")
private User user1;
@ManyToOne
@JoinColumn(name = "user2_id")
private User user2;
@LazyCollection(LazyCollectionOption.EXTRA)
@OrderBy("sentAt DESC")
@OneToMany(mappedBy = "chat", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<Message> messages = new ArrayList<>();
public Chat(User user1, User user2) {
this.user1 = user1;
this.user2 = user2;
}
}
In respect of the messages
field, I am only interested in accessing the first element, -which is the latest message this case-
Would executing the following statement: chat.getMessages().get(0)
cause the entire messages
list to be initialized? If yes, then what is the best practice?
答案1
得分: 1
这种方式不起作用。
根据hibernate文档:
> LazyCollectionOption.EXTRA
仅适用于有序集合,即使用 @OrderColumn
或者 Map
注解的列表。
>
> 对于包(例如普通的不保留任何特定顺序的实体列表),@LazyCollection(LazyCollectionOption.EXTRA)
的行为与任何其他 FetchType.LAZY
集合相同(在首次访问时会完整获取集合的内容)。
从另一方面来说,根据@OrderColumn 注解的文档:
> 应该使用 OrderBy
注解来进行持久状态可见且由应用程序维护的排序。当指定了 OrderColumn
时,不使用 OrderBy
注解。
>
> 排序列必须是整数类型。 持久性提供程序在更新关联或元素集合时,维护排序列的值的连续(非稀疏)排序。第一个元素的排序列值为0。
因此,无法使用 @OrderColumn
注解按日期/时间进行排序,从而无法在第一个元素上使用 LazyCollectionOption.EXTRA
进行懒加载。
我建议您为获取最后一条聊天消息使用单独的查询。
英文:
It will not work in this way.
According to the hibernate documentation:
> LazyCollectionOption.EXTRA
only works for ordered collections, either List(s) that are annotated with @OrderColumn
or Map(s).
>
> For bags (e.g. regular List(s) of entities that do not preserve any certain ordering), the @LazyCollection(LazyCollectionOption.EXTRA)
behaves like any other FetchType.LAZY
collection (the collection is fetched entirely upon being accessed for the first time).
From the other side, according to the documentation for the @OrderColumn annotation:
> The OrderBy
annotation should be used for ordering that is visible as persistent state and maintained by the application. The OrderBy
annotation is not used when OrderColumn
is specified.
>
> The order column must be of integral type. The persistence provider maintains a contiguous (non-sparse) ordering of the values of the order column when updating the association or element collection. The order column value for the first element is 0.
So, you can not use the @OrderColumn
annotation for ordering by date/time and as result the LazyCollectionOption.EXTRA
for the first element lazy loading.
I would suggest you to use a separate query for the fetching of the last chat message.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论