Spring JPA findBy accent - spring-data-jpa

I am developing a spring-data-jpa application.
I 've ridden the repository with findBy but does not work when I look content with an accent. Does anyone know why?
I am using the following:
Page<Dades> findByNomcomercialIgnoreCaseContaining (#Param ("nomcom") String nomcom, Pageable pageable);
The database is Oracle.
Thanks for your interest.

It's because ignoreCase does not deal with accents. It only compares both String after uppercasing them. See the documentation for more informations.
I don't know any simple solution to ignore accents with Spring Jpa. You coud either :
Remove this parameter in your query, and filter the result in Java afterward (comparing Strings after doing org.apache.commons.lang3.StringUtils.stripAccents).
Use Spring Jpa Specifications. Again, it provides only functionslike upper, like, ... so you have to write your own, depending on what database you are using.

#Param is not required. if you have any query i.e if you are using #Query then we need use #param to pass the specific value releated to query.Below you can check how to use #Query and #Param
#Query("SELECT t.title FROM Todo t where t.id = :id")
String findTitleById(#Param("id") Long id);
if you are not added these annotation use in your repository layer
#Transactional
#Repository
Check another thing i.e
#Transactional
#Repository
public interface IXyzRepository extends CrudRepository<ABC,Integer>{
//some methods you have
}
whether the primary id of class ABC is of type Integer

Related

Convert Spring's Order to JPA Order from Pageable

Our frontend is designed to send Pageable object with Spring's Order which contains attribute name.
Sample Entity:
#Entity
#Table
public class Foo {
private String userName;
#Embedded
private Bar bar;
}
#Embeddable
public class Bar {
private String value;
}
We receive pageable with order in repository and parse JPA's Order from that pageable object like this:
pageable.getSort().get().forEach(springOrder ->
jpaOrders.add(getBuilder().asc(root.get(springOrder .getProperty())))
);
We need do it this way because we are building queries via criteria api.
When we receive in repository attribute of Foo, everything is fine, e.g. "userName". But when we receive attribute of embeddable entity, e.g. "bar.value" we got exception
Unable to locate Attribute with the the given name [bar.value] on this ManagedType
Can you tell me how to create JPA's Order object from attribute which define attribute of embeddable entities? Thank you in advice
For these property paths you will have to create joins and apply the Order using the proper join alias and the last part of the property path.
For more details, I'd recommend looking into the code of Spring Data JPA.
Find all references to the Order class and start reading some code.
Have you tried using org.springframework.data.jpa.repository.query.QueryUtils#toOrders ?

Spring JPA findByColumnNameLike not working

I have a method -> findByfileNameLike(fileName,1, pageable) and its declaration in a repository that extends JPA Repository is
#Query(value = QUERY)
#Transactional(propagation = Propagation.REQUIRED, readOnly = true)
#LogExecutionTime
Page<BatchDTO> findByfileNameLike(String
fileName,#Param("departmentId")Integer departmentId, Pageable pageable)
Query is Select new DTO(bdm.id.batch.status) from Table bdm where bdm.id.departmentId =:departmentId and bdm.id.batch.status <> 7";
I want to filter the query by the column fileName.I have read to give the method name as given according to the doc of spring data jpa.But its not working.
Where and how will i give the fileName to be filtered?Should it be first parameter in the method?
Once you specify a query using the annotation #Query, Spring data jpa will not automatically create a query for you based on the method name and it will rely on the query provided by using the annotation.
The method findByfileNameLike will not make any difference here as a query is provided explicitly. Hope that answers your question

Spring LDAP JPA - Limit number of result

I'm using spring-ldap 2.0.4 and spring-data-jpa 1.9.0.
I built a JPA repository like this :
public interface PersonRepo extends LdapRepository<Person> {
Person findByUid (String uid);
#Query("(&(attribute=*{0}*)(attribute2=X)(attribute3=Y))")
List<Person> findByAttributeContains(String attribute);
}
So far everything is fine. I could write methods that fill my needs thanks to query methods.
For some queries i had to use #Query annotation because they were many and operator.
But i would like to limit the number of result to return from my second query method.
I know there is there is the Top and First keywords to define query methods in spring JPA. But I didn't manage to get it work. Plus I want to use multiple and operator in the method.
Thanks
I managed to limit the number of result using XML LDAP configuration.
<ldap:ldap-template context-source-ref="contextSource" count-limit="100"/>

Is it possible to use SpringData MongoDB repository to execute an arbitrary query, with pagination?

We have a use case where a user can pass in arbitrary search criteria for a collection, and wants the output paged. Using Spring Data repositories, this is quite simple if we know ahead of time what attributes they may be searching on by simple extending MongoRepository, and declaring a:
Page<Thing> findByFooAndBarAndBaz(Type foo, Type bar, Type baz, Pageable page)
However, if we generate the query ourselves either using the fluent interface or constructing a mongo string and wrapping it in a BasicQuery class, I can not find a way to get that into a repository instance. There is no:
Page<Thing> findByQuery(Query q, Pageable page)
functionality that I have been able to see.
Nor can I see how to hook into the MongoTemplate querying functionality with the Page abstraction.
I'm hoping I don't have to roll my own paging (calculating skip and limit parameters, which I guess is not hard) and call into the template directly, but I guess I can if that's the best choice.
I don't think this can be done in the way I'd hoped, but I've come up with a workaround. As background, we put all our methods to do data access in a DAO, and some delegate to the repository, some to the template.
Wrote a DAO method which takes our arbitrary filter string (which I have a utility that converts it to standard mongo JSON query syntax.
Wrap that in a BasicQuery to get a "countQuery".
Use that countQuery to get a total count of records using MongoTemplate#count(Query, Class)
Append my paging criteria to create a "pageQuery" using Query#with(Pageable)
Run the pageQuery with MongoTemplate#find(Query, Pageable)
Get the List<T> result from that, the Pageable that was used for the query and the count returned from the countQuery run, and construct a new PageImp to return to the caller.
Basically, this (DocDbDomain is a test domain class for testing out document db stuff):
Query countQuery = new BasicQuery(toMongoQueryString(filterString));
Query pageQuery = countQuery.with(pageRequest);
long total = template.count(countQuery, DocDbDomain.class);
List<DocDbDomain> content = template.find(pageQuery, DocDbDomain.class);
return new PageImpl<DocDbDomain>(content, pageRequest, total);
You can use the #Query annotation to execute an arbitrary query through a repository method:
interface PersonRepository extends Repository<Person, Long> {
#Query("{ 'firstname' : ?0 }")
Page<Person> findByCustomQuery(String firstname, Pageable pageable);
}
Generally speaking, #Query can contain any JSON query you can execute via the shell but with the ?0 kind of syntax to replace parameter values. You can find more information on the basic mechanism in the reference documentation.
In case you can't express your query within the #Query-Annotation, you can use the Spring Repository PageableExecutionUtils for your custom queries.
For example like this:
#Override
public Page<XXX> findSophisticatedXXX(/* params, ... */ #NotNull Pageable pageable) {
Query query = query(
where("...")
// ... sophisticated query ...
).with(pageable);
List<XXX> list = mongoOperations.find(query, XXX.class);
return PageableExecutionUtils.getPage(list, pageable,
() -> mongoOperations.count((Query.of(query).limit(-1).skip(-1), XXX.class));
}
Like in the original Spring Data Repository, the PageableExecutionUtils will do a separated count request and wrap it into a nice Page for you.
Here you can see that spring is doing the same.

Spring Data JPA finder for dynamic fields as Map

My requirement is to have few custom fields in the domain objects. These fields may vary as per the clients.
We are using Spring Data JPA to execute finders. Spring data implicitly provides finders for static fields of the domain and can also handle finders for the fields in the object graph.
I want to know if there is a way to find data on the custom fields? Can someone suggest me a strategy to achieve the same. Below is the sample of my domain class.
public class Employee{
private String name;
private String age;
private Map customeFields; (May vary as per client)
}
I was thinking of overriding QueryLookupStrategy and create my CustomJpaQuery on lines of PartTreeJpaQuery to achieve it. Is there any better approach? Does spring data jpa provides an easy mechanism to override query creation mechanism?
If you are using hibernate (not sure about other JPA implementations) you may add methods with #Query annotations like this:
#Query("select e from Employee as e where e.customeFields[:key] = :value")
List<Employee> findSomeHow(#Param("key") String key, #Param("value") String value)