2017-04-27 2 views
1

la même question que j'ai trouvé cette LinkObtenez la révision max moins à une révision particulière avec Envers

Il fonctionne bien, mais le problème est alors que je me sers Rejoignez, il ne donne pas seul résultat, Son renvoyant toutes les Révisions moins de révision donnée.

Mon code est comme ci-dessous

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

Et

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

S'il vous plaît, dites-moi est quelque chose que je dois utiliser pour obtenir que la révision max Moins de révision donnée.

+0

Attendez-vous à ce que le numéro de révision soit le résultat ou l'instance d'entité réelle? En outre, IDK ce que ce 'computeAggregationInInstanceContext' est? La méthode '#max()' ne s'applique qu'aux requêtes de projection. – Naros

+0

Non, je ne veux pas seulement une révision max. J'essaie de trouver une révision maximale de chaque entité inférieure ou égale au numéro de révision donné. J'ai ajouté un lien à ma question qui est similaire à ma question. Mais ici, je dois utiliser ** Join ** et après avoir ajouté join, il donne plusieurs enregistrements. –

+0

Et ** computeAggregationInInstanceContext ** Je l'ai trouvé avec ce [Link_1] (https://hibernate.atlassian.net/browse/HHH-7827]) et à partir de ce [Link_2] (http://stackoverflow.com/questions/ 25723323/find-max-revision-of-each-entity-less-than-or-equal-to-given-revision-with-enver) –

Répondre

0

Si vous regardez cela d'un point de vue purement SQL, ce que vous décrivez est d'essayer d'acquérir une valeur ou un agrégat de valeurs qui correspondent à un ensemble particulier de prédicats. Cela implique automatiquement une requête de projection.

La solution ici serait quelque chose comme:

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

Les éléments clés que vous manque, ce sont les derniers trois lignes de la requête.

addProjection(AuditEntity.selectEntity(true)) indique à Envers de générer un distinct sur les instances d'entité elles-mêmes afin que les valeurs de retour soient des instances d'entité uniques. Cela devrait éviter tout problème avec les jointures/doublons.

Nous ajoutons ensuite un ordre addOrder(AuditEnttiy.revisionNumber().desc()) par clause ayant Envers pour trier les résultats dans l'ordre décroissant. Nous faisons cela parce que l'objectif est d'obtenir une seule ligne dont le numéro de révision est inférieur ou égal à revisionId. En faisant cela, cette ligne sera la première rangée de notre ensemble de résultats.

Nous appliquons ensuite un setMaxResults(1). Sur la base de l'objectif, cela va de pair avec la clause order by que nous avons ajoutée car cela demande à Hibernate de ne retourner que la seule ligne d'intérêt, celle en haut de l'ensemble de résultats qui a un numéro de révision inférieur ou égal à revisionId.

HTH.

+0

Merci beaucoup d'expliquer trop bien, mais en ajoutant 'addProjection (AuditEntity.selectEntity (true))' résultat de la requête donne ** Instrument objet ** (auquel nous effectuons Join), alors qu'il devrait donner ** CustomTagInstance ** objet.Je pensais que cela pouvait être dû à ** JoinType ** donc j'ai vérifié avec Left join aussi mais le résultat est le même, Puis j'ai enlevé cette ligne, après que j'obtiens le résultat unique mais ce n'est pas le numéro de révision max. égal à donné Id de révision, Son choix d'une valeur aléatoire moins de nombre donné, alors que je veux max –

+0

L'ordre est-il important ??? Cela signifie que j'ai changé l'ordre de votre code, après cela il donne un bon résultat, comme je l'ai fait 'AuditQuery query_cusTagInst = audQueryCreator.forEntitiesAtRevision (CustomTagInstance.class, révision_Id) .add (AuditEntity.revisionNumber() .lt (révision_Id)). AddOrder (AuditEntity.revisionNumber(). Desc()) .traverseRelation ("instrument", JoinType.INNER) .add (AuditEntity.property ("instrumentId") .eq (id)) .setMaxResults (1); ' –