Reputation: 67
suppose I have the following entries in the DB:
id | entityId | entityPart | lastModifiedDate |
---|---|---|---|
1 | entity1 | part1 | 28.12.2020 |
2 | entity2 | part1 | 28.12.2020 |
3 | entity3 | part2 | 28.12.2020 |
4 | entity1 | part1 | 30.12.2020 |
5 | entity3 | part2 | 31.12.2020 |
Now, if I want to use spring data to find the entry with the newer lastModifiedData field, I can find it by defining the following method
findFirstByEntityIdAndEntityPartOrderByLastModifiedDateTimeDesc(String entityId, String entityPart)
Is there any way to return a list of all entries that will contain only the the entries that have the newer lastModifiedDate, so in our case it should return the list containing only the entries with ids 2, 4, 5, as for these entries, they have the newer lastModifiedData.
EDIT 1 As a solution I used a sql query like follows, also defined a fix for pagination
@Query(value = "SELECT * FROM orders AS or WHERE LAST_MODIFIED_DATE =\n" +
" (SELECT MAX(LAST_MODIFIED_DATE)\n" +
" FROM orders \n" +
" WHERE (ENTITY_ID = or.ENTITY_ID AND ENTITY_PART = or.ENTITY_PART))"
countQuery = "SELECT COUNT(*) FROM (\n" +
" SELECT MAX(LAST_MODIFIED_DATE) as or\n" +
" FROM orders \n" +
" GROUP BY ENTITY_ID , ENTITY_PART) AS order")
nativeQuery = true)
Upvotes: 0
Views: 130
Reputation: 57
Because you use date without time there will be danger that you going to have duplicate date on entries. If you can modify database, just add boolean value it to identify latest entry. Then you can use List findByBoolean(Boolean true);
Upvotes: 0
Reputation: 4114
In this case, the After
keyword should be used:
(I kept the same ordering as in your example)
List<YourEntityType> findByLastModifiedDateAfterOrderByLastModifiedDateTimeDesc(Date lastModifiedDateAfter)
but, it will be not enough. First, you need to find the last one(with the query you've provided), and then query those entities that are with the value. This can't be done with one repository query, but you can combine multiple ones by defining a default
method. Please note the @Transactional
annotation, the queries should run in one transaction otherwise the result can be inconsistent.
example:
public interface ExampleRepository extends CrudRepository<YourEntityType, Long> {
YourEntityType findFirstByEntityIdAndEntityPartOrderByLastModifiedDateTimeDesc(String entityId, String entityPart);
List<YourEntityType> findByLastModifiedDateAfterOrderByLastModifiedDateTimeDesc(Date lastModifiedDateAfter);
@Transactional
default List<YourEntityType> findByLastModifiedDateOrderByLastModifiedDateTimeDesc(String entityId, String entityPart) {
YourEntityType last = findFirstByEntityIdAndEntityPartOrderByLastModifiedDateTimeDesc(entityId, entityPart);
return findByLastModifiedDateAfterOrderByLastModifiedDateTimeDesc(last.getLastModifiedDateAfter());
}
}
ref: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation
Upvotes: 1