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

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).

Related

How to query only limited columns in Hibernate, and map them to a given POJO?

My project involves using GraphQL within a Spring Boot app. For demonstration purposes, here is my GraphQL schema:
type Company{
name: String,
parentOrganization: String,
flag:Int
}
I'm still learning Spring Boot and JPA, so I use spring-boot-starter-data-jpa for all the JPA, Hibernate, etc.
My problem is, when someone queries only for name and organization, Hibernate queries for all the columns and GraphQL picks the columns requested.
#Repository
#Transactional
public interface CompanyRepository extends JpaRepository<Company,Long> {
}
The above code doesn't really give me any flexibility in limiting the columns that are queried. I've tried using Hibernate's Criteria API as well, but whichever way I go, I get this error:
Unable to locate appropriate constructor on class [packagee.entity.company]. Expected arguments are: java.lang.String, java.lang.String [select new package.entity.Company(generatedAlias0.company, generatedAlias0.organization) from package.entity.Company as generatedAlias0]
Below is the code for my Criteria implementation:
public static List<Company> get(EntityManager em, List<String> fieldsAsked){
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Company> cq = cb.createQuery(Company.class);
Root<Company> root = cq.from(Company.class);
List<Selection<?>> selectionList = new LinkedList<Selection<?>>();
for(String name: fieldsAsked){
selectionList.add(root.get(name));
}
cq.multiselect(selectionList);
return em.createQuery(cq).getResultList();
}
How do I get limited columns from Hibernate? I've seen many answers online that ask to make appropriate constructor in the entity class, but that's not really possible for me because my entity parameters are mostly Strings and I cant make constructors for all the permutations possible (because I'm using GraphQL, the control of what to query really goes to the end user of my project).
What should I do? Thanks in advance!
What you want to do is not really possible with Hibernate directly, but you can checkout Blaze-Persistence Entity-Views which also has a GraphQL integration that supports exactly what you are looking for. See https://persistence.blazebit.com/documentation/1.6/entity-view/manual/en_US/#graphql-integration
Here is a sample project that shows how you can use this: https://github.com/Blazebit/blaze-persistence/tree/master/examples/spring-data-graphql
Solution 1:
You can create a new DTO class which will be returned by your query.
The DTO class:
public class CompanyDTO(){
//fields,constructor
}
And in the repository:
#Query(value = "SELECT new com.example.dto.companyDTO" +
"(c.name,c.parentOrganization)" +
" FROM Company c")
List<CompanyDTO>findCompanySelectedColumns(PageRequest pageable);
Solution 2(clean solution):
You can use interface. Do not implement the interface.
interface customCustomer{
String getName();
String getParentOrganization();
}
In repository:
List<CustomCustomer>findAllByNameAndParentOrganization();

Change default behaviour of mongoTemplate.find

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

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

Spring Data JPA QueryDslPredicateExecutor find distinct results

I have a Spring Data & JPA QueryDSL based project in which I have many repository interfaces extending QueryDslPredicateExecutor like below:
public interface ProductRepository extends JpaRepository<Product, Long>,
QueryDslPredicateExecutor<Product> {
}
I am performing findAll() queries with BooleanExpressions all over my application to fetch data. However I now need to find the distinct results of a query based on a particular column.
I am also using Projections & Custom repositories in some cases to select particular columns based on this post.
Is there a way to select distinct so that I only get the distinct values of a particular column for a query, based on any of the above approaches?
Today I've encountered the same issue and it seems that there's no direct repository approach to solve it.
I ended using Querydsl in order to accomplish what I wanted: being able to use Page<T> findAll(Predicate var1, Pageable var2); using distinct.
A simple snippet:
public Page<LocalizedMessage> findAll(Predicate predicate, Pageable pageable) {
QMessage qMessage = QMessage.message;
Querydsl querydsl = new Querydsl(entityManager, new PathBuilder<>(Message.class, qMessage.getMetadata()));
JPAQuery countQuery = querydsl.createQuery(qMessage).distinct().where(predicate);
JPAQuery query = querydsl.createQuery(qMessage).distinct().where(predicate);
querydsl.applyPagination(pageable, query);
return PageableExecutionUtils.getPage(query.fetch(), pageable, countQuery::fetchCount);
}
This code is based on QuerydslJpaRepository's findAll(Predicate, Pageable) method. I presumed that it could be easy to extend this repository in order to add findAllDistinct methods using JPQLQuery.distinct().
I've filed a feature request at spring-data's JIRA.
Hope this helps someone.
If you use Querydsl queries directly in your repository you can call query.distinct() to get distinct results.

how to get a value from a repository with a value which is compared with two fields of a table

Hi i am new to spring JPA . I have a table which has two columns namely 'active_from' and 'active_to'.Now I would like to get a column which has a date(ie.current date) which has a value between "active_from" and "active_to".How to acheive this using spring jpa repositories.?
This link you could find query methods to add queries that are not covered by the common jpa repository or with the support creation.
Check 2.3.4 Using #Query in
JPA repositories
Using Query methods you can do that, try something like this.
public interface UserRepository extends JpaRepository<User, Long> {
#Query(value = "SELECT * FROM USERS WHERE active_from > :?0 AND active_to < :?0 )
List<User> findBetweenDate(String currentDate);
}

Categories

Resources