9
votes

Critères hibernés et colonne de comptage

J'essaie de retourner une entité avec une colonne qui comporte le nombre d'une autre table qui est une à plusieurs relativement. Je veux faire cela en utilisant des critères d'hibernate, pas le HQL.

select p.*, (select count(*) from child where child.parentid = p.id) as LEVELS
from parent p


2 commentaires

Votre clause "où" est-elle censée être un "de"?


Merci corrigé cette erreur de syntaxe


4 Réponses :


0
votes

Vous pourrez peut-être le faire par une sorte de projection.

Voir le tutoriel sur des projections hibernées. Vous êtes probablement intéressé par la méthode code> sqlprojection code> dans Projections classe pour la sous-requête. P>

List results = session.createCriteria(Parent.class, "p") 
    .setProjection(Projections.projectionList()
        .add(Projections.property("field1"))
        .add(Projections.property("field2"))
        .add(Projections.property("field3"))
        .add(Projections.sqlProjection("select count(*) from child where child.parentid = p.id"), new String[] {"LEVELS"}, new Type[] {Hibernate.INTEGER})
    ).list();


7 commentaires

Je vais essayer ça, mais existe-t-il de toute façon pour ne pas utiliser SQL brut et utiliser une requête détachée en quelque sorte?


La partie délicate semble être que votre compter dépend d'une autre relation. Si vous utilisez l'hibernate Association mappings, Ensuite, vous pouvez mapper une liste d'objets enfants et utiliser simplement la méthode Java Taille .


Voir mon autre réponse pour la méthode des associations.


Ce projet original m'a donné SELECT * à partir de (sélectionnez SELECT Count (*) à partir de Badgelevels BL où bl.badgeid = b.id de cisco.badges this_ where où this_.active =?) Où rownum <=?


Comment puis-je retourner le reste des colonnes de parent.class avec le compte? Est-ce que je manque une projection?


Vous pouvez ajouter les colonnes supplémentaires en chaînant des appels sur la projection . J'ai modifié ma réponse originale pour cela.


Oui, mais comment le faites-vous dans un appel parce que je pourrais ajouter plus de propriétés à l'avenir et que vous ne voulez pas taper 20 colonnes à ramener.



0
votes

Définissez un mappage de champ d'objet comme ci-dessous. Ensuite, lorsque vous interrogez vos objets parent, chaque objet doit avoir un champ de liste de types appelé enfant que vous pouvez appeler Taille code> sur.

<class name="Person">
    <id name="id" column="id">
        <generator class="native"/>
    </id>
    <set name="children">
        <key column="parentId" 
            not-null="true"/>
        <one-to-many class="Child"/>
    </set>
</class>

<class name="Child">
    <id name="id" column="childId">
        <generator class="native"/>
    </id>
</class>


1 commentaires

Je retourne une liste de parents et je ne veux pas retourner tous les enfants de cet objet. Je veux juste le comte des enfants avec les colonnes parents.



4
votes

Je dois travailler faire cela. Pas très dynamique mais cela fonctionnera.

    @Basic
    @Column(name = "LEVEL")
    @Formula(value="(SELECT count(*) FROM BadgeLevels bl WHERE bl.badgeid = this_.id)")
        public long getLevel() {
        return level;
    }


0 commentaires

5
votes

Si l'entité mère contient également une liste d'enfants (association bidirectionnelle), vous pouvez utiliser des critères pour renvoyer le nombre d'enfants comme suit:

    Criteria criteria = hibernateSessionHelper.getSessionFactory().getCurrentSession().createCriteria(Parent.class);

    ProjectionList projList = Projections.projectionList();
    projList.add(Projections.countDistinct("children.id"));
    projList.add(Property.forName("field1").group());
    projList.add(Property.forName("field2").group());
    projList.add(Property.forName("field3").group());
    .
    .
    .
    criteria.createAlias("children", "children", CriteriaSpecification.LEFT_JOIN);

    criteria.setProjection(projList);

    List<Object[]> results = crit.list();


0 commentaires