2017-04-27 39 views
1

同樣的問題,我發現這個Link獲得最大的修訂小於與envers

它工作正常,但問題是當我使用加入,它是不會放棄單一的結果,它是一個特定版本返回所有修訂版少於給定的修訂版。

我的代碼如下

AuditReader reader = AuditReaderFactory.get(session); 
AuditQueryCreator audQueryCreator = reader.createQuery(); 

AuditQuery query_cusTagInst = audQueryCreator.forEntitiesAtRevision(CustomTagInstance.class, revision_Id) 
       .add(AuditEntity.revisionNumber().le(revision_Id)) 
       .traverseRelation("instrument", JoinType.INNER) 
       .add(AuditEntity.revisionNumber().maximize().computeAggregationInInstanceContext()) 
       .add(AuditEntity.property("instrumentId").eq(id)); 
CustomTagInstance customTagInst = null; 
List list_cusTagInst = query_cusTagInst.getResultList(); 
for(int i=0; i<list_cusTagInst.size(); i++){ 
    customTagInst = (CustomTagInstance) list_cusTagInst.get(i); 
} 

而且

@Audited 
@Table(name = "CUSTOM_TAG_INSTANCE") 
public class CustomTagInstance implements java.io.Serializable { 

private Long tagInstanceId; 
private Instrument instrument; 

@Id 
@Column(name = "TAG_INSTANCE_ID", unique = true, nullable = false, precision = 22, scale = 0) 
public Long getTagInstanceId() { 
    return this.tagInstanceId; 
} 

public void setTagInstanceId(Long tagInstanceId) { 
    this.tagInstanceId = tagInstanceId; 
} 

@ManyToOne(fetch = FetchType.LAZY) 
@JoinColumn(name = "INSTRUMENT_ID") 
public Instrument getInstrument() { 
    return this.instrument; 
} 

public void setInstrument(Instrument instrument) { 
    this.instrument = instrument; 
} 

請告訴我有什麼,我需要使用得到的只有最大的修訂,而不是特定的修訂少。

+0

您是否期望得到RevisionNumber作爲結果或實際的實體實例?此外,IDK這個'computeAggregationInInstanceContext'是什麼? '#max()'方法只適用於投影查詢。 – Naros

+0

不,我不想只修改最大值。我正試圖找到每個實體的最大修訂版,小於或等於給定修訂版號。我添加了與我的問題類似的問題的鏈接。但在這裏,我必須使用**加入**,並添加聯接後,它給出多個記錄。 –

+0

和** computeAggregationInInstanceContext **我發現它與這[Link_1](https://hibernate.atlassian.net/browse/HHH-7827])和從這[Link_2](http://stackoverflow.com/questions/ 25723323/find-max-revision-of-each-entity-less-than-or-equal-to-given-revision-with-enver) –

回答

0

如果您從純粹的SQL角度來看待這個問題,您所描述的是試圖獲取與特定謂詞集相匹配的值或值集合。這自動暗示投影查詢。

的這裏的解決辦法是這樣的:

final AuditQuery query = AuditReaderFactory.get(session) 
    .createQuery() 
    .forEntitiesAtRevision(CustomTag.class, revisionId) 
    .add(AuditEntity.revisionNumber().le(revisionId)) 
    .traverseRelation("instrument", JoinType.INNER) 
    .add(AuditRevisionNumber().maximize().computeAggregationInInstanceContext()) 
    .add(AuditEntity.property("instrumentId").eq(id)) 
    .up() 
    .addProjection(AuditEntity.selectEntity(true)) 
    .addOrder(AuditEntity.revisionNumber().desc()) 
    .setMaxResults(1); 

你失蹤的關鍵部分是查詢的最後線。

addProjection(AuditEntity.selectEntity(true))告訴Envers生成一個獨立的實體實例本身,以便返回值是唯一的實體實例。這應該避免任何聯接/重複問題。

然後,我們添加一個addOrder(AuditEnttiy.revisionNumber().desc()) order by子句,讓Envers以降序對結果進行排序。我們這樣做是因爲我們的目標是獲得一個修訂號小於或等於revisionId的單行。通過這樣做,該行將成爲結果集中的第一行。

然後我們應用setMaxResults(1)。基於這個目標,這與我們添加的order by子句結合在一起,因爲這要求Hibernate僅返回單個關注行,結果集頂部的版本號小於或等於等於revisionId

HTH。

+0

非常感謝你解釋太好,但是在添加'addProjection(AuditEntity.selectEntity(true))'查詢結果給** **對象**(我們正在執行Join)時,它應該給** CustomTagInstance **對象。我想這可能是因爲** ** JoinType所以我檢查與LEFT JOIN太多,但結果是一樣的,然後我刪除了這條線,在那之後我得到一個結果,但不是最大版本號記錄低於或等於對給定的版本的ID,它的採摘一些隨機值小於給定數量的,而我想最大 –

+0

是爲了事項???意味着我改變你的代碼的順序,之後,其給予良好的效果,像我一樣 'AuditQuery query_cusTagInst = audQueryCreator.forEntitiesAtRevision(CustomTagInstance.class,REVISION_ID)。新增(AuditEntity.revisionNumber()。LT(REVISION_ID))。addOrder (AuditEntity.revisionNumber()遞減()).traverseRelation( 「儀器」,JoinType.INNER)。新增(AuditEntity.property( 「instrumentId」).EQ(ID)).setMaxResults(1);' –