Do Not Replace Persistent Collection in Setter

ID

java.hibernate_collection_setter_replace

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Java

Tags

best-practice, hibernate, orm, reliability

Description

Reports setter methods that reassign @OneToMany, @ManyToMany, or @ElementCollection fields via simple assignment (this.items = newItems). Hibernate wraps entity collections with PersistentCollection for dirty-tracking. Replacing the collection reference loses the wrapper and breaks change detection.

Rationale

When Hibernate loads an entity, it replaces the original collection instance with a PersistentCollection proxy that intercepts calls to add, remove, clear, etc. If a setter replaces this proxy with a new plain ArrayList, Hibernate can no longer detect what changed and may silently skip persistence of modifications.

// Bad: setter replaces the persistent collection
@OneToMany
private List<Order> orders;

public void setOrders(List<Order> orders) {
    this.orders = orders; // PersistentCollection wrapper lost
}

Remediation

Mutate the existing collection in place instead of replacing it:

// Good: mutate in place
public void setOrders(List<Order> orders) {
    this.orders.clear();
    this.orders.addAll(orders);
}