Спящий режим, вставка или обновление без выбора
У меня есть объекты продуктов, которые относятся к определенным категориям, то есть к классическим отношениям много к одному.
@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 или прямые запросы.
Ответы
Ответ 1
session.load() существует специально для таких случаев. Следующее:
Category category = session.load(categoryId);
product.setCategory(category);
не попадет в базу данных. Тем не менее, он будет генерировать исключение на более позднем этапе (во время flush, более или менее), если нет категории, доступной с данным идентификатором.
Использование load()
быстрее, чем merge()
и не имеет побочных эффектов (каскадирование и т.д.)
Ответ 2
Спящий режим нуждается в безопасном способе определения состояния вашего объекта. Вот почему вам предстоит пройти долгий путь, чтобы вы не могли смешивать объекты с разных сеансов (поэтому вы не можете загружать категории при запуске, а затем просто использовать их позже).
Решение заключается в загрузке категорий при запуске, настройке кэширующего провайдера, такого как ehcache
для этого класса, и затем использования этого кода:
Product product = new Product(somename);
product.setCategory(session.merge(category));
Это не вызовет каких-либо переходов DB, если вы настроите кеш, которые не могут изменить эти категории.
Ответ 3
Я только что попробовал следующее:
Category category = new Category(categoryId);
product.setCategory(category);
И это сработало, я имею в виду, что запись продукта в db получила правильную ссылку на категорию и категорию с id
categoryId
не изменились.