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
1o Conversion pattern by using a encapsuled Bag collection plus your desired Set or List exposed as a property
@Entity
public class One {
private Collection<Many> manyCollection = new ArrayList<Many>();
@Transient
public Set<Many> getManyCollectionAsSet() { return new HashSet<Many>(manyCollection); }
public void setManyCollectionAsSet(Set<Many> manySet) { manyCollection = new ArrayList<Many>(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<Many> getManyCollection() { return manyCollection; }
private void setManyCollection(Collection<Many> manyCollection) { this.manyCollection = manyCollection; }
}
2o 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 }
}
3o 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
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…