Hibernate 6 entity refresh ignores the FetchType.LAZY property

Given:
Hibernate 6.2.25.Final.

Entity 1:

@Entity
@Table(name = "chatRoom")
public class ChatRoom
{
    @Id
    private String id;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "chatRoom",
            orphanRemoval = true)
    private Set<ChatRoomUser> chatRoomUsers;

    private String info;

    public ChatRoom()
    {
        this.id = UUID.randomUUID().toString();
    }

}

Entity 2:

@Entity
@Table(name = "chat_room_user")
public class ChatRoomUser
{
    @EmbeddedId
    private ChatRoomUserId id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "chat_room_id", referencedColumnName = "id")
    @MapsId("chatRoomId")
    private ChatRoom chatRoom;

    @Column(name = "info")
    private String info;
}

Problem:

Now, if we get the ChatRoom entity and call em.refresh(chatRoom, LockModeType.PESSIMISTIC_WRITE) then Hibernate will also lock ChatRoomUser although chatRoomUser collection marked as LAZY.

While in hibernate 5.6.14 LAZY collection do not get locked.

I have created a test case GitHub - chernykhalexander/hibernate6EntityError: em refresh ignores the FetchType.LAZY where we can observe the behavior for the 2 versions of the Hibernate.

Question:

Could you please confirm that this is an intended behavior for the refresh method in Hibernate 6.x?

Your association is annotated an CascadeType.ALL, this means that refresh operations will also be cascaded to it - Iā€™m guessing this was also happening in 5. Could you please check if the lock mode was applied in 5 when the association was FetchType.EAGER instead?

If your refresh requested an explicit lock mode and it will also be cascaded to annotated associations it seems logical that those will be locked as well, so I would say the new behavior is correct.

Does it mean that the old behavior is incorrect?

With FetchType.EAGER in Hibernate 5 Set<ChatRoomUser> got locked but if set FetchType.LAZY in Hibernate 5 then Set<ChatRoomUser> not locked.

In Hibernate 6 with FetchType.EAGER Set<ChatRoomUser> got locked and with FetchType.LAZY Set<ChatRoomUser> also got locked.

It seems that cascade refresh do not work for the lazy collection in Hibernate 5 the way it works in Hibernate 6ā€¦

This is a bug. Locking should only cascade if lock cascading is enabled. Please create a Jira issue for this and attach your example project.

Got it. Here is the Jira task [HHH-18208] - Hibernate JIRA

1 Like