How to query documents with null values MongoRepository Spring Data MongoDB - spring

I couldn't initialise the value to be false in Spring Data MongoDB, so in my query, I want to search documents with field set to false or null.
The following snippet doesn't seem to work:
#RestResource(rel = "findInactiveOrders", path = "findInactiveOrders")
Order findByIdAndIsActiveFalseOrIsActiveNull(#Param("id"))

I'm not sure you can achieve such query using Spring data method name. Since your query will be evaluated as _id == "id" AND isActive == false OR isActive == null and not _id == "id" AND ( isActive == false OR isActive == null ).
If by chance isActive can only be true, false or null, you could try
#RestResource(rel = "findInactiveOrders", path = "findInactiveOrders")
Order findByIdAndIsActiveNot(#Param("id"), true)
Otherwise, you will need to use other query method provided by Spring data mongodb such as MongoTemplate helper class or #Query annotation.
#Query annotation
#RestResource(rel = "findInactiveOrders", path = "findInactiveOrders")
#Query("{$and: [{'_id': :#{#id}}, $or: [{ 'isActive':false}, {'isActive': null}]]}")
Order findByIdAndIsActiveNot(#Param("id"))

Related

#Value on R2dbc table fields

Given the following entity/table defined in a Spring/KotlinCoroutines project.
#Table("workers")
data class Worker(
#Id
val id: UUID? = null,
#Column(value = "photo")
var photo: String? = null,
// see: https://github.com/spring-projects/spring-data-r2dbc/issues/449
#Transient
#Value("#{root.photo!=null}")
val hasPhoto: Boolean = false
)
The hasPhoto field does not map to a table field. I follow the R2dbc official reference doc and use a Spring EL to evaluate the EL result as value of this field.
But when I test this hasPhoto, it always returns false even I set the photo to a nonnull string.
Got answer from the Spring guys, #Value here only can access the projection.

Spring JPA: Use CriteriaBuilder to filter on a datetime between two instants

I'm setting up a method to filter entries by the "lastupdated" column. I'm trying to filter entries of which the lastupdated value is between a given startTime and endTime.
I'm using the simplified code below:
public List<SomeEntity> getItemsByLastUpdated() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<SomeEntity> criteriaQuery = cb.createQuery(SomeEntity.class);
var root = criteriaQuery.from(SomeEntity.class);
var predicates = new ArrayList<>();
var startTime = Instant.now();
var endTime = Instant.now().plus(5, MINUTES);
predicates.add(cb.greaterThanOrEqualTo(root.get("lastupdated"), startTime));
predicates.add(cb.lessThan(root.get("lastupdated"), endTime));
criteriaQuery.where(predicates.toArray(new Predicate[0]));
return entityManager.createQuery(criteriaQuery).getResultList();
}
For some reason, the criteria for datetime fields are not (correctly) being applied: All the entities are being returned instead of only the items within the startTime-endTime range.
I'm guessing that I need to explicitly state that the "lastupdated" field is a datetime field; when I set startTime to Instant.MAX, I receive an error that seems to hint on a date filter instead of datetime:
Invalid value for EpochDay (valid values -365243219162 - 365241780471): 365241780838
Would anyone know how I can filter on a datetime field being between two given java Instants?
PS. I'm aware of using derived queries such as findByXGreaterThanOrEqualToAndXLessThan(Instant instant1, Instant instant2); but since there are several other criterias which I have not included, this option is not feasible.
I think you could easily do the same using EntityManager and JPQL instead of Criteria API:
public List<SomeEntity> getItemsByLastUpdated() {
var query = "select e from SomeEntity e
where e.lastupdated >= :from
and e.lastupdated < :to
and your_other_criteria";
return entityManager.createQuery(query)
.setParameter("from", startTime)
.setParameter("to", endTime)
.getResultList();
}
It took me quite some time to figure it out; turned out that the lack of filtering didn't have anything to do with the CriteriaBuilder setup.
I had created a test to verify the method, and prepared some entities before running the test. However, the "lastupdated" field in the entity class was annotated with #UpdateTimestamp, which would result in all the saved entities having pretty much the same 'lastupdated' value.

Dealing with nullable UUID in a controller - SpringBoot and Postgres

I have an entity that includes a nullable UUID (but it is not an ID), as follows:
#Column(nullable = true)
var myField: UUID? = null
I also have a dto converter as follows:
myField = entity.myField.let { it }
I can correctly store a null value for the UUID field, but when inspecting the GET response from my controller whenever I pass a null value for such field the body does not contain the myField at all. What is the reason for that? How does SpringBoot deal with null value for UUID.
Thanks

Spring Data Elasticsearch Problem with IP_Range Data type

I use Spring boot 2.0.1.RELEASE/ Spring Data Elasticsearch 3.0.6.
I annotate my domain class with #Document annotation and i have a field as below:
#Field(store = true, type = FieldType.?)
private String ipRange;
as you see, I need to set the field type to IP_Range (exists in elastic search engine data types)
but not exists in FieldType enum.
I want to create this document index by ElasticsearchTemplate.createIndex(doc) method. but none of any FieldType enum support ip_range data type.
Spring Data Elasticsearch currently (3.2.0.M2) does not support this. I saw that you already opened an issue, thanks for that. The answer here is just for the completeness and for other users having the same problem
Thanks #P.J.Meisch for your reply, I used #Mapping annotation to specify my mapping directly via json format. Already Spring data supports creating index based on this config. but i am also waiting for Range Data Structure Support to refactor my code.
My Document:
#Document(createIndex = true, indexName = "mydomain", type = "doc-rule"
, refreshInterval = BaseDocument.REFRESH_INTERVAL, replicas = BaseDocument.REPLICA_COUNT, shards = BaseDocument.SHARD_COUNT)
#Mapping(mappingPath = "/elasticsearch/mappings/mydomain-mapping.json")
public class MyDomainDoc {
#Field(store = true, type = FieldType.text)
private List<String> ipRange;
... other fields
}
And My mydomain-mapping.json file:
{
"properties": {
...,
"ipRange": {
"type": "ip_range",
...
},
...
}
}

Query database with JPA for null values

The value in database can be sometimes NULL and sometimes not. How can I retrieve it?
This is my try which makes me suprised:
#Repository
public interface AddressRepo extends JpaRepository<Address, Long>{
#Query("select count(a) > 0 from Address a where a.street = :street")
boolean testtest(#Param("street") String street);
}
test OK:
// given
address = new Address("WIELKA WARSZAAAWA", "Bokserska", "xxx", "50-500");
// when
addressRepo.save(address);
// then
assertTrue(addressRepo.testtest("Bokserska")); // OK
test fails:
// given
address = new Address("WIELKA WARSZAAAWA", null, "xxx", "50-500");
// when
addressRepo.save(address);
// then
assertTrue(addressRepo.testtest(null)); // cuz false!
The JPQL is not able to translate this statement:
WHERE a.street = null
To this SQL:
WHERE a.street IS null
So, you need to create a new #Query:
select count(a) > 0 from Address a where a.street IS NULL
Mount manually the JPQL string or use Criteria to create a dynamic query are also good options.

Resources