I have a collection in my model that contains a set of \'previous versions\' of my root domain object. The previous versions are therefore \'immutable\' and we will never wa
When you have a List or Set-based collection and you add a new object into your collection, Hibernate will always hit the database because it compare one by one object by using equals implementation before saving or updating - when using a Set - or by comparing a index column when using a List. This behavior is needed because of the Set and List semantic. Because of that, the performance of your application can decrease significantly whether you have a bunch of records.
Some workaround to overcome this issue
1º Conversion pattern by using a encapsuled Bag collection plus your desired Set or List exposed as a property
@Entity
public class One {
private Collection manyCollection = new ArrayList();
@Transient
public Set getManyCollectionAsSet() { return new HashSet(manyCollection); }
public void setManyCollectionAsSet(Set manySet) { manyCollection = new ArrayList(manySet); }
/**
* Keep in mind that, unlike Hibernate, JPA specification does not allow private visibility. You should use public or protected instead
*/
@OneToMany(cascade=ALL)
private Collection getManyCollection() { return manyCollection; }
private void setManyCollection(Collection manyCollection) { this.manyCollection = manyCollection; }
}
2º Use ManyToOne instead of OneToMany
@Entity
public class One {
/**
* Neither cascade nor reference
*/
}
@Entity
public class Many {
private One one;
@ManyToOne(cascade=ALL)
public One getOne() { return one; }
public void setOne(One one) { this.one = one }
}
3º Caching - when applied because of, depending on your requirements, your configuration can increase or decrease the performance of your application. See here
4° SQL constraint - If you want a collection that behaves like a Set, you can use a SQL constraint, which can be applied to a column or set of columns. See here