I have this method defined in a CRUD-Repository :
List<MenuPriceByDay> findAllOrderByUpdateDate();
but when I init the app. I got this error:
Failed to create query for method public abstract java.util.List
com.tdk.backend.persistence.repositories.MenuPriceByDayRepository.findAllOrderByUpdateDate()!
No parameter available for part updateDate SIMPLE_PROPERTY (1): [Is,
Equals] NEVER.
Please can you check this spring jpa documentation ?
It must be like that
// Enabling static ORDER BY for a query
List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
List<Person> findByLastnameOrderByFirstnameDesc(String lastname);
You can apply static ordering by appending an OrderBy clause to the
query method that references a property and by providing a sorting
direction (Asc or Desc).
Related
I am using spring-data-jpa, I want update something, I have annotated my method in PaySupplierSettleBillRepository as
public interface PaySupplierSettleBillRepository extends JpaRepository<PaySupplierSettleBillEntity, Long>,
JpaSpecificationExecutor<PaySupplierSettleBillEntity> {
#Modifying
#Query("update PaySupplierSettleBillEntity p set p.payTime=:payTime,p.paymentOrder=:paymentOrder, p.transferTime=:transferTime, p.transferBank=:transferBank, p.transferOrder=:transferOrder, p.operatorName=:operatorName, p.remark=:remark where p.orderNumber=:orderNumber")
int updatePayInfo(PaySupplierSettleBillEntity entity);
}
I am getting following exception while starting
Caused by: java.lang.IllegalStateException: Using named parameters for method public abstract xxxxxx
how I fix it ? thinks.
That is not how you write a #Query with named parameters. Take a look at the example from Spring documentation here (https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.named-parameters).
If you want to provide an object as param, you can do something like this.
#Query("UPDATE Entity E SET E.name = :#{#entity.name}")
public void updateEntity(#Param("entity") Entity entity);
Caused by: java.lang.IllegalStateException: Using named parameters for method can be thrown when a method has redundant parameter which is not used in the #Query.
In your case, entity should be used in the SQL query like it's mentioned in the previous answer https://stackoverflow.com/a/56053250/5962766 or you should replace it with specifying necessary parameters one by one in the method signature.
Related: IllegalStateException with naming parameters in tomcat
I have entity Composition containing fields Date publicationDate and Boolean archival. I'm trying to get list of Compositions with publicationDate before date passed as argument and having archival flag set to false. After going through some of 'query creation from method names' tutorials and docs i came up with methods
List<Composition> findByPublicationDateBeforeDateAndArchivalFalse(Date date);
or
List<Composition> findByPublicationDateBeforeDateAndArchivalFalse(#Param("date")Date date);
but none of this works. Both gives UnsatisfiedDependencyException with
nested exception is org.springframework.data.mapping.PropertyReferenceException: No property beforeDate found for type Date! Traversed path: Composition.publicationDate.
Intellij also underlines BeforeDate as it cannot resolve property beforeDate. What is the proper way of using those keywords with parameters so the parameters could be distinguished from fields by Spring?
Refactor your method to following:
List<Composition> findByPublicationDateBeforeAndArchivalFalse(Date date);
Before keyword will compare publicationDate with date you pass as an argument, so there is no need to say BeforeDate. Just like an example in Spring Data documentation:
Before -> findByStartDateBefore produces following SQL part … where x.startDate < ?1
I need to lowercase all emails when querying my table, but the documentation specifies only method-name-keyowrd for UPPER():
IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstame) = UPPER(?1)
How the LOWER() could be used?
I have debug it and can see that PredicateBuilder doesn't seem to be considering it.
Are you aware if that is a limitation? Or could this be achieved in different way?
As per the Spring JPA reference guide, findXXXByIgnoreCase(...) by default uses UPPER(...) to perform case insensitive search.
To force it to use LOWER keyword we can use a custom query with #Query annotation and specifying SELECT .... LOWER(email)= LOWER(?1).
In my case I have used custom query as below to force it to use LOWER keyword for email column:
#Query("SELECT p from Person p where LOWER(email) = LOWER(?1)")
List<Person> findByEmailIgnoreCase(#Param("email") String email);
and this resulted in creating following query:
Hibernate: select person0_.id as id1_0_, person0_.email as email2_0_, person0_.first_name as first_na3_0_, person0_.last_name as last_nam4_0_ from person person0_ where lower(person0_.email)=lower(?)
This should help the query to use the function index i.e., LOWER(email).
The Spring Data JPA docs say this about case sensitivy of properties:
// Enabling ignoring case for an individual property
List<Person> findByLastnameIgnoreCase(String lastname);
// Enabling ignoring case for all suitable properties
List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);
Using IgnoreCase in your method name will automatically generate a query which is case insensitiv for one or all specified properties.
Otherwise you always have the possibility to specify a custom query for your method by annotating it like this:
#Query("select u from User u")
Stream<User> findAllByCustomQueryAndStream();
By using the #Query annotation you can use the plain old JPQL to query your database.
I'm using Spring Security Expressions within #Query like this example:
#Query("select o from Pet o where o.owner.name like ?#{hasRole('ROLE_ADMIN') ? '%' : principal.username}")
If you have the role ADMIN, the query returns all the pets. But if you don't have this role, the query returns only Pet objects where the owner name is the same of the user authenticated name.
This works fine, but when I try to use hasAnyRole('ROLE_ADMIN','ROLE_OWNER'), the system returns an exception...
org.springframework.expression.spel.SpelEvaluationException: EL1004E:(pos 0): Method call: Method hasAnyRole(java.lang.String,java.lang.String) cannot be found on java.lang.Object[] type
at org.springframework.expression.spel.ast.MethodReference.findAccessorForMetho
...
In SecurityExpressionRoot is defined the method hasAnyRole:
public final boolean hasAnyRole(String... roles) {
return hasAnyAuthorityName(defaultRolePrefix, roles);
}
I have the same issue, the quick workaround is to write hasRole('ROLE_SUPER') or hasRole('ROLE_OWNER').
This exception is caused by Spring Data, which is not able to resolve methods with a variable number of arguments in SpEL, as far as I can see when debugging.
The ExtensionAwareEvaluationContextProvider method resolver doesn't match hasAnyRole(String[]).
I created https://jira.spring.io/browse/DATACMNS-1518.
EDIT: this issue has been fixed, I just tested latest snapshot and got hasAnyRole work.
I have an #Entity Video having a one-to-many relation with a List<Tag> tags as one of its fields. I use the following #Repository using Spring Data to get the most popular tags:
#Repository
public interface TagRepository extends CrudRepository<Tag, Integer>{
#Query("SELECT t FROM Tag t WHERE (SELECT SUM(v.views) FROM Video v WHERE t MEMBER OF v.tags) > 0")
public List<Tag> findMostViewedTags(int maxTags);
}
The Query is processed and considered valid by Spring, I tested the generated SQL vs my database locally and it returned 2 Tags. In my Code however, I receive the value Null when I call the method findMostViewedTags(100).
The Query lookup strategy is the default "CREATE_IF_NOT_FOUND".
If there are no results found, should the method return an empty list or Null? My desired behavior is to receive an empty list.
Why does the method call return Null instead of a List<Tag> with size() 2?
The normal behavior is indeed returning an empty list if no results are found. If a List<Object> is the return value of the method in the defined interface, the method should never return Null.
The problem is that a parameter is given to the method and is not used anywhere in the Query. For some reason Spring decides to return a Null in that case. Solution: remove the unused parameter or use the parameter in the Query.
I have experienced similar problem. The cause was that I was using Mockito and have not correctly mocked the data with when().