QuerydslPredicate и общий класс

У меня много контроллеров с одинаковыми методами, разница только в классе сущности.

Я хочу создать универсальный BaseController и имею проблемы с аннотацией QuerydslPredicate (не могу установить root, это общий)

class abstract BaseController<T extends BaseEntity> {
   @Autowired
   private Repository<T, Long> repository;

   @RequestMapping(method = RequestMethod.GET)
   public Page<T> findAll(@QuerydslPredicate Predicate predicate, Pageable pageable) {
      return repository.findAll(predicate, pageable);
   }
}

Method extractTypeInfo from QuerydslPredicateArgumentResolver return T. Но нужен класс Entity.

И я не могу установить корневое значение QuerydslPredicate (нет класса)

@QuerydslPredicate(root = T.class)

Любая помощь в том, как этого добиться?


person Yura Heineken    schedule 27.05.2016    source источник
comment
Вы придумали какое-либо решение для этого?   -  person TheKojuEffect    schedule 12.09.2016
comment
У меня такая же проблема, есть решение?   -  person Yunus Einsteinium    schedule 19.01.2017
comment
На самом деле я думаю, что проблема в дизайне Spring Core Predicate. Предикат должен быть разработан как Predicate‹T›, тогда он будет хорошо подходить.   -  person Saurabh Kumar    schedule 04.07.2017
comment
Посмотрите, это может помочь: работа с весенними данными jpa 2 0 7"> stackoverflow.com/questions/51111121/   -  person I_Al-thamary    schedule 08.01.2019


Ответы (1)


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

Но как насчет этого? (много кода, полный пример).

Пружинная база

@SpringBootApplication
public class Application {

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

Объекты

@MappedSuperclass
@Data
@NoArgsConstructor
@AllArgsConstructor
public abstract class BaseEntity {

    @Id
    @Column(name = "id")
    private Integer id;

    @Column(name = "created_at")
    private Date createdAt;
}

@Entity
@Table(name = "user")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class User extends BaseEntity {

    @Column(name = "username")
    private String userName;
}

@Entity
@Table(name = "another_user")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class AnotherUser extends BaseEntity {

    @Column(name = "another_username")
    private String anotherUserName;
}

Контроллеры

public abstract class BaseEntityController<T extends BaseEntity> {

    private final BaseEntityRepository<T> repository;

    @Autowired
    protected BaseEntityController(BaseEntityRepository<T> repository) {
        this.repository = repository;
    }

    @GetMapping(value = "/index")
    public Page<T> index(Predicate predicate, Pageable pageable) {
        return repository.findAll(predicate, pageable);
    }
}

@RestController
@RequestMapping("/user")
public class UserController extends BaseEntityController<User> {

    protected UserController(BaseEntityRepository<User> repository) {
        super(repository);
    }

    @Override
    public Page<User> index(@QuerydslPredicate(root = User.class) Predicate predicate, Pageable pageable) {
        return super.index(predicate, pageable);
    }
}

@RestController
@RequestMapping("/anotheruser")
public class AnotherUserController extends BaseEntityController<User> {

    protected AnotherUserController(BaseEntityRepository<User> repository) {
        super(repository);
    }

    @Override
    public Page<User> index(@QuerydslPredicate(root = AnotherUser.class) Predicate predicate, Pageable pageable) {
        return super.index(predicate, pageable);
    }
}

Репозитории

@NoRepositoryBean
public interface BaseEntityRepository<T extends BaseEntity> extends CrudRepository<T, Integer>, QuerydslPredicateExecutor<T> {
}

@Repository
public interface UserEntityRepository extends BaseEntityRepository<User> {
}

@Repository
public interface AnotherUserEntityRepository extends BaseEntityRepository<AnotherUser> {
}

Он работает и максимально абстрагируется. Вам все равно придется создавать дополнительные классы @Controller и @Repository для каждого @Entity. Хотя в основном это будут пустые окурки. Но я не думаю, что вы можете полностью обмануть @Querydsl или Spring Data, чтобы правильно использовать дженерики в объединении.

person Mikhail Kholodkov    schedule 09.01.2019