2014-04-09 15 views
1

我有一個有成員對象列表的類,我只需要檢索成員對象的幾個字段,我該怎麼做呢?當我執行生成的查詢時,它只顯示既有所有者又有用戶的記錄,那些沒有這些記錄的記錄不會包含在查詢結果中。如何在成員對象的特定字段上應用投影?

@Entity 
public class Category implements Serializable { 

    @Id 
    @GeneratedValue 
    private long id; 
    @OneToOne 
    private List<Product> products = new ArrayList() 

    ... 
} 

@Entity 
public class Product { 

    @Id 
    @GeneratedValue 
    private long id; 
    private float price; 
    @Temporal(javax.persistence.TemporalType.DATE) 
    private Date regDate; 
    @OneToOne 
    private Person owner; 
    @OneToOne 
    private Person user; 


    ... 
} 

我需要檢索產品的所有字段以及所有者和用戶的所有字段的類別的id。

我有下面的代碼,但它似乎是錯誤的,因爲有每個類別的產品列表。

Criteria cre = session.createCriteria(Category.class, "cat") 
        .createAlias("cat.products", "pro") 
        .createAlias("pro.owner", "owner") 
        .createAlias("pro.user", "user") 
        .addOrder(Property.forName("pro.id").asc()); 
      ProjectionList pl = Projections.projectionList(); 
      pl.add(Projections.property("cat.id").as("cid")); 
      pl.add(Projections.property("pro.id").as("pid")); 
      pl.add(Projections.property("pro.price").as("price")); 
      pl.add(Projections.property("pro.regDate").as("date")); 
      pl.add(Projections.property("owner.fname").as("owFname")); 
      pl.add(Projections.property("owner.lname").as("owLname")); 
      pl.add(Projections.property("user.fname").as("usFname")); 
      pl.add(Projections.property("user.lname").as("usLname")); 
      cre.setProjection(pl); 

criteria.setResultTransformer(new AliasToBeanResultTransformer(CategoryResult.class)); 
categoryResult = (CategoryResult) criteria.list().get(0); 

結果應該是如下

public class CategoryResult { 


    private long cid; 
    private List<ProductResults> products = new ArrayList() 

    ... 
} 

public class ProductResults { 


    private long pid; 
    private float price; 
    private Date regDate; 
    private String owFname; 
    private String owLname; 
    private String usFname; 
    private String usLname; 
    ... 
} 

回答

1

你應該嘗試與此自定義一個替換AliasToBeanResultTransformer在代碼:

public class CategoryResultTransformer extends AliasToBeanResultTransformer { 
    public static final String CID_ALIAS = "cid"; 
    private int cidIndex = -1; 

    public CategoryResultTransformer() { 
     super(ProductResults.class); 
    } 

    @Override 
    public Object transformTuple(Object[] tuple, String[] aliases) { 
     if (cidIndex < 0) { 
      for (int i = 0; i < aliases.length; ++i) { 
       if (CID_ALIAS.equals(aliases[i])) { 
        cidIndex = i; 
        break; 
       } 
      } 
     } 

     return new Object[] { tuple[cidIndex], super.transformTuple(tuple, aliases) }; 
    } 

    @Override 
    public List transformList(List list) { 
     List<CategoryResult> res = new ArrayList<CategoryResult>(); 
     Map<Long, CategoryResult> map = new HashMap<Long, CategoryResult>(); 

     for (Object[] row : (List<Object[]>)list) { 
      long cid = ((Number)row[0]).longValue(); 
      CategoryResult cat = map.get(cid); 

      if (cat == null) { 
       cat = new CategoryResult(); 
       cat.setCid(cid); 
       res.add(cat); 
       map.put(cid, cat); 
      } 

      cat.getProducts().add((ProductResults)row[1]); 
     } 

     return res; 
    } 
} 

附:

我認爲它的意思是在你的代碼的該片段@OneToMany

@OneToOne 
private List<Product> products = new ArrayList() 

不是嗎?

相關問題