JPA весенних данных: поиск объекта значения с использованием необработанного значения?

#java #spring #hibernate #spring-data-jpa #spring-data

Вопрос:

У меня есть сущность, которая определена со значением Объект как поле:

 class CustomerEntity {

  @Id
  @Column(name = "customer_id", nullable = false)
  private CustomerId customerId;

}
 

Идентификатор клиента определяется как объект значения:

 class CustomerId implements Serializable {
  private final String value;
  //constructor, getter omitted for brewity
}
 

Репозиторий также легко определяется и хорошо работает

 interface CustomerRepository extends JpaRepository<CustomerEntity, CustomerId> {
   Optional<Customer> findByCustomerId(CustomerId customerId);
}
 

Как я могу определить хранилище данных Spring, в котором я мог бы искать клиента по cusomter_id, используя строковое значение?

 Optional<Customer> findByCustomerIdStartsWith(String search);
 

Что-то похожее на SELECT * FROM Customers where customer_id like '?%' ? Насколько я понимаю, мне нужно использовать пользовательское выражение JpaExpression с @Query аннотацией. Но я не могу понять, как я могу преобразовать поле объекта значения в строку…

UPD 1 Нашел обходной путь, но он выглядит немного уродливо…

 @Query("FROM CustomerEntity e where concat(e.customerId, '') like ?1%")
Optional<Customer> findByCustomerIdStartsWith(String search);
 

UPD 2

Поэтому я нашел единственный способ заставить его работать — сделать объект Value как @Embeddable и использовать его в других объектах, как @Embedded и @AttributeOverride с. Тогда решения, предложенные в aswers, будут работать. В качестве недостатка мне нужно сделать пустой конструктор для объекта Value.

Ответ №1:

В документации упоминаются findByFirstnameLike . Будет ли findByCustomerIdLike работать для вас?

Также ознакомьтесь с расширенными выражениями типа «Нравится«.

В расширенной ссылке «Нравится» упоминается: @Query("select u from User u where u.firstname like %?1") для findByFirstnameEndsWith . Поэтому я подумал, что это должно сработать с

 @Query("select c from Customer c where c.customerId.value like ?1%")

List<Customer> findByCustomerIdStartsWith(String id); 
 

Я не стал расширять ответ ранее, так как в другом ответе упоминалось что-то очень похожее, когда я пытался добавить детали. Я предполагаю, что это должно работать с методом equals, реализованным в CustomerID

Комментарии:

1. к сожалению, это не сработает, потому что Spring Data ожидает, что параметр будет иметь тип «Идентификатор клиента». Это приведет к следующей ошибке: org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [34%] did not match expected type [com.mycompany.CustomerId (n/a)]

2. Обновил свой ответ. Надеюсь, это сработает.

3. Я получаю следующую ошибку: org.hibernate.QueryException: could not resolve property: value

4. значение-это поле в классе CustomerID

5. Да, это есть, как собственность, так и getValue() аксессуар . но все равно спящий режим выдает ошибку…

Ответ №2:

Используйте JPQL в @Query и перейдите к CustomerId#value использованию средства доступа. Передайте именованный аргумент в запрос с помощью @Param("search") и обратитесь к нему как :search — он также работает с like 'something%' конструкцией.

 @Query(SELECT * FROM Customers c where c.customerId.value like ':search%'")
Optional<Customer> findByCustomerIdStartsWith(@Param("search") String search);
 

Комментарии:

1. Я получаю следующую ошибку: org.hibernate.QueryException: could not resolve property: value