Я все еще нахожусь в процессе изучения hibernate / hql, и у меня есть вопрос, который наполовину лучший вопрос / половина проверки работоспособности.
Допустим, у меня есть класс A:
@Entity
public class A
{
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(unique=true)
private String name = "";
//getters, setters, etc. omitted for brevity
}
Я хочу обеспечить, чтобы каждый экземпляр A, который был сохранен, имел уникальное имя (отсюда и аннотация @Column), но я также хочу иметь возможность обрабатывать случай, когда уже сохранен экземпляр A с таким именем.Я вижу два способа сделать это:
1) Я могу поймать исключение org.hibernate.exception.ConstraintViolationException, которое может быть выброшено во время вызова session.saveOrUpdate (), и попытаться его обработать.
2) Я могу запросить существующие экземпляры A, которые уже имеют это имя в DAO, перед вызовом session.saveOrUpdate ().
Сейчас я склоняюсь к подходу 2, потому что в подходе 1 я нене знаю, как программно выяснить, какое ограничение было нарушено (в A есть пара других уникальных членов).Прямо сейчас мой код DAO.save () выглядит примерно так:
public void save(A a) throws DataAccessException, NonUniqueNameException
{
Session session = sessionFactory.getCurrentSession();
try
{
session.beginTransaction();
Query query = null;
//if id isn't null, make sure we don't count this object as a duplicate
if(obj.getId() == null)
{
query = session.createQuery("select count(a) from A a where a.name = :name").setParameter("name", obj.getName());
}
else
{
query = session.createQuery("select count(a) from A a where a.name = :name " +
"and a.id != :id").setParameter("name", obj.getName()).setParameter("name", obj.getName());
}
Long numNameDuplicates = (Long)query.uniqueResult();
if(numNameDuplicates > 0)
throw new NonUniqueNameException();
session.saveOrUpdate(a);
session.getTransaction().commit();
}
catch(RuntimeException e)
{
session.getTransaction().rollback();
throw new DataAccessException(e); //my own class
}
}
Правильно ли я поступаю?Может ли hibernate сказать мне программно (т.е. не как строку ошибки), какое значение нарушает ограничение уникальности?Отделяя запрос от коммита, я приглашаю ошибки безопасности потока, или я безопасен?Как это обычно делается?
Спасибо!