2010-04-29 31 views

Trả lời

7

tôi giả sử bạn đang sử dụng một phiên bản của Hibernate mà thực hiện JPA 2.0. Đây là giải pháp JPA 2.0 có thể hoạt động với bất kỳ triển khai thực hiện nào.

Vui lòng chú thích uuids bằng chú thích @ElementCollection của JPA. Không sử dụng @CollectionOfElements của Hibernate như đã đề cập trong một số nhận xét trả lời khác. Cái sau có chức năng tương đương nhưng là being deprecated.

Foobar.java sẽ xem xét khoảng như thế này:

@Entity 
public class Foobar implements Serializable { 

    // You might have some other id 
    @Id 
    private Long id; 

    @ElementCollection 
    private List<String> uuids; 

    // Getters/Setters, serialVersionUID, ... 

} 

Đây là cách bạn có thể xây dựng một CriteriaQuery để chọn tất cả Foobar s mà uuids chứa "abc123".

public void getFoobars() { 
{ 
    EntityManager em = ... // EM by injection, EntityManagerFactory, whatever 

    CriteriaBuilder b = em.getCriteriaBuilder(); 
    CriteriaQuery<Foobar> cq = b.createQuery(Foobar.class); 
    Root<Foobar> foobar = cq.from(Foobar.class); 

    TypedQuery<Foobar> q = em.createQuery(
      cq.select(foobar) 
       .where(b.isMember("abc123", foobar.<List<String>>get("uuids")))); 

    for (Foobar f : q.getResultList()) { 
     // Do stuff with f, which will have "abc123" in uuids 
    } 
} 

Tôi đã tạo chương trình chứng minh khái niệm khép kín khi chơi với trò chơi này. Tôi không thể đẩy nó ra ngay bây giờ. Xin vui lòng bình luận nếu bạn muốn POC đẩy github.

+0

Đã thử với hibernate 3.6.7-Final và không hoạt động (nó có vẻ là một lỗi trong hibernate). – greuze

-2

Để bắt đầu, tôi không nghĩ rằng Hibernate có thể ánh xạ List<String>. Tuy nhiên, nó có thể ánh xạ một danh sách các thực thể khác.

Vì vậy, nếu mã của bạn là một cái gì đó như thế này:

@Entity 
public class Foobar { 

    private List<EntityObject> uuids; 
    ... 
} 

EntityObjectString -property gọi str, các tiêu chí có thể trông như thế này:

List<Foobar> returns = (List<Foobar>) session 
       .createCriteria.(Foobar.class, "foobars") 
       .createAlias("foobars.uuids", "uuids") 
        .add(Restrictions.like("uuids.str", "%abc123%")) 
       .list(); 
+1

Không có vấn đề gì khi sử dụng danh sách các chuỗi, chỉ cần chú thích nó bằng @CollectionOfElements. Giải pháp của bạn yêu cầu tôi tạo ra một lớp thực thể bổ sung, thứ mà tôi đã hy vọng tránh được với câu hỏi rất cụ thể này. –

1

Bạn có thể sử dụng một Query như trong ví dụ bên dưới hoặc bạn có thể chuyển đổi điều này thành một NamedQuery. Thật không may có vẻ không phải là một cách để làm điều này với Tiêu chí.

List<Foobar> result = session 
    .createQuery("from Foobar f join f.uuids u where u =: mytest") 
    .setString("mytest", "acb123") 
    .list(); 
1

Điều bạn đang yêu cầu không được hỗ trợ ngoài hộp bằng ngủ đông. Xem http://opensource.atlassian.com/projects/hibernate/browse/HHH-869

Đây là một cách giải quyết khác vé jira:

entityCriteria.add(Restrictions.sqlRestriction(
    "fooAlias.id in (select e.id from foobar_table e, values_table v" + 
    " where e.id = v.entity_id and v.field = ?)", "abc123"), Hibernate.String)) ; 
2

Tôi đã tìm thấy bài đăng này từ một năm trước và tôi đã thực hiện phương pháp này, nếu nó có thể giúp bất kỳ ai có cùng vấn đề tôi đã có vài giờ trước.

Public List<EntityObject> getHasString(String string) { 
     return getSession().createCriteria(EntityObject.class) 
           .add(Restriction.like("property-name", string, MatchMode.ANYWHERE).ignoreCase(); 
          .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 
          .list(); 

Làm tương tự với một nhóm dây.

public List<EntityObject> getByStringList(String[] tab) { 
     Criterion c = Restrictions.like("property-name", tab[tab.length-1], MatchMode.ANYWHERE).ignoreCase(); 
     if(tab.length > 1) { 
      for(int i=tab.length-2; i >= 0 ; i--) { 
       c = Restrictions.or(Restrictions.like("property-name",tab[i], MatchMode.ANYWHERE).ignoreCase(), c); 
      } 
     } 
     return getSession().createCriteria(EntityObject.class) 
           .add(c) 
          .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 
          .list(); 
    } 

Nó hoạt động với câu lệnh "hoặc", nhưng có thể dễ dàng được thay thế bằng "và".

0

Giải pháp với sqlRestriction từ jira http://opensource.atlassian.com/projects/hibernate/browse/HHH-869 có vẻ là cách tốt nhất để đi cho tôi vì tôi sử dụng tiêu chí rất nhiều api. Tôi đã phải chỉnh sửa mã Thierry, do đó nó làm việc trong trường hợp của tôi

mẫu:

@Entity 
public class PlatformData 
{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long iID; 

    private List<String> iPlatformAbilities = new ArrayList<String>(); 
} 

Tiêu chuẩn gọi:

tCriteria.add(Restrictions.sqlRestriction(
     "{alias}.id in (select e.id from platformData e, platformdata_platformabilities v" 
      + " where e.id = v.platformdata_id and v.element = ?)", aPlatformAbility.toString(), 
     Hibernate.STRING)); 
3

Tôi biết đây là câu hỏi cũ, nhưng tôi vừa gặp phải vấn đề này và giải pháp tìm thấy.

Nếu bạn muốn sử dụng tiêu chí Hibernate, bạn có thể tham gia bộ sưu tập uuids và sử dụng thuộc tính elements để khớp các thành phần. Chỉ cần như vậy:

session.createCriteria(Foobar.class) 
    .createAlias("uuids", "uuids") 
    .add(Restrictions.eq("uuids.elements", "MyUUID")) 
    .list() 
+1

Bạn cũng có thể sử dụng thay cho "phần tử" hằng số 'CollectionPropertyNames.COLLECTION_ELEMENTS'. –

Các vấn đề liên quan