SpringData JPA Repository Method Query with a like? - spring

In Spring-data JPA, is there anyway to create a method query that is essentially searches by like??
I have the following method query
public MakeModel findByModelIgnoreCase(String model);
What I really want is a like expression. Do I need to just create a Criteria or a #Query annotation? Am I asking too much?
//Stupid example of what I want to be able to do
public MakeModel findByFuzzyModelIgnoreCase(String model);
Really I guess at the heart of it, I want to do a table search. I'm using Hibernate underneath Spring Data so I guess I could use some search api like Hibernate Search. I'm open to recommendations here.

If you don't want add "%" manually, you can use the following query methods:
MakeModel findByModelStartingWithIgnoreCase(String model); //SQL => LIKE 'model%'
MakeModel findByModelEndingWithIgnoreCase(String model); //SQL => LIKE '%model'
MakeModel findByModelContainingIgnoreCase(String model); //SQL => LIKE '%model%'

Like is supported too:
MakeModel findByModelLikeIgnoreCase(String model);
When you call the method use the follwing:
Add "%" at the start to say that it doesn't matter to be a strict start match ,
the same at the end, or you can use one of them it depends on the like you want.
MakeModel makeModel = findByModelLikeIgnoreCase("%"+model+"%");
if your make model Is test and the string to compare to is "%"+model+"%" then :
es is a match , T is a match , test is a match
the string to compare to is model+"%":
te is a match , es is not .

Related

Which method does Spring Data Rest use to extract entity from query parameter?

For example, we have a request like this:
GET /orders/search
{
"user": "http://example.org/users/1",
...
}
In what way does Spring Data Rest retrieve the User Entity from an URL? Does it use Regex to retrieve the id 1 then query it or something else?
If yo are wondering about spring data repository, you need to use this method.
User user = userRepository.findById(Integer id);

Update by query multiple fields using Spring Data Elasticsearch?

I want to update all the documents that have for exemple the same name. I've seen in the elasticsearch documentation that I can use _update_by_query. So I tried to implement it in my repository like this:
#Query("{\"script\": { \"inline\": \"ctx._source.name = ?1\"; \"ctx._source.username = ?2\"; \"ctx._source.avatar = ?3\", \"lang\": \"painless\" }, \"query\": { \"match\": { \"name\" : \"?1\" }}")
List<User> update(String name, String username, String avatar);
But I get the following error:
nested exception is ElasticsearchStatusException[Elasticsearch exception [type=parsing_exception, reason=[script] query does not support [inline]]]
at org.springframework.kafka.listener.SeekUtils.seekOrRecover(SeekUtils.java:157) ~[spring-kafka-2.5.0.RELEASE.jar:2.5.0.RELEASE]
Edit 26.06.2020:
This answer is not correct, I added a correct on.
Old incorrect answer:
Seems strange to me, that this error comes from org.springframework.kafka.listener.SeekUtils.
To update using a script, you can use the update(UpdateQuery updateQuery, IndexCoordinates index) of a ElasticsearchOperations instance.
To have this in your Repository, you will need to create a repository cusomization like it is described here. In the implementation, autowire a ElasticsearchOperations instance. In this custom repository interface, you define the method
List<User> update(String name, String username, String avatar);
In the implementation, build up a UpdateQuery object with the script and the other information and pass this to the ElasticsearchOperations instance.
After checking the code of Spring Data Elasticsearch, I need to withdraw what I wrote in the first answer:
Currently Spring Data Elasticsearch does not support update by query. It is only possible to update entities with a know id either in a single operation or in a batch update.
I created an issue in Jira to add support for that.

How to Return all instances of the type with the given ID in JPA SpringBoot?

I'm trying to return (or fetch) all the records from the database based on an ID provided by me. I'm using JPA and i'm aware of findAll() method but it returns all the records without any criteria, I created a custom query and it is only returning a unique value from the table but i want to return all records based on a criteria.
For example, findAllByUserID(String UserID) method should return all the records based on that UserID not just one.
I'd appreciate any help or suggestion.
Thanks
Have a look at the doc. There you will find the keywords you can use to declare methods in repository interfaces that will generate the according queries:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods
In your case: If userID is an attribute of your entity you can add a method
List<YourEntity> findByfindAllByUserID(String userId)
to your repository interface.
First, make sure that you're not using any aggregate function in your select query such as DISTINCT()
Then make sure that the the method which is implementing that query is returning a List of you're desired result.
here's how it should look :
#Query("select t from table t where t.code = ?1")
List<Result> findAllByUserID(String UserID);

How to get top results using specifications in spring data jpa?

I am quite new to spring data jpa. I am trying to use specifications while querying database. My question is using crudrepository we can method like :
findTopByUsernameOrderByUpdatedAtDesc(String username);
How can I achieve the same using specifications? I can do basic things like and or in specifications, but not very robust like we can do with criteria etc.
Specification<CustomClass> spec = Specifications.where(specification).and(username);
List<CustomClass> list = findAll(spec);
This was done as follows :
Pageable pageable = new PageRequest(0, 1, Sort.Direction.DESC, "username");
Page oneElementPage = repository.findAll(spec, pageable);
This will sort the data on username column in descending direction and return first result.
You can't express this in a Specification directly. But you can use a Pageable for this:
Page oneElementPage = repository.findAll(spec, new PageRequest(0, 1));
Gives you a Page with a single element.

How to make a custom sorting query in spring boot for a mongo db repository?

I want to put this query with #Query annotation in my repository.
This is the query:
`db.report.find({'company' : 'Random'}).sort( { 'reportDate' : -1} ).limit(1)`
Which is the best way to implement custom queries with #Query annotations or to use MongoTemplate ?
Using Mongo Template.
Criteria find = Criteria.where("company").is("Random");
Query query = new Query().addCriteria(find).with(new Sort(Sort.Direction.DESC, "reportDate"));
BasicDBObject result = mongoOperations.findOne(query, BasicDBObject.class, "collection_name");
Using Mongo Repository
Report findTopByCompanyOrderByReportDateDesc(String company)
Note that in the new version of Springboot(v2.2.5), the correct method is sort.by().
like this:
Query query = new Query().addCriteria(find).with(Sort.by(Sort.Direction.DESC, "reportDate"));

Resources