Спящий режим, вставка или обновление без выбора
Вопрос
У меня есть объекты продуктов, которые принадлежат к определенным категориям, т.е.классическое отношение «многие к одному».
@Entity
public class Product{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
Long id;
String name;
Double price;
@ManyToOne(fetch = FetchType.LAZY)
Category category;
...
}
@Entity
public class Category implements Identifiable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
...
}
Я хочу вставлять и обновлять товары без предварительного выбора категорий.Так:
Product product = dao.get(productId);
Category category = dao.get(categoryId);
product.setCategory(category);
dao.update(product);
или
Product product = new Product(somename);
Category category = dao.get(categoryId);
product.setCategory(category);
dao.insert(product);
Можно ли обновить и вставить без выбора категории?Я не хочу использовать для этого HQL или прямые запросы.
Решение
сеанс.загрузка() существует специально для таких случаев.Следующее:
Category category = session.load(categoryId);
product.setCategory(category);
не попадет в базу данных.Однако на более позднем этапе (во время очистки, более или менее) будет выдано исключение, если не будет доступной категории с данным идентификатором.
С использованием load()
быстрее, чем merge()
и не имеет побочных эффектов (каскадирование и т. д.)
Другие советы
Hibernate нуждается в безопасном способе определения состояния вашего объекта.Вот почему очень важно убедиться, что вы не можете смешивать объекты из разных сеансов (чтобы вы не могли загружать категории при запуске, а затем просто использовать их позже).
Решение состоит в том, чтобы загружать категории при запуске, настроить поставщика кеширования, например ehcache
для этого класса, а затем используйте этот код:
Product product = new Product(somename);
product.setCategory(session.merge(category));
Это не приведет к каким-либо обращениям к базе данных, если вы настроите кеш, который экземпляры категорий не смогут изменить.
Я только что попробовал следующее:
Category category = new Category(categoryId);
product.setCategory(category);
И это сработало, я имею в виду, что запись продукта в БД получила правильную ссылку на категорию и категорию с идентификатором.
categoryId
не изменились.