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.
Related
I have two Queries:
Query1(pagable) first datasource
Query2(pagable) second datasource
I would like to do something like this
Page results = merge(query1, query2)
How i can do this in JPA ?
Are both queries on the same entity? If so you can collect the content from both in a list (List<T> content) and build a new page object. Something as follows:
Page<T> mergedResult = new PageImpl(List<T> content);
https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/PageImpl.html
Actually, I wanted to retrieve the Top 500 records in a table. I knew spring data has internal method findTop500 method for it. My question is can this 500 be passed dynamically? Suppose if my requirement changes to get Top1000 I don't want it to modify again.
Assuming you are asking about Spring data-methods
You can use a Pageable object to dynamically set how many entries you want to retrieve.
You can use it like this:
PageRequest pageRequest = new PageRequest(0, maxResults);
List<Record> records = repository.findAll(pageRequest);
List<Record> records = repository.findAllByKey(key, pageRequest);
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"));
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 .
I am using spring data jpa with hibernate as jpa persistence provider.
I am using native queries in my application. There are some update queries and I would like to get the actual number of records updated when the update query gets executed. Is there a way in spring data jpa to do this?
I am currently following the below approach;
#Modifying
#Query(value="update table x set x_provision = ?1 where x_id = ?2", nativeQuery=true)
int updateProvision(Integer provision, Integer id);
#Transactional is added on service layer.
The problem here is that when the table gets updated I get the count as 1. But there are some cases where no rows are updated. In this case also I get the count as 1. But I would like to receive the actual number of records updated which sometimes is 0.
Can someone let me know if I am doing something wrong here?
If you take a look at ModifyingExecutor, which is used to execute this query
#Override
protected Object doExecute(AbstractJpaQuery query, Object[] values) {
int result = query.createQuery(values).executeUpdate();
if (em != null) {
em.clear();
}
return result;
}
Then you see, it only delegates to native JPA infrastructure, to return number of updated elements.
So, this might have to do with used database or ORM framework configuration, other than that, the query you wrote should return correct result.