2017-04-27 1 views
1

Die gleichen Frage, die ich mit diesem LinkErhalten max Revision weniger als zu einer bestimmten Revision mit envers

Es fand funktioniert gut, aber das Problem ist, während ich bin mit Mitglied werden, es ist nicht einziges Ergebnis geben, Seiner Alle Revisionen werden weniger als die angegebene Revision zurückgegeben.

Mein Code ist wie unten

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

Und

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

Bitte sagen Sie mir ist es etwas, das ich brauche, um bestimmte Revision zu erhalten, verwenden Sie nur max Revision weniger als.

+0

Erwarten Sie, die RevisionNumber als das Ergebnis oder die tatsächliche Entitätsinstanz zu erhalten? Desweiteren, was ist dieser 'computeAggregationInInstanceContext'? Die '#max()' Methode ist nur für Projektionsabfragen anwendbar. – Naros

+0

Nein, ich möchte nicht nur die maximale Revision. Ich versuche eine maximale Revision jeder Entität zu finden, die kleiner oder gleich einer bestimmten Revisionsnummer ist. Ich habe einen Link zu meiner Frage hinzugefügt, der meiner Frage ähnlich ist. Aber hier muss ich ** Join ** verwenden und nach dem Hinzufügen von Join gibt es mehrere Datensätze. –

+0

Und ** computeAggregationInInstanceContext ** Ich habe es gefunden mit [Link_1] (https://hibernate.atlassian.net/browse/HHH-7827) und von diesem [Link_2] (http://stackoverflow.com/questions/ 25723323/find-max-revision-von-jeder-einheit-weniger-als-gleich-gegeben-revision-mit-enver) –

Antwort

0

Wenn Sie dies aus einer reinen SQL-Perspektive betrachten, versucht das, was Sie beschreiben, einen Wert oder ein Aggregat von Werten zu erhalten, die einer bestimmten Gruppe von Prädikaten entsprechen. Das impliziert automatisch eine Projektionsabfrage.

Die Lösung hier wäre so etwas wie:

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); 

Die wichtigsten Teile, die Sie Zeilen der Abfrage werden die letzten drei fehlten.

Die addProjection(AuditEntity.selectEntity(true)) weist Envers an, auf den Entitätsinstanzen selbst ein eindeutiges zu generieren, sodass die Rückgabewerte eindeutige Entitätsinstanzen sind. Dies sollte Probleme mit Joins/Duplikaten vermeiden.

Dann fügen wir eine addOrder(AuditEnttiy.revisionNumber().desc()) Order by-Klausel hinzu, die Envers die Ergebnisse in absteigender Reihenfolge sortiert. Wir tun dies, weil das Ziel darin besteht, eine einzelne Zeile mit einer Revisionsnummer zu erhalten, die kleiner oder gleich revisionId ist. Auf diese Weise wird diese Zeile die erste Zeile in unserer Ergebnismenge sein.

Wir wenden dann eine setMaxResults(1) an. Basierend auf dem Ziel geht dies Hand in Hand mit der von uns hinzugefügten Reihenfolge-Klausel, die Hibernate dazu auffordert, nur die eine Zeile von Interesse zurückzugeben, diejenige an der Spitze der Ergebnismenge, die eine Revisionsnummer kleiner als oder hat gleich revisionId.

HTH.

+0

Vielen Dank für das Erklären zu gut, aber beim Hinzufügen von 'addProjection (AuditEntity.selectEntity (true))' query Ergebnis gibt ** Instrument-Objekt ** (zu dem wir Join durchführen), während es ** CustomTagInstance geben sollte ** Objekt.Ich dachte, dies könnte wegen ** JoinType ** sein, also habe ich auch mit Links Join überprüft, aber das Ergebnis ist das gleiche, Dann habe ich diese Zeile entfernt, danach bekomme ich ein einzelnes Ergebnis, aber das ist nicht Max Revisionsnummer record less-than oder gleichbedeutend mit der Überarbeitungs-ID, die einen zufälligen Wert kleiner als die angegebene Zahl auswählt, während ich maximal –

+0

haben möchte. Bedeutet, ich habe die Reihenfolge Ihres Codes geändert, danach gibt es ein gutes Ergebnis, wie ich es tat 'AuditQuery query_cusTagInst = audQueryCreator.forEntitiesAtRevision (CustomTagInstance.class, revision_Id) .add (AuditEntity.revisionNumber(). Lt (Revision_Id)). AddOrder (AuditEntity.revisionNumber(). Desc()) .traverseRelation ("Gerät", JoinType.INNER) .add (AuditEntity.property ("instrumentId") .eq (id)) .setMaxResults (1); ' –

Verwandte Themen