2016-03-31 11 views
0

私はこのSQL文を持っている:Hibernate基準で結合テーブルから特定のエンティティを選択する方法は?

select c.* 
from tableA a 
inner join tableB b on a.id = b.a_id        
inner join tableC c on b.id = c.b_id 

と私の基準は次のとおりです。

Criteria criteria = session.createCriteria(tableA.class, "a") 
       .createAlias("a.b", "b") 
       .createAlias("b.c", "c"); 

私は基準をTABLEC選択することができますか?以下のような

何か -

List<tableC> listC = criteria.list() 

は私が

.setProjection(Property.forName("c"))投影を追加しようとしたが、私は次のエラーを得た:

org.hibernate.QueryException: could not resolve property: c of: ...xx.xx.tableA 
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:81) 
at org.hibernate.persister.entity.AbstractPropertyMapping.toType(AbstractPropertyMapping.java:75) 
at org.hibernate.persister.entity.AbstractEntityPersister.toType(AbstractEntityPersister.java:1465) 

これは私のクラスである:

CnTermsGroupクラス

@Entity 
@Table(name="CN_TERMS_GROUP") 
public class CnTermsGroup extends implements Serializable { 

private static final long serialVersionUID = 1145853863134597537L; 

@Id 
@Column(name="CN_TERMS_GROUP_ID") 
private long cnTermsGroupId; 

@Column(name="CN_TERMS_GROUP_NAME") 
private String cnTermsGroupName; 

@OneToMany(mappedBy="cnTermsGroup", cascade=CascadeType.ALL, orphanRemoval=true) 
@Fetch(FetchMode.SUBSELECT) 
private List<CnTermsCounted> cnTermsCounteds; 

public CnTermsGroup() { 
} 

public long getCnTermsGroupId() { 
    return this.cnTermsGroupId; 
} 

public void setCnTermsGroupId(long cnTermsGroupId) { 
    this.cnTermsGroupId = cnTermsGroupId; 
} 

public String getCnTermsGroupName() { 
    return this.cnTermsGroupName; 
} 

public void setCnTermsGroupName(String cnTermsGroupName) { 
    this.cnTermsGroupName = cnTermsGroupName == null ? "" : cnTermsGroupName; 
} 

public List<CnTermsCounted> getCnTermsCounteds() { 
    return this.cnTermsCounteds; 
} 

public void setCnTermsCounteds(List<CnTermsCounted> cnTermsCounteds) { 
    this.cnTermsCounteds = cnTermsCounteds; 
} 

@Override 
public Object getId(){ 
    return cnTermsGroupId; 
} 

}

CnTermsCountedクラス

@Entity 
@Table(name="CN_TERMS_COUNTED") 
public class CnTermsCounted extends BaseModelImp implements Serializable{ 

private static final long serialVersionUID = -8486592249097766983L; 

@Id 
@Column(name="CN_TERMS_COUNTED_ID") 
private long cnTermsCountedId; 

@ManyToOne(fetch = FetchType.LAZY) 
@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE) 
@JoinColumn(name="CN_TERMS_GROUP_ID") 
private CnTermsGroup cnTermsGroup; 

@OneToMany(mappedBy = "cnTermsCounted", cascade=CascadeType.ALL, orphanRemoval=true) 
@Fetch(FetchMode.SUBSELECT) 
private Set<CnTermsRun> cnTermsRuns; 

public CnTermsCounted() { 
} 

public long getCnTermsCountedId() { 
    return this.cnTermsCountedId; 
} 

public void setCnTermsCountedId(long cnTermsCountedId) { 
    this.cnTermsCountedId = cnTermsCountedId; 
} 

public CnTermsGroup getCnTermsGroup() { 
    return this.cnTermsGroup; 
} 

public void setCnTermsGroup(CnTermsGroup cnTermsGroup) { 
    this.cnTermsGroup = cnTermsGroup; 
} 


public Set<CnTermsRun> getCnTermsRuns() { 
    return this.cnTermsRuns; 
} 

public void setCnTermsRuns(Set<CnTermsRun> cnTermsRuns) { 
    this.cnTermsRuns = cnTermsRuns; 
} 

@Override 
public Object getId() { 
    return cnTermsCountedId; 
} 

}

とCnTermsRunクラス

@Entity 
@Table(name="CN_TERMS_RUN") 
public class CnTermsRun extends BaseModelImp { 
private static final long serialVersionUID = -9042920700902106238L; 

@Id 
@Column(name="CN_TERMS_RUN_ID") 
private long cnTermsRunId; 

@ManyToOne 
@JoinColumn(name="CN_TERMS_COUNTED_ID") 
private CnTermsCounted cnTermsCounted; 


public CnTermsRun() { 
} 

public long getCnTermsRunId() { 
    return this.cnTermsRunId; 
} 

public void setCnTermsRunId(long cnTermsRunId) { 
    this.cnTermsRunId = cnTermsRunId; 
} 


public CnTermsCounted getCnTermsCounted() { 
    return this.cnTermsCounted; 
} 

public void setCnTermsCounted(CnTermsCounted cnTermsCounted) { 
    this.cnTermsCounted = cnTermsCounted; 
} 

/* (non-Javadoc) 
* @see com.sintecmedia.onair.model.imp.BaseModelImp#getId() 
*/ 
@Override 
public Object getId() { 
    return cnTermsRunId; 
} 
} 

と基準:

Criteria criteria = session.createCriteria(CnTermsGroup.class, "cnTermsGroup") 
     .createAlias("cnTermsGroup.cnTermsCounteds", "cnTermsCounted") 
     .createCriteria("cnTermsCounted.cnTermsRuns") 
     .setResultTransformer(Transformers.aliasToBean(CnTermsRun.class)); 
+0

は、なぜあなたは基準条件= session.createCriteria(tableC.class、 "C")から起動することはできませんか? – StanislavL

+0

私はJPAクラスで持っている '@Fetch(FetchMode.SUBSELECT)'アノテーションを使用して、ヒットをDBに減らしたいと考えています。 – Mie

+0

.setResultTransformer(Transformers.aliasToBean(tableC.class))はどうですか? – StanislavL

答えて

0

私は2つのアプローチが考えられます。

第1のアプローチは、これはList<Map<String, Object>>を返し

Criteria criteria = session.createCriteria(CnTermsGroup.class, "cnTermsGroup") 
     .createAlias("cnTermsGroup.cnTermsCounteds", "cnTermsCounted") 
     .createAlias("cnTermsCounted.cnTermsRuns", "cnTermsRuns") 
     .setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP); 

以下のようCriteria.ALIAS_TO_ENTITY_MAPを使用しています。コレクションCnTermsRunエンティティに:私たちは、元のために、以下のように、alias nameを使用して、必要なエンティティを収集することができ

List<CnTermsRun> subEntities = new ArrayList<>(); 
List<Map<String, Object>> objects = criteria.list(); 
for (Map<String, Object> record : objects) { 
    subEntities.add((CnTermsRun)record.get("cnTermsRuns")); 
} 

第2のアプローチは、これは直接List<CnTermsRun>を返しますが、必要と

以下のようTransformers.aliasToBean(...)を使用しています新しいconstructorをデフォルトのコンストラクタとともに追加します。

public CnTermsRun(long cnTermsRunId, CnTermsCounted cnTermsCounted) { 
    this.cnTermsRunId = cnTermsRunId; 
    this.cnTermsCounted = cnTermsCounted; 
} 

し、以下の基準:あなたはTABLECクラスが必要な場合は

Criteria criteria = session.createCriteria(CnTermsGroup.class, "cnTermsGroup") 
     .createAlias("cnTermsGroup.cnTermsCounteds", "cnTermsCounted") 
     .createAlias("cnTermsCounted.cnTermsRuns", "cnTermsRuns") 
     .setProjection(Projections.projectionList().add(Projections.alias(Projections.property("cnTermsRuns.id"), "cnTermsRunId")).add(Projections.alias(Projections.property("cnTermsRuns.cnTermsCounted"), "cnTermsCounted"))) 
     .setResultTransformer(Transformers.aliasToBean(CnTermsRun.class)); 
List<CnTermsRun> subEntities = criteria.list(); 
関連する問題