2013-05-15 34 views
6

Tôi đang cố sử dụng GROUP BY trong tiêu chí của mình. Tôi cần phải làm điều này:Tiêu chí Hibernate Sử dụng DANH SÁCH GROUP BY và RETURN ENTITY DANH SÁCH

SELECT b FROM Book b GROUP BY volumeCode; 

Tôi đã mã sau:

Criteria c = s.createCriteria(Book.class); 
    c.setProjection(Projections.projectionList().add(Projections.groupProperty("volumeCode"))); 
    List<Book> result = c.list(); 

Nhưng tiêu chí này chỉ trả về volumeCode s (một danh sách các Strings). Tôi cần có danh sách Book s. Vì vậy, tôi đã cố gắng sử dụng Transformers:

Criteria c = s.createCriteria(Book.class); 
    c.setProjection(Projections.projectionList().add(Projections.groupProperty("volumeCode"))); 
    c.setResultTransformer(Transformers.aliasToBean(Book.class)); 
    List<Book> result = c.list(); 

Mã này trả về danh sách các giá trị rỗng. Có thể làm điều đó với tiêu chí?

Trả lời

5

Trước hết, dự án sẽ lọc lượng dữ liệu được truy xuất, nếu bạn muốn có thêm dữ liệu, bạn cũng nên thêm các thuộc tính đó vào phép chiếu.

Ví dụ:

c.setProjection(Projections.projectionList() 
    .add(Projections.property("id").as("id")) 
    .add(Projections.property("descripction").as("description")) 
    .add(Projections.groupProperty("volumeCode").as("volumeCode"))); 

Bây giờ, máy biến áp làm những gì nó nói "Bí danh để Bean", nó là một trận đấu bí danh với các thuộc tính của đậu java của bạn "Book.java".

Edit:

Nếu không có máy biến áp, nếu chiếu có nhiều hơn một tài sản, kết quả đi ra như thế này:

for(Object[] item:criteria.list()){ 
    System.out.println((String)item[0]); //ID 
    System.out.println((String)item[1]); //Description 
    System.out.println((String)item[2]); //Volume code 
} 

Thats lý do tại sao bạn đã nhận được ngoại lệ cast, về máy biến áp, cố gắng khớp mọi bí danh với tên thuộc tính của hạt java của bạn.

+0

Xin chào Ziul, thx cho câu trả lời của bạn. Với lời khuyên của bạn, tôi nhận được Danh sách các đối tượng nhưng Java ném Ngoại lệ khi tôi cố gắng truyền bất kỳ đối tượng nào từ danh sách vào Sách. –

+0

Ehm, tôi xóa dòng với biến áp O: -) ... Sau khi thêm dòng này trở lại tôi vẫn nhận được Danh sách các đối tượng null. –

+0

Cảm ơn bạn đã chỉnh sửa bài đăng của mình. Tôi không muốn chỉ có một tài sản mà là cả một vật thể. Tôi cần phải có cùng một danh sách các đối tượng như sau khi gọi 'SELECT b FROM Book b GROUP BY volumeCode' do đó kết quả nên là List

2

Tôi nghĩ bạn có thể sử dụng: criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

+0

Bạn nghĩ sao? Tại sao? Làm sao? – rayryeng

+1

@rayryeng Tôi gặp phải cùng một vấn đề cố gắng để có được 'SELECT p FROM người p GROUP BY personId' bằng cách sử dụng tiêu chí nhưng sử dụng setProjection nó chỉ chuyển đổi nó thành sql tương đương' select distint (personId) từ person' và trả về danh sách personId wheres i cần đối tượng toàn bộ con người và 'Danh sách list = session.createCriteria (" Person "," p ") .setResultTransformer (Criteria.DISTINCT_ROOT_ENTITY);' trả về danh sách đối tượng person. về lý do tại sao và làm thế nào hy vọng điều này sẽ giúp [ở đây] (http://stackoverflow.com/questions/10961048/setresulttransformer-in-criteria) – Mazrul

+0

Thêm bài đăng này vào bài đăng của bạn. Chúng tôi không biết tại sao điều này đã giúp bạn ban đầu – rayryeng

3

cz_Nesh. xin lỗi về câu trả lời đầu tiên của tôi. tôi đọc Hibernate api và đọc một số mã nguồn Hibernate tôi tìm thấy điều đó. nếu bạn sử dụng mã này

session.createCriteria(EmpUserImpl.class).list(); 

nó sẽ trả về danh sách EmpUserImpl. nếu bạn sử dụng mã này

 criteria.setProjection(Projections.projectionList() 
      .add(Projections.groupProperty("company").as("company")) 
      .add(Projections.property("name").as("name")) 
      .add(Projections.property("company").as("company"))); 
     List list = criteria.list(); 

nó sẽ trả về Danh sách, không phải là Danh sách EmpUserImpl tại sao? tôi thấy lớp cha mẹ của tiêu chí CriteriaSpecification tôi thấy điều đó.

public interface CriteriaSpecification { 

/** 
* The alias that refers to the "root" entity of the criteria query. 
*/ 
public static final String ROOT_ALIAS = "this"; 

/** 
* Each row of results is a <tt>Map</tt> from alias to entity instance 
*/ 
public static final ResultTransformer ALIAS_TO_ENTITY_MAP = AliasToEntityMapResultTransformer.INSTANCE; 

/** 
* Each row of results is an instance of the root entity 
*/ 
public static final ResultTransformer ROOT_ENTITY = RootEntityResultTransformer.INSTANCE; 

/** 
* Each row of results is a distinct instance of the root entity 
*/ 
public static final ResultTransformer DISTINCT_ROOT_ENTITY = DistinctRootEntityResultTransformer.INSTANCE; 

/** 
* This result transformer is selected implicitly by calling <tt>setProjection()</tt> 
*/ 
public static final ResultTransformer PROJECTION = PassThroughResultTransformer.INSTANCE; 

/** 
* Specifies joining to an entity based on an inner join. 
* 
* @deprecated use {@link org.hibernate.sql.JoinType#INNER_JOIN} 
*/ 
@Deprecated 
public static final int INNER_JOIN = JoinType.INNER_JOIN.getJoinTypeValue(); 

/** 
* Specifies joining to an entity based on a full join. 
* 
* @deprecated use {@link org.hibernate.sql.JoinType#FULL_JOIN} 
*/ 
@Deprecated 
public static final int FULL_JOIN = JoinType.FULL_JOIN.getJoinTypeValue(); 

/** 
* Specifies joining to an entity based on a left outer join. 
* 
* @deprecated use {@link org.hibernate.sql.JoinType#LEFT_OUTER_JOIN} 
*/ 
@Deprecated 
public static final int LEFT_JOIN = JoinType.LEFT_OUTER_JOIN.getJoinTypeValue(); 

}

bạn sẽ nhìn thấy public static thức ResultTransformer DỰ? nó nói rằng biến áp kết quả này được chọn ngầm bằng cách gọi setProjection() có nghĩa là khi bạn sử dụng criteria.setProjection, kết quả sẽ không liệt kê EmpUserImpl, vì ResultTransformer được thay đổi thành "PROJECTION" từ "ROOT_ENTITY" .it sẽ đóng gói bằng Projection (như chọn tên, oid ..). vì vậy, nếu bạn muốn trả về Danh sách EmpUserImpl bạn cần đặt Projections.property ("name"). As ("name")., (Nếu bạn cần tên chỉ cần đặt tên). đây là mã của tôi.

 Criteria criteria = session.createCriteria(EmpUserImpl.class); 
    criteria.setProjection(Projections.projectionList() 
      .add(Projections.groupProperty("company").as("company")) 
      .add(Projections.property("name").as("name")) 
      .add(Projections.property("company").as("company"))); 
    criteria.setResultTransformer(Transformers.aliasToBean(EmpUserImpl.class)); 
    List<EmpUserImpl> list = criteria.list(); 
    for (EmpUserImpl empUserImpl : list) { 
     System.out.println(empUserImpl.getName()); 
    } 

nó có thể hoạt động. Tôi hy vọng nó có thể giúp bạn.

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