2010-11-15 18 views
0

Est-il possible de commander une collection d'objets parents à la fois par la propriété d'un parent et par celle d'un enfant?Ordre des deux parents puis de l'enfant à l'aide de JPA

Disons que j'ai une classe entité qui a ce bit de code:

@OrderBy("age") 
public List<Father> getFathers() { 
    return fathers; 
} 

Le Père entité a une propriété d'âge que nous voulons à l'ordre par âge ascendant (comme indiqué ci-dessus).

Un père peut avoir un enfant. Un enfant aurait aussi une propriété d'âge. Je voudrais que getFathers() retourne une liste des pères de sorte qu'ils soient ordonnés par l'âge des pères et ensuite par la suite l'âge de l'enfant. Si je garde le code ci-dessus tel quel, les Pères seraient ordonnés par leur âge correctement, mais un Père (âgé de 30 ans) avec un enfant de 10 ans pourrait venir devant un Père (également âgé de 30 ans) avec un âge de 5 ans. vieux enfant.

J'ai essayé de faire quelque chose comme ceci:

@OrderBy("age, child.age") 
public List<Father> getFathers() { 
    return fathers; 
} 

Mais je recevrais l'exception suivante:

org.hibernate.AnnotationException: property from @OrderBy clause not found: Father.child.age 

Edit: Désolé, laissez-moi préciser, avec un peu plus de code. Le getFathers() n'est pas dans l'entité enfant mais dans une autre entité. Appelons-Village:

@Entity 
public class Village { 
    ... 
    @OneToMany(mappedBy = "village", 
       targetEntity = Father.class) 
    @OrderBy("age") 
    public List<Father> getFathers() { 
     return fathers; 
    } 
} 

Alors disons il y a un village et vous pouvez obtenir les Pères qui vivent dans ce village. Pour l'exemple de cet exemple, disons qu'un père pour une règle de village étrange ne peut avoir qu'un enfant chacun.

Alors Père ressemblerait à quelque chose comme ceci:

@Entity 
public class Father { 
    private Child child; 
    ... 

    @OneToOne(mappedBy = "father") 
    public Child getChild() { 
     return child; 
    } 

    public void setChild(Child child) { 
     this.child = child; 
    } 
} 

Alors maintenant dans la classe village d'origine, je veux getFathers() de retourner tous les pères pour l'âge, plus, s'il y a des pères avec le même âge, je veux qu'ils soient ensuite ordonnés par l'âge de leur enfant.

Edit 2: J'ai aussi trouvé que je peux obtenir l'effet de ce que je veux mais il ne peut pas être la manière la plus élégante de le faire:

session.createFilter(village.getFathers(), "order by child.age"); 
+0

Montrez vos deux classes avec les propriétés en question mappées. S'il vous plaît omettre d'autres propriétés pour la brièveté. –

+0

Bien sûr! Vous pouvez le faire en utilisant 'Filter', mais vous avez besoin d'une propriété' child' dans la classe 'Father' de toute façon. –

Répondre

3

Il semble que vous êtes manquant la cartographie bidirectionnelle. Vous devez également mapper Child en Father. Par ailleurs, il devrait y avoir une relation un-à-plusieurs entre Father et Child, traditionnellement parlant. Ce qui signifie que dans la classe Father, il devrait y avoir une propriété List<Child> children;, et non l'inverse.

[EDIT]

Non, vous ne pouvez pas faire comme ça. Pourquoi? Parce que lorsque vous définissez votre @OrderBy("age, child.age"), l'ensemble, child.age, serait considéré comme une propriété. Il sera traité comme String. Par conséquent, en effet, vous n'avez aucun nom de propriété child.age dans la classe Father.J'espère que vous obtenez mon point. Donc, la solution Filter, vous êtes venu avec, est un bon moyen d'aller.

+0

Ma classe Father a toujours eu la propriété Child et provoque toujours l'exception Order By. – digiarnie

+0

@digiarnie: Non, vous ne pouvez pas faire comme ça. Pourquoi? Parce que lorsque vous définissez votre '@OrderBy (" age, child.age ")', l'ensemble, 'child.age', serait considéré comme une propriété. Il sera traité comme un 'String'. Par conséquent, en effet, vous n'avez aucun nom de propriété 'child.age' dans la classe' Father'. J'espère que tu m'obtiens. Ainsi, la solution 'Filter' est une bonne solution. –

+0

Merci d'avoir expliqué cela. – digiarnie