1
votes

Spring Boot JPA & Criteria API - Sélectionnez une seule colonne

J'essaie de récupérer une seule colonne de la table, mais j'obtiens une erreur de compilation concernant le type de retour.

SQL

public List<Note> findAllByNote(Note oNote, int iOffset, int iResultSize) {

        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Comment> cq = cb.createQuery(Comment.class);

        Root<Comment> oComment = cq.from(Comment.class);
        List<Predicate> predicates = new ArrayList<>();

        predicates.add(cb.equal(oComment.get("oNote"), oNote));
        predicates.add(cb.greaterThan(oComment.get("version"), 0));

        Subquery<Note> subquery = cq.subquery(Note.class);
        Root<Note> note = subquery.from(Note.class);

        cb.desc(note.get("m_dtCreationDate"));

        cq.where(predicates.toArray(new Predicate[0]));

        cq.multiselect(oComment.<Note>get("oComment"));

        return (List<Note>)em.createQuery(cq).setFirstResult(iOffset).setMaxResults(iResultSize).getResultList();
    }

J'ai un tableau Commentaire et un tableau Note . Le tableau des commentaires comporte des colonnes commentaire, note et version . Le commentaire lui-même est une note. Maintenant, je veux récupérer tous les commentaires de la note dont la version est supérieure à 0. Mais ici, je ne veux que la colonne de commentaires qui est de type note.

Comment.java

@Entity
@Table(name = "note")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE, region="notes")
public class Note implements Serializable{

    private static final long serialVersionUID = 4089174391962234433L;

    @Column(name="title")
    private String m_szTitle;

    @Column(name="htmlcontent")
    private String m_sbHtmlContent;

    @Column(name="textcontent")
    private String m_sbTextContent;

    @Id
    @Column(name="noteuuid", columnDefinition="varchar(36)")
    private String noteUuid;
}

    @Entity
    @Table(name="comment")
    @Cache(usage=CacheConcurrencyStrategy.READ_WRITE, region="comments")
    public class Comment implements Serializable {

        private static final long serialVersionUID = -4420192568334549165L;

        public Comment() {
        }

        @Id
        @OneToOne
        @JoinColumn(name="commentuuid",referencedColumnName="noteuuid")
        private Note oComment;

        @Id
        @OneToOne
        @JoinColumn(name="noteuuid",referencedColumnName="noteuuid")
        private Note oNote;
}

select oComment from comment where oNote = note and version > 0;

erreur Erreur lors de l'instruction de retour,

Impossible de convertir de la liste en liste


0 commentaires

4 Réponses :


0
votes

Il n'est pas nécessaire d'écrire une méthode de référentiel personnalisée car celle que vous créez est déjà générée dans spring-data.

Si votre dépôt étend le CrudRepository, vous recevrez gratuitement la méthode que vous recherchez.

Le modèle est findAllBy [propertyOfClass].

Mais sachez que vous n'avez en fait aucune collection de NOTE dans votre entité.

Peut-être devriez-vous d'abord changer l'association OneToOne en OneToMany.


0 commentaires

1
votes

La racine de votre requête de critères est Comment et non Note

return (List<Note>)em.createQuery(cq).setFirstResult(iOffset)
.setMaxResults(iResultSize).getResultList();

et vous essayez de faire

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Comment> cq = cb.createQuery(Comment.class);
Root<Comment> oComment = cq.from(Comment.class);

l'erreur de compilation est inévitable dans ce scénario, car em.createQuery (cq) .getResultList () renverra List pas Liste


1 commentaires

Oui. Je veux une colonne de commentaires de la table des commentaires, c'est pourquoi je l'ai fait.



2
votes

dans CustomRepositoryMethod , remplacez d'abord ligne CriteriaQuery cq = cb.createQuery (Comment.class); à CriteriaQuery cq = cb.createQuery (Note.class)

paramètre cb.createQuery accept result Classe dans docs que vous pouvez voir.

mise à jour

// assuming query like
// select oComment from comment inner join Note on comment.noteuuid=Note.noteuuid where Note.noteUuid = 1 and version > 0;

CriteriaBuilder cb = em.getCriteriaBuilder();
// data type of oComment
CriteriaQuery<Note> query = cb.createQuery(Note.class);
// from comment
Root<Comment> comment = query.from(Comment.class);

//join
Join<Comment, Note> note = comment.join(comment.get("oNote"));

//version Condition
Predicate version=cb.greaterThan(comment.get("version"),0 );

//Note condition
predicate note=cb.equal(note.get("noteuuid"),note.getNoteUuid());

// get oComment and where condtion 
query.select(comment.get("oComment")).where(cb.and(version,note));

    return  em.createQuery(query).setFirstResult(iOffset).setMaxResults(iResultSize).getResultList();


6 commentaires

Je veux une colonne de commentaires de la table de commentaires à l'aide de colonnes de notes et de versions. Si j'ai changé le code selon votre suggestion, la requête sera appliquée à la table de notes et il me sera donné le syntex de requête au moment de l'exécution.


pouvez-vous me dire quelle requête vous souhaitez effectuer?


J'ai déjà ajouté une requête et je viens d'ajouter une brève description.


votre requête n'est pas valide. oNote est une entité pas une colonne. pouvez-vous me montrer votre classe de note?


Ajout de la classe Note. Oui, mais la table de commentaires a noteid.


@KaustubhKhare voir la réponse mise à jour cela peut vous aider. et non testé



0
votes

Peut être construit comme une requête de critères comme suit:

CriteriaQuery<Country> q = cb.createQuery(Country.class);

Root<Country> c = q.from(Country.class);

q.select(c.get("currency")).distinct(true);

La méthode select prend un argument de type Selection et le définit comme contenu de la clause SELECT.

/ p>


0 commentaires