Spring boot JPA & Criteria API - Выберите один столбец - PullRequest
0 голосов
/ 28 июня 2019

Я пытаюсь получить один столбец из таблицы, но получаю ошибку компиляции о типе возвращаемого значения.

SQL

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

У меня есть Comment стол и Note стол.Таблица комментариев содержит comment, note and version столбцов.Сам комментарий является примечанием.Теперь я хочу получить все комментарии к заметке, версия которой больше 0. Но здесь я хочу получить только столбец комментариев с типом заметки.

Comment.java

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

Note.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;
}

CustomRepositoryMethod

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

error Ошибка в операторе возврата,

Cannot cast from List<Comment> to List<Note>

Ответы [ 4 ]

2 голосов
/ 28 июня 2019

in CustomRepositoryMethod заменить первую строку CriteriaQuery<Comment> cq = cb.createQuery(Comment.class); на CriteriaQuery<Note> cq = cb.createQuery(Note.class)

cb.createQuery параметр принять результат Класс в документы вы можете видеть.

обновление

// 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();
1 голос
/ 28 июня 2019

Корнем запроса критериев является Comment, а не Note

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

, и вы пытаетесь сделать

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

ошибка компиляции в этом сценарии неизбежна, так как em.createQuery(cq).getResultList() вернет List<Comment> не List<Note>

0 голосов
/ 28 июня 2019

Может быть построен как запрос критерия следующим образом:

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

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

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

Метод select принимает один аргумент типа Selection и устанавливает его в качестве содержимого предложения SELECT.

0 голосов
/ 28 июня 2019

Нет необходимости писать собственный метод репозитория, поскольку тот, который вы создаете, уже сгенерирован в spring-data.

Если ваш репозиторий расширяет CrudRepository, вы получите тот метод, который вы ищетебесплатно.

Шаблон - findAllBy [propertyOfClass].

Но учтите, что у вас на самом деле нет Коллекции NOTE в вашей сущности.

Возможно, вам следует сначала изменитьобъединение OneToOne в OneToMany.

...