Tôi vẫn còn trong quá trình học hibernate/hql và tôi có một câu hỏi đó là một nửa thực hành tốt nhất câu hỏi/kiểm tra sanity một nửa.câu hỏi độc đáo cột ngủ đông
Hãy nói rằng tôi có một lớp 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
}
Tôi muốn thực thi mà mỗi trường hợp của A mà được lưu có một cái tên duy nhất (vì thế chú thích @column), nhưng tôi cũng muốn có thể để xử lý trường hợp đã có một cá thể A được lưu có tên đó. Tôi thấy hai cách để làm điều này:
1) Tôi có thể bắt org.hibernate.exception.ConstraintViolationException có thể được ném trong cuộc gọi session.saveOrUpdate() và cố gắng xử lý nó.
2) Tôi có thể truy vấn các phiên bản hiện tại của A đã có tên đó trong DAO trước khi gọi session.saveOrUpdate().
Hiện tại tôi đang nghiêng về phía phương pháp 2, vì trong phương pháp tiếp cận 1 Tôi không biết cách lập trình tìm ra ràng buộc nào đã bị vi phạm (có một vài thành viên duy nhất khác trong A). Ngay bây giờ mã DAO.save() của tôi trông gần giống như thế này:
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
}
}
Tôi sẽ làm điều này đúng cách? Có thể ngủ đông cho tôi biết theo chương trình (tức là không phải là chuỗi lỗi) giá trị nào vi phạm ràng buộc duy nhất không? Bằng cách tách truy vấn khỏi cam kết, tôi có đang mời các lỗi an toàn luồng không hoặc tôi có an toàn không? Việc này thường được thực hiện như thế nào?
Cảm ơn!
Tôi có gặp vấn đề về an toàn luồng nào với phương pháp thứ hai không? Theo như tôi hiểu, phần "Cách ly" của các nguyên tắc DB của ACID được cho là sẽ giúp tôi ở đây, nhưng tôi không chắc cách hibernate/hsqldb tuân thủ như thế nào. – Seth
Tôi không hiểu tại sao cách ly lại quan trọng đối với trường hợp này. Kiểm tra nếu một tên tồn tại sẽ xảy ra trong cùng một giao dịch và không thay đổi trạng thái của dữ liệu trong cơ sở dữ liệu. – Rachel