#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