Change default behaviour of mongoTemplate.find - java

Is there any way to modify every query prepared by mongotemplate.find spring boot 2?
I want to modify every find query prepared by spring data mongo find . I want to add custom query after every find query to mongo.
How can I achieve that in spring boot 2.

I want to override find methods of mongo template with my own implementation and want to add some custom query on top of find query which was built by crud repository methods.

I want to add some custom query by overriding methods of mongotemplate to every find method of crud repository

you would need to customize the repository class implementation for the mongoDB.
below is the sample code to help you understand how to add customized query in the repository. you would need to twik the code as per your requirement after getting the result.
public interface PersonRepository extends PagingAndSortingRepository<Person, String> {
List<Person> findByLastname(String lastname);
Page<Person> findByFirstname(String firstname, Pageable pageable);
Person findByShippingAddresses(Address address);
}
you can visit this page for proper understanding
https://docs.spring.io/spring-data/mongodb/docs/1.2.0.RELEASE/reference/html/mongo.repositories.html

Related

How to render data from multiple tables from MySQL using React, Spring Boot?

I have four tables in a database. When the user uses the Search option from the React application I want the search button to query all the tables and display data from all the tables which is AWS RDS MYSQL. How should I proceed? I am using Spring boot, mysql, and react.
I would recommend taking a look at JPA Respositories. Since your db seams to be small, a simple repository method like that one should make the trick.
However, if you have a more complicated requirement, you can use a Spring Projection. Create a query that retrieves all the fields you'll need, even if they're from different tables, and map the result into a Spring Projection
Using spring data jpa you should create a method in your repository that returns a list of your projection class:
public interface MyRepository extends Repository<MyEntityProjection, Long> {
#Query("SELECT ... WHERE field = ?1")
List<MyEntityProjection> getData(String param);
}
The projection class should be something like this:
public interface MyEntityProjection {
String getField();
String getField2();
}
Adding as many fields as your query returns.
Read the docs I linked for more information and examples.

how to write not in clause using springboot findAll() method

I am try to get data from the database using spring boot JPA and CRUD Repository findAll() method with using not in clause but not find any where. There is any solution making dynamic query using findAll() method.
Example:
hql="select * from urlMaster urlmast where urlmast.urlcd not in (select distinct acturl.acuCd from ActionUrl acturl) order by urlmast.urlcd";
Currently I am just getting data from the urlMaster data. But i want acturl.acuCd not in ActionUrl table.
Repository class:
public interface ActionUrlRepository extends CrudRepository<urlMaster, Long>,JpaRepository<urlMaster, Long> {
}
Service implementation:
actionurlrepository.findAll();
If there is any provision? Please guide me. Thanks!
You could put your query string in an #Query annotation, as described in https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query
So something like :
public interface ActionUrlRepository extends JpaRepository<urlMaster, Long> {
#Query("select * from urlMaster urlmast where urlmast.urlcd not in (select distinct acturl.acuCd from ActionUrl acturl) order by urlmast.urlcd")
List<urlMaster> findByNotIn();
}
By the way, you don't need CrudRepository on the declaration, since JpaRepository already extends from it (via PagingAndSortingRepository).

How to specify spring data jpa request to load collection of entity properties?

I use spring data JPA. I need in my repository request to load only collection of concrete properties colors:
#Query(value = "SELECT cd.color FROM CalendarDetails cd where cd.userCalendar.userId = :userId")
List<String> findCalendarColorsByUserWithDuplicates(#Param("userId") Long userId);
Provided solution works correctly.
I want simplify it using spring approach to load collection of the repository objects I'd use (repository public interface CalendarDetailsRepository extends JpaRepository<CalendarDetails, Long>):
List<CalendarDetails> findByUserCalendarUserId(#Param("userId") Long userId);
But I need collection of colors! Trying
List<String> findColorByUserCalendarUserId(Long userId);
I get collection of CalendarDetails
Is it possible to improve my last request following spring data approaches to load list of colors?
You can try special Projection mechanisms that Spring Data provides. It will allow you not only to optimize your queries but also to make it with pure java without using #Query.
There are a lot of ways to
make it, but I would recommend the following.
You add an interface that contains getters for the properties that you need to take from entity:
public interface ColorOnly {
String getColor();
}
Then you return the list of this interface' objects:
List<ColorOnly> findColorByUserCalendarUserId(Long userId);
To use the colours from the interface, you just invoke getColor method. You may consider simplifying it with Java 8 streams and map conversions. BTW, this one will only query colour. No other fields will be included into the query Hibernate produces.
Try to add All
findAllByUserCalendarUserId(Long userId);
BTW, IntelliJ IDEA provide very deep support of JPA repositories, so it's prevent a lot of possible issues when you create queries like this one

Spring data repositories - parameter what to retrieve all records?

#Repository
public interface UserDao extends User {
public List<User> findByFirstname(String firstname);
}
How could I use above code to retrieve all records?
I tried findByFistname(null);, it doesn't work...
I don't want to use findByFirstname(); because it's possible to have parameter.
Hope you all understand.
Have you considered using a spring data specification? In spring data a specification is a way to wrap the JPA criteria api.
The idea behind the JPA Criteria api is to generate queries programatically, by defining query objects.
Once you have encapsulated the criteria in a specification objects, a single findAll method can be used in a number of scenarios. For example programatically add criteria based input form the user, such as additional search filters etc.
To use this feature a repo will need to extend "JpaSpecificationExecutor"
public interface UserRepository extends JpaRepository<User>, JpaSpecificationExecutor {
List<T> findAll(Specification<T> spec);
}
The find method can then be called with multiple criteria, or the criteria can be built dynamically based on the situation:
List<User> users = userRepository.findAll(where(userLastNameIs("John")).and(userIsArchived()));
Alternatively you can also try query by exampe. The idea here is to provide the actual domain object with the populated search fields to an example matcher. Configure the example matcher to control the search and pass it to the findAll method.
Again the repo will need to implement an interface. Check the documentation for the detailed pros/cons of each approach.
Person person = new Person();
person.setFirstname("Dave");
ExampleMatcher matcher = ExampleMatcher.matching()
.withIgnorePaths("lastname")
.withIncludeNullValues()
.withStringMatcherEnding();
Example<Person> example = Example.of(person, matcher);
List<Person> people = personRepository.findAll(example);
You should extend your repository from JpaRepository. Be careful with name of repository (It should follow convention). After you inject your UserRepository bean you will have already implemeted by spring data crud methods like findOne(), findAll(), delete() etc.
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
//assume your primary key is Long type
}
Also will be useful documentation
As I got from comments you're trying to achieve ignorance of null values of passed parameters (instead of retrieving all records by findAll()).
Unfortunately, currently, it's not supported by Spring .
You could leverage the #Query annotation and write the query manually in such manner:
#Query("select u from User u where "
+ "(:firstname is null or u.firstname = :firstname)"
+ "(:lastname is null or u.lastname = :lastname)"
)
public List<User> findUserByFirstNameAndLastName(
#Param("firstname") String firstname,
#Param("lastname") String lastname
);
https://spring.io/blog/2011/02/10/getting-started-with-spring-data-jpa/
This is very good tutorial of Spring Data. I suggest you to start with it. tutorial of Spring Data. If you want to go deeper you can read the documentation.
http://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html

Customize query for paging and sorting in Spring data rest

I am using Spring data rest and am trying to customize the query for two of the overloaded findAll methods using #Query. However, when I attempt this I receive this error:
java.lang.IllegalStateException: Ambiguous search mapping detected. Both public abstract org.springframework.data.domain.Page courses.CourseRepository.findAll(org.springframework.data.domain.Pageable) and public abstract java.lang.Iterable courses.CourseRepository.findAll(org.springframework.data.domain.Sort) are mapped to /findAll! Tweak configuration to get to unambiguous paths!
When these methods are called the URL does not contain /findAll by convention. A URL for retrieving unsorted courses (but using paging) is
http://localhost:8080/v1/courses
and sorting is
http://localhost:8080/v1/courses?sort=title
Here's the relevant code, which is fairly straightforward:
public interface CourseRepository extends PagingAndSortingRepository<Course, Long> {
#Override
#Query("SELECT c FROM Course c WHERE c.visible = 'Yes'")
Page<Course> findAll(Pageable pageable);
#Override
#Query("SELECT c FROM Course c WHERE c.visible = 'Yes'")
Iterable<Course> findAll(Sort sort);
}
I've also attempted using an #NamedQuery on the Course entity with the same error message.
EDIT:
I have discovered that the findAll(Pageable pageable) method has Sorting 'built-in', however it does not sort the results. When I hit the following URL and attempt to sort by title the results are clearly not sorted by title. However, without the custom #Query the results are sorted.
http://localhost:8080/v1/courses?sort=title
Try
http://localhost:8080/v1/courses?sort=title,asc
http://localhost:8080/v1/courses?sort=title,desc
Or if you are using older Spring version, then take a look at this doc:
http://docs.spring.io/spring-data/rest/docs/1.1.x/reference/html/paging-chapter.html
I guess you are trying overloading findAll method of Spring-Data. This can be achieved only by CustomRepository.
Here is the useful link for you to guide about creating CustomRepository.
You can defined a class with the custom methods for tweaking Spring-Data's method based on the need.
Spring documentation link for the same

Categories

Resources