2016-03-31 11 views
0

Ich habe diese SQL-Anweisung:Wie bestimmte Entität aus verbundenen Tabellen mit Hibernate-Kriterien auswählen?

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 

und meine Kriterien:

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

wie kann ich mit den Kriterien wählen TableC?

so etwas wie -

List<tableC> listC = criteria.list() 

Ich versuchte Projektion hinzufügen .setProjection(Property.forName("c"))

aber ich habe die Folgefehler:

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) 

dies ist meine Klassen:

CnTermsGroup Klasse

@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 Klasse

@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; 
} 

}

und CnTermsRun Klasse

@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; 
} 
} 

und die Kriterien:

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

Wenn Sie TableC Klassen warum benötigen, können Sie nicht von den Kriterien Kriterien = session.createCriteria (tableC.class, "c") beginnen? – StanislavL

+0

Ich möchte, dass Hibernate die '@ Fetch (FetchMode.SUBSELECT)' Annotation, die ich in meinen JPA-Klassen habe, um die Treffer auf die DB zu verringern. – Mie

+0

Was ist mit .setResultTransformer (Transformers.aliasToBean (tableC.class))? – StanislavL

Antwort

0

Ich kann mir zwei Ansätze vorstellen.

Erster Ansatz wird mit Criteria.ALIAS_TO_ENTITY_MAP wie unten

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

Dies gibt eine List<Map<String, Object>>. Wir können die erforderlichen Einheiten sammeln die alias name verwenden, wie unten, für die Ex: die Sammlung CnTermsRun Einheiten:

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

Zweiter Ansatz wird mit Transformers.aliasToBean(...) wie unten

Das gibt List<CnTermsRun> direkt, sondern erfordert eine neue constructor hinzugefügt werden, zusammen mit Standardkonstruktor:

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

Und die nachstehenden Kriterien:

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(); 
Verwandte Themen