Query on boolean field on ElasticSearch repository - elasticsearch

I am using ElasticsearchRepository and want to query on boolean property.
Sample snippet here:
class TempBean
{
private boolean isActive;
}
interface MyEntityRepository implements CrudRepository<MyEntity, Long>
{
TempBean findByIsActiveTrue();
}
How to query on the active property without passing it as param to the abstract method?
This is possible if I would have JpaRepository as per this answer how-to-query-for-boolean-property-with-spring-crudrepository

It is possible, as can be seen in the docs. Just remove "Is" from your function:
interface MyEntityRepository implements CrudRepository<MyEntity, Long>
{
TempBean findByActiveTrue();
}
As a side note, I don't know about your schema but I would suggest you use Page<TempBean> as your return type, which would require PageRequest as an argument. This is in case more than one TempBean docs have "active":"true" and your function is likely to return more than one records.

Related

Spring Data: can I create a method in the #Repository with a name what return list of object if String equals to constant?

Guess easier if I show you my example:
#Entity
class User {
Long id;
Status status;
}
enum Status {
NEW("N"), DELETED("D")
}
I have an AttributeConverter on Status so in DB the enum is stored with one character.
In my database I have entities like:
Table user
------------
Id Status
1 N
2 N
3 D
4 N
5 D
I want a method that list the Users with Status D. Something like this:
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByStatusEqualsD();
or
List<User> findByStatusEqualsDeleted();
problem is these are not working
}
I could write this:
List<User> findByStatus(Status status);
And call it as repo.findByStatus(Status.DELETED) but I want a method what returns only the deleted users.
If I call it as repo.findByStatus(Status.NEW) then it will return the new users.
I prefer to not write a #Query, I hope it is possible what I'm asking without doing it...
Thanks in advance.
Such behavior is not supported.
Method name is translated into JPQL expression (which is the same as used in #Query) with parameters in it (if needed) so you have to provide these. (https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation)
If you want query parameters to be hardcoded - #Query is what you need.
Alternatively you can have default method in your repository calling the parametrized one as mentioned here JpaRepository with Enum: findAllByOfferState_ACTIVE. NoSuchElementException
Easy,
You don't need a repo for that. Create a Service instead:
public interface UserDAOService{
List<User> getAllDeletedUsers();
}
And then just implement it with hardcoded findByStatus method from repo:
#Service
public class UserDAOServiceImpl implements UserDAOService{
private final UserRepository userRepository;
public UserDAOServiceImpl(UserRepository userRepository) {
this.userRepository= userRepository;
}
#Override
public List<Author> getAllDeletedUsers();
return userRepository.findByStatus(Status.DELETED);
}

Best approach to create different JSON response from same Entity

I have an entity class User with 20 fields, some of them being confidential fields. I have a controller class, which has a method getUser to fetch all the user from DB and send the JSON respone. Below is the sample code for the same:
#GetMapping("/getUsers")
public UserDT getUsers( Model theModel) {
List<User> userList;
userList = userService.findAll();
return userList;
}
When I run the above code, it returns all the fields from User table/User Entity Class. Instead of sending all the fields, I would like to send selected fields say Field1 to Field5 only.
Ultimate goal is to have multiple views for the same Entity Class. For URL1 I would like to show only field1 to field5 of User table, But for URL2 I would like to show Field9 , Filed15, Field20.
Do I need to create multiple Entity Class for each URL? Please guide me with the best practice to be followed in such scenario.
Assuming you are using Spring Data JPA, use projections.
So create different projections for your different URLs write a method that returns the projection (or a dynamic one as in the documentation).
public interface NamesOnlyProjection {
String getFirstName();
String getLastName();
}
public interface UserinfoProjection {
String getUsername();
String getPassword();
String getDepartment();
}
Then in your repository do something like this
public interface PersonRepository extends JpaRepository<Person, Long> {
<T> List<T> findAll(Class<T> type);
}
Then you can do something like this in your controller/service
#RestController
public class PersonController {
private final PersonRepository persons;
#GetMapping("/people/names")
public List<NamesOnlyProjection> allNames() {
return persons.findAll(NamesOnlyProjection.class);
}
#GetMapping("/people/users")
public List<UserinfoProjection> allNames() {
return persons.findAll(UserinfoProjection.class);
}
}

How to Define Dynamic Model in Spring Framework

I am using Spring Framework as my back end
I have define know as Entity class The Entity class know contain 5 Fields
Below is the class , The code below dose not have setter getter part to make shorter and cleaner
#Entity
#Table(name="TblKnow")
public class Know {
#Id
private Double idKnow;
private String SubjectKnow;
private String BodyKnow;
private String ImgKnow;
private double CountView;
In JpaRepository interface i want to only query two column not all of columns.
public interface KnowRepository extends JpaRepository<Know,Double> {
#Query("SELECT idKnow,SubjectKnow FROM Know")
public Page<Know> findCByOrderByIdKnowDesc(Pageable pageable);
Problem: i try to run but i get below exception
java.lang.IllegalArgumentException: Cannot create TypedQuery for query with more than one return using requested result type [java.lang.Long]
But if i use without below query it is fine
public Page<Know> findAllByOrderByIdKnowDesc(Pageable pageable);
You can create a custom constructor and use that to select only some fields in JPA query.
public Know(Double idKnow, String SubjectKnow) {
this.idKnow = idKnow;
this.SubjectKnow = SubjectKnow;
}
And the use this constructor in JPA query. Make sure you use complete path of class with package.
#Query("SELECT NEW packagePath.Know(idKnow,SubjectKnow) FROM Know")
query :
public Page<Know> findAllByOrderByIdKnowDesc(Pageable pageable);
works dut to you select Know objects with fields that are mapped correct into Know class (and after wrapped into Page).
with query :
#Query("SELECT idKnow,SubjectKnow FROM Know")
public Page<Know> findCByOrderByIdKnowDesc(Pageable pageable);
returns some custome bean/object that spring data can't map in correct way into Know class (as you declared it as expected return class wrapped into Page). add counstructor into Know with idKnow,SubjectKnow fields , or you can wrap it into some DTO with idKnow,SubjectKnow fields.

How to write a findByCritera1InAndCritera2In using (spring data) CrudRepository with parameters being optional

I'm using spring boot with spring data, specifically the class PagingAndSortingRepository that extends CrudRepository.
I need a query which returns all entries of a table if matches either of the four lists ignoring it when it is null (or empty).
If I use findByTypeInAndLocaleInAndCategoryInAndTagIn and one of the lists is empty, the result is empty as well. So I ended up writing several finders and depending on which lists are empty using a different one. Is it possible to combine this in one finder?
So e.g. if I use findByTypeAndLocale I'd like to match all values of type if the list type is empty.
Happy about any hints.
#Repository
public interface FeedRepository extends PagingAndSortingRepository<FeedEntry, Long>, JpaSpecificationExecutor<FeedEntry> {
public List<FeedEntry> findByGuid(String guid);
public Page<FeedEntry> findAll(Pageable pageable);
public Page<FeedEntry> findByLocale(List<LocaleEnum> type, Pageable pageable);
public Page<FeedEntry> findByType(List<FeedTypeEnum> type, Pageable pageable);
public Page<FeedEntry> findByTypeAndLocale(FeedTypeEnum type, LocaleEnum locale, Pageable pageable);
public Page<FeedEntry> findByTypeInAndLocaleIn(List<FeedTypeEnum> type,List<LocaleEnum> locale, Pageable pageable);
public Page<FeedEntry> findByTypeInAndLocaleInAndCategoryIn(List<FeedTypeEnum> type,List<LocaleEnum> locale, List<String> category, Pageable pageable);
public Page<FeedEntry> findByTypeInAndLocaleInAndTagIn(List<FeedTypeEnum> type,List<LocaleEnum> locale, List<String> tag, Pageable pageable);
public Page<FeedEntry> findByTypeInAndLocaleInAndCategoryInAndTagIn(List<FeedTypeEnum> type,List<LocaleEnum> locale, List<String> category, List<String> tag, Pageable pageable);
}
You cannot do it as you are doing. If the list is empty means there isn't any value which matches with your condition query.
To do what you are looking for you need to do it with QBE (Query By example) which is compatible with CrudRepository
QBE doc
Why? You need a dynamic query and as the doc says:
Query by Example (QBE) is a user-friendly querying technique with a
simple interface. It allows dynamic query creation and does not
require to write queries containing field names. In fact, Query by
Example does not require to write queries using store-specific query
languages at all.
An example of the doc:
public interface PersonRepository extends JpaRepository<Person, String> { … }
public class PersonService {
#Autowired PersonRepository personRepository;
public List<Person> findPeople(Person probe) {
return personRepository.findAll(Example.of(probe));
}
}
**Making example for your case...
I'm affraid it is not possible at the moment.
IMHO the best way you can achieve your goal is to use Spring Data JPA Specifications (http://docs.spring.io/spring-data/jpa/docs/1.10.2.RELEASE/reference/html/#specifications) and manually check every parameter for not null value...

How to use Or condition in PagingAndSortingRepository

I need to use two or more conditions on different fields in a Repository that extends PagingAndSortingRepository.
For example:
public interface PersonRepository extends PagingAndSortingRepository<Person,String> {
Page<Person> findByCreatedUser(String createdUserId, Pageable pageable);
}
This method should filter by createdUserId=Person.createdUserId or createdUserId=Person.userId.
How can this be done?
Never mind. I found the answer.
Page findByCreatedUserIdOrUserId(String createdUserId, String userId, Pageable pageable);
Just define a method and add the #Query annotation as outlined in the documentation:
public interface PersonRepository extends PagingAndSortingRepository<Person,String> {
#Query("......")
Page<Person> findByCreatedUser(String createdUserId, String userId, Pageable pageable);
}
http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query

Resources