Если у вас есть коллекция на основе списка или набора и вы добавляете новый объект в свою коллекцию, Hibernate всегда будет обращаться к базе данных, поскольку сравнивает один за другим объект с использованием равной реализации перед сохранением или обновлением - при использовании набора - или путем сравнения столбца индекса при использовании списка. Такое поведение необходимо из-за семантики Set и List. Из-за этого производительность вашего приложения может значительно снизиться, если у вас есть куча записей.
Некоторое решение для преодоления этой проблемы
1º Шаблон преобразования с использованием инкапсулированной коллекции Bag плюс желаемый набор или список, представленный в виде свойства
@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; }
}
2º Использовать ManyToOne вместо 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º Кэширование - при применении из-за того, что, в зависимости от ваших требований, ваша конфигурация может увеличивать или уменьшать производительность вашего приложения. Смотри здесь
4 ° Ограничение SQL - если вам нужна коллекция, которая ведет себя как набор, вы можете использовать ограничение SQL, которое можно применить к столбцу или множеству столбцов . Смотрите здесь