Why does Hibernate marks entity's ElementCollection as dirty when there are no changes?

I’m using Hibernate and JPA. I have an entity that looks like this:

@Data
@Entity
@Table(name = "MY_ENTITY")
public class MyEntity {

    @Id
    @Column(name = "ID")
    public Long id;

    @Version
    @Column(name = "VERSION")
    public Long version = 1L;

    @Embedded
    @AttributeOverride(name = "timestamp", column = @Column(name = "UPDATED_TIME"))
    public CustomTimestamp updatedTime;

    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "ENTITY_CONNECTION", joinColumns = @JoinColumn(name = "ENTITY_ID"))
    @OrderColumn(name = "CONNECTION_ORDER")
    @Fetch(FetchMode.SUBSELECT)
    @JsonDeserialize(using = ConnectionDeserializer.class)
    public List<Connection> connections = new ArrayList<>();

    @PreUpdate
    public void preUpdate() {
        this.updatedTime = new CustomTimestamp();
    }

}
@Data
@Embeddable
public class Connection {

    @Column(name = "CONNECTED_ENTITY_ID")
    public String connectedEntityId;

    @Column(name = "CONNECTED_ENTITY_TYPE")
    public String connectedEntityType;

    @Column(name = "NOTE")
    public String note;


}

The input for the entity includes all the fields with a delete flag. The deserializer mentioned, takes the existing list and performs the diff with the update sent. Updates the existing entities in the list, adds the new entities and deletes the entities marked with the “delete” flag.

In the API I expose a path to “patch” the entity, meaning the user passes the fields they want to update. And I perform the following logic:

MyEntity originalEntity = repository.findById(id);
ObjectReader entityForUpdate = objectMapper.readerForUpdating(originalEntity);
MyEntity updatedEntity = objectMapper.update(entityForUpdate, updateInput);
repository.saveAndFlush(updatedEntity);

And example “patch” input would be something like:

patch /entity/{id}
body: 
{
    "connections": [
        {
            "connectedEntityId": "test",
            "connectedEntityType": "testType"
        }
    ]
}

When sending it twice, I would expect the second time to not detect anything as “dirty” and therfore not increment the version, however it does.

When looking at Hibernate’s logs, looks like the “connection” collection is dirty.

How does Hibernate’s dirty check decides if the collection is dirty?

Tried using Set instead of ArrayList - Collection was still dirty.

Tried using OneToMany mapping - the problem was the opposite - parent entity never updates. From what I understand, this is not the best option since “Connection” doesn’t stand as an entity on its own.

Tried adding a generated ID to Connection entity - Collection was still dirty.

Verified all entities implement equals() as expected

How do you determine that Hibernate ORM thinks the collection is dirty? I assume that whatever you are using to apply a patch is creating new objects for collection elements and Hibernate ORM doesn’t bother checking if a collection element is deeply equal to an element of the initial state.
To avoid unnecessary update statements you’d have to avoid replacing objects in that case.