2016-01-18 2 views
4

У меня есть книга класса со списком авторов:поиск Spring JPA criteriaBuilder в списке

@Entity 
@Table(name = "book") 
public class Book extends Content { 

    @ManyToMany(fetch = FetchType.LAZY) 
    private List<Author> authors; 
...} 

Теперь это мой BookSpecifications класс:

public static Specification<Book> authorIdIs(Long authorId) { 
    return new Specification<Book>() { 
     @Override 
     public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) { 
      return cb.isTrue(root.get("authors").get("id").in(authorId)); 
     } 
    }; 
} 

Как проверить данный authorId является в списке?

Ошибка:

java.lang.IllegalStateException: Illegal attempt to dereference path source [null.authors] of basic type 
    at org.hibernate.jpa.criteria.path.AbstractPathImpl.illegalDereference(AbstractPathImpl.java:98) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final] 
    at org.hibernate.jpa.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:191) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final] 
    at com.tarameshgroup.derakht.service.specs.BookSpecifications$3.toPredicate(BookSpecifications.java:40) ~[classes/:na] 
    at org.springframework.data.jpa.domain.Specifications$ComposedSpecification.toPredicate(Specifications.java:189) ~[spring-data-jpa-1.9.2.RELEASE.jar:na] 
+0

Я не говорю, что я помогу, но вы можете укажите, как вы его используете? Это новая конструкция для меня, поэтому я не знаю, откуда приходит «Спецификация» и как ее выполнить ... Мне кажется, что корневой файл не инициализирован правильно, см. «Null» в '[null .authors] ', но это не реальный NPE ... – Betlista

+0

Хорошо, я нашел некоторый учебник - https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and- querydsl/... – Betlista

+1

@Betlista Моя проблема заключается в поиске в списке, – CVV

ответ

7

Для этого вы можете использовать Соединение с предикатом:

Приведи ниже код,

public static Specification<Book> authorIdIs(Long authorId) { 
    return new Specification<Book>() { 
     @Override 
     public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) { 
       Join join = root.join("authors");     
       return cb.equal(join.get("id"),authorId); 
     } 
    }; 
} 
+0

@Harsahl Что делать, если мне нужно также выбрать атрибуты авторов? Я думаю, что join не будет делать select * .authors automaticlly. – zt1983811

+0

@ zt1983811 Поэтому вам нужно получить эти атрибуты только в соединении. –

Смежные вопросы