2008-10-21 37 views
23

Giả sử, các đối tượng thuộc loại A được lưu trữ trong DB. Dưới đây là cách tôi tải một cụ thể từ DB sử dụng Hibernate:Hibernate: kiểm tra xem đối tượng có tồn tại hay không

org.hibernate.Session session = ...; 
long id = 1; 
A obj = session.load(A.class, id); 

Nếu đối tượng với id = 1 không tồn tại Tôi sẽ nhận được ObjectNotFoundException. Nhưng có cách nào để kiểm tra xem đối tượng đó tồn tại mà không cần phải nắm bắt ngoại lệ? Những gì tôi muốn làm là smth như:

org.hibernate.Session session = ...; 
long id = 1; 
boolean exists = session.exists(A.class, id); 
if(exists){ 
// do smth..... 
} 

Không thể tìm thấy nó ngủ đông docs ...

Trả lời

24

Bạn có thể sử dụng session.get:

public Object get(Class clazz, 
        Serializable id) 
      throws HibernateException 

Nó sẽ trả về null nếu đối tượng không tồn tại trong cơ sở dữ liệu. Bạn có thể tìm thêm thông tin trong Hibernate API Documentation.

+0

Hmm ... Tôi vẫn nhận được điều tương tự (ObjectNotFoundException) bất kể tôi sử dụng "tải" hoặc "nhận". –

+0

Có thể bạn đang nhận được một ngoại lệ từ một phiên trước đó()? Từ tài liệu cho ObjectNotFoundException: "Ngoại lệ này có thể không được ném khi load() được gọi vì load() trả về proxy nếu có thể. Sử dụng Session.get() để kiểm tra xem một hàng có tồn tại trong db hay không." – Juanma

+2

có được công trình nhưng đó là một cách tiếp cận chậm kể từ Hibernate sẽ phải lấy tất cả các cột và ảnh hưởng đến chúng đến đối tượng mới và lưu trữ nó trong phiên. Nếu bạn không muốn lãng phí tài nguyên vô ích, hãy xem xét cách tiếp cận HQL thay thế. –

42

bạn có thể sử dụng HQL để kiểm tra sự tồn tại của đối tượng:

public Boolean exists (DTOAny instance) { 
    Query query = getSession().    
    createQuery("select 1 from DTOAny t where t.key = :key"); 
     query.setString("key", instance.getKey()); 
    return (query.uniqueResult() != null); 
} 

ngủ đônguniqueResult() phương thức trả về null nếu không có dữ liệu được tìm thấy. Bằng cách sử dụng HQL bạn có thể tạo ra nhiều tiêu chí truy vấn phức tạp hơn.

10

Hibernate

lấy về chỉ quan trọng đối với hiệu suất tối ưu:

public boolean exists(Class clazz, String idKey, Object idValue) { 
    return getSession().createCriteria(clazz) 
      .add(Restrictions.eq(idKey, idValue)) 
      .setProjection(Projections.property(idKey)) 
      .uniqueResult() != null; 
} 

JPA

Kể từ Hibernate là một thực hiện của JPA, nó có thể inject một EntityManager. Phương pháp này cũng có hiệu suất tốt vì nó lazily fetches các ví dụ:

public boolean exists(Class clazz, Object key) { 
    try { 
     return entitymanager.getReference(Entity.class, key) != null; 
    } catch (EntityNotFoundException.class) { 
     return false; 
    } 
} 
+2

Bạn không cần điều kiện cho dòng cuối cùng: Bạn có thể sử dụng .uniqueResult()! = Null; – stephenwebber

+1

Thx cho gợi ý, tôi đã cập nhật mã! – Journeycorner

3

Một chút đơn giản hóa phương pháp @Journeycorner

public boolean exists(Class<?> clazz, Object idValue) { 
    return getSession().createCriteria(clazz) 
      .add(Restrictions.idEq(idValue)) 
      .setProjection(Projections.id()) 
      .uniqueResult() != null; 
} 

A dưới đây phương pháp có thể hữu ích cũng có. Hãy ghi nhớ, rằng phương pháp này có thể được sử dụng với các tiêu chí mà có thể tạo ra không nhiều hơn một kỷ lục (như Restrictions.idEq() tiêu chí)

public static boolean uniqueExists(Criteria uniqueCriteria) { 
    uniqueCriteria.setProjection(Projections.id()); 
    return uniqueCriteria.uniqueResult() != null; 
} 
Các vấn đề liên quan