#java #jpa #dao
#java #jpa #dao
Вопрос:
Я хотел бы знать, какая реализация метода удаления лучше:
public void remove(T t) {
entityManager.remove(entityManager.merge(t));
}
public void remove(PK pk) {
entityManager.remove(entityManager.getReference(entityType, pk));
}
Я прочитал довольно много статей об этом, и почти в каждой из них это похоже на первый подход, который кажется мне совершенно ненужным, поскольку это можно сделать без необходимости извлекать весь объект из базы данных (если он не присутствует в контексте сохранения), а затем удалять его. Есть ли что-то, чего мне не хватает, и первый подход действительно лучше?
Комментарии:
1. Почему вы не вызываете
entityManager.remove(t)
?2. @stacker: Я хочу, чтобы этот метод удалял как управляемые, так и обособленные объекты.
Ответ №1:
Вы могли бы проверить, управляется ли объект, вызвав
boolean isManaged = entityManager.contains( t );
Если true, просто вызовите
entityManager.remove(t);
в противном случае ваш второй подход кажется лучше, поскольку слияние может вызвать большую активность БД из-за быстрой загрузки (если настроено). Javadoc в getReference говорит: «Получите экземпляр, состояние которого может быть выбрано лениво. Если запрошенный экземпляр не существует в базе данных, генерируется исключение EntityNotFoundException при первом обращении к состоянию экземпляра. (Среде выполнения поставщика сохраняемости разрешено вызывать исключение EntityNotFoundException при получении ссылки (java.lang.Класс, java.lang.Вызывается объект).) Приложение не должно ожидать, что состояние экземпляра будет доступно при отключении, если только приложение не получило к нему доступ во время работы entity manager.»
Короче говоря, для этого необходимо управлять объектом, я бы предложил:
em.remove(em.contains(r) ? r : em.merge(r));
Комментарии:
1. Это решение кажется хорошим, однако мне было бы интересно узнать, проводил ли кто-нибудь какие-либо измерения, выполнял ли кто-нибудь JPQL / HQL-запрос в соответствии со строками «УДАЛИТЬ ИЗ объекта e, ГДЕ e.id =:id», быстрее, чем вызывать merge, а затем удалять, когда объект не содержится в диспетчере? Превышают ли накладные расходы на построение запроса, не требующего извлечения объекта?
2. Мне кажется ненужным, если объект присутствует в контексте сохранения, вызов em.merge(r) возвращает ссылку на управляемый объект.merge(r) возвращает ссылку на управляемый объект. Этот вопрос не об этом. Что меня беспокоит, так это когда объект отсутствует в контексте сохранения .. потому что тогда метод merge должен извлекать объект из базы данных, что в данном случае кажется мне ненужным, поскольку мне нужно только удалить строку из базы данных.