具有规范和排序属性的Spring数据

时间:2016-12-15 10:54:11

标签: spring-boot orm spring-data-jpa

我有两个entitis,存储库和类实现规范:

@Entity
    public class Person {
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private Long id;
        private String name;
        @OneToOne
        @JoinColumn(name = "phone_id")
        private Phone phone;

@Entity
public class Phone {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;
    private String number;

    public Long getId() {
        return id;
    }

public interface PersonRepositories extends CrudRepository<Person, Long>, JpaSpecificationExecutor<Person> {
}

public class PersonSpecification implements Specification<Person> {

    private String name;
    public PersonSpecification(String name) {
        this.name=name;
    }
    @Override
    public Predicate toPredicate(Root<Person> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
         List<Predicate> predicates = new ArrayList<>();
        if(name!=null) {
            predicates.add(builder.like(root.get("name"), name));
        }
        query.groupBy(root.get("id"));
        return  builder.and((predicates.toArray(new Predicate[predicates.size()])));
    }



  @Service
    public class PersonSearchServicesImpl implements PersonSearchServices {
        @Autowired
        PersonRepositories personRepositories;
        @Override
        public List<Person> searchPerson(String name, String order) {
            PersonSpecification person = new PersonSpecification(name);
            Direction direction = Sort.Direction.ASC;
            String[] sortProp = {order};
            Sort sort = new Sort(direction, sortProp);
            Pageable pageable = new PageRequest(0, 10, sort);

            Page<Person> findAll = personRepositories.findAll(person, pageable);
        return findAll.getContent();
    }

一些示例数据:

@SpringBootApplication
public class SpringOrmSpecApplication implements CommandLineRunner {

    @Autowired
    PersonSearchServices services;
    @Autowired
    PhoneRepositories phoneRepositories;
    @Autowired
    PersonRepositories personRepositories;

    public static void main(String[] args) {
        SpringApplication.run(SpringOrmSpecApplication.class, args);
    }

    @Override
    public void run(String... arg0) throws Exception {
        Phone phone = new Phone();
        phone.setNumber("AAA");
        phoneRepositories.save(phone);

        Phone phone2 = new Phone();
        phone2.setNumber("BBB");
        phoneRepositories.save(phone2);

        Person person = new Person();
        person.setName("Barry");
        person.setPhone(phone);
        personRepositories.save(person);

        Person person2 = new Person();
        person2.setName("Alfred");
        person2.setPhone(phone2);
        personRepositories.save(person2);

        Person person3 = new Person();
        person3.setName("Alfred");
        person3.setPhone(phone);
        personRepositories.save(person3);

        search();
    }
public void search(){
        List<Person> searchPerson = services.searchPerson("Alfred", "phone");
        searchPerson.stream().forEach(p -> System.out.println(p));
    }

在数据库H2上运行良好但在Postgres中从这些参数中搜索数据时会出错:

ERROR: column "phone1_.id" must appear in the GROUP BY clause or be used in an aggregate function

我该如何解决?

1 个答案:

答案 0 :(得分:0)

很抱歉这个答案很弱,但是我必须为Oracle解决这个问题(我实际上并不理解为什么它适用于h2)简短回答,你必须做它所要求的,并将该字段添加到组中。这种语法可能不完整,而且错误。

 query.groupBy( root.get("phone").get("id") )