Querying multiple tables using jpa repository - spring-boot

Suppose if I have 3 entities - User, Skills, Department
and I have repositories corresponding to all of them - UserRepository, SkillRepository, DepartmentRepository.
I understand that the relation mapping between entities i.e. one-one many-many should be specified in the respective entity classes. The question is I want to use all of the 3 entities in a query. How would I do it? A single repository is associated with only one entity right? So, how/where would I write it?

As there are many different ways to specify queries with Spring Data JPA there are various answers to this.
Maybe you don't have to. If entity A references B and you just want to get the Bs with your A you simply use your ARepository to load As and use object navigation to get your Bs. You might read up on eager and lazy loading for more information about how to control this.
If you want referenced entities in the where condition you can use property paths in your query method names: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-property-expressions
If you are using #Query annotations you can do (almost) whatever you want with JPQL. Among others, you may as well navigate properties to use them in where clauses.
In general, you'd put that query in the matching repository based on the primary entity returned.

Related

Why is Hibernate #OnetoMany relationship required?

I have two entities Library and Books which are associated by Hibernate #OneToMany in a spring boot project. Fetching books in a particular library through the getter functions renders a LazyInitialisationException. The solution that I could find was making a query in the Books entity and fetching all the books corresponding to the library-id of the library. So, I was thinking why is oneToMany relationship required if we can just store a key corresponding to library in the Books table.
Simply storing a key doesn't provide any consistency assurances. Also, using defined OneToMany or ManyToOne you can also define the cascade types (you would only need to save the parent entity and then all the children would automatically be saved, in a single transaction).
The quick way to fix your problem would be to use FetchType EAGER, but I would recommend fixing whatever you have misconfigured.

Spring JPA custom query with combination of parameters in WHERE condition?

How to write JPA query in Spring Data that uses at least one of three parameters?
I have these three parameters:
Id (PK)
Name
Surname
Client must supply at least one of these three parameters and I want to find user by these not-empty parameters.
Is it possible to create such custom query to my repository or do I have to create custom queries for all possible combination of WHERE conditions?
You can have your repository extend org.springframework.data.querydsl.QueryDslPredicateExecutor and use the inherited findAll(Predicate predicate) method to query using any combination of parameters.
You would not then have to write any query methods:
http://docs.spring.io/spring-data/jpa/docs/1.10.5.RELEASE/reference/html/#core.extensions.querydsl
You can also have the Predicate automatically bound in a Spring MVC Controller as detailed here:
https://spring.io/blog/2015/09/04/what-s-new-in-spring-data-release-gosling#querydsl-web-support
and here:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#core.web.type-safe
So your controller can then automatically handle a search with 1,2 or all 3 parameters passed as request parameters without your having to write any code at all.
This is where you need the ability to create dynamic queries at runtime.
In your application code, you should have logic to build the predicate based on whether each of the above properties from the input DTO is empty or not.
One way to do it is to use QueryDSL.
To use QueryDSL, you should include the relevant dependency in your pom/gradle file and then your repository should extend the QueryDslPredicateExecutor interface. This will give you two additional generic finder methods.
T findAll(Predicate) or
Page<T> findAll(Predicate, Pageable)
One thing to keep in mind is that the above two methods are appropriate where this is no need to do a join
Your requirement here seems to be a single table query, so either one of the finder methods should suffice.
If you do need to do a join with other tables and need fine grained control over how the JOIN happens (INNER JOIN vs LEFT OUTER JOIN vs CROSS JOIN) etc, then you should consider creating a Custom repository that your repository can extend.
And then provide your own customImpl that you can now access from the repository.
thanks a lot for the reply ... as i read Spring is not easy flexible as other framework... for i.e i tried some node js api framework and it is easier and more flexible .. what do you think about this ?

How to handle a chain of OneToMany relationships in QueryDSL?

Thus far I have referred to this repo as a reference for how to structure my repositories in my Spring project which leverages QueryDSL.
The only "shortcoming" of this example for me is that it does not outline how I might write a Repository which uses a chain of more than one OneToMany relationships. Using this repository as an example/reference, they have a "Customer" repository and for each Customer there are many "Address". I'm unsure how I would use give or take the same patterns they are using, but for a Class which had a OneToMany relationship with Customers. Meaning, how would I handle a Repository for "CustomerGroup" which has a OneToMany relationship with "Customers" which in turn has a one to many relationship with "Addresses".
Some patterns have occurred to me, but not seem elegant/optimal so I'm looking for anyone with experience or insight as to what might be a nice way of solving this problem.
I very much appreciate any help!
Do you mean in order to write WHERE statements based on the relations?
For example if you want to retrieve all customer groups that contain a customer from a specific country, you can simply call
QCustomerGroup.customerGroup.customer.any().addresses.any().country.eq("Germany")
To make this working to need to add
#OneToMany
private Address addresses;
to the Customer entity.

Entity Framework 2 different tables retrieve data as single entity

We have 2 exactly same tables in our database. One is an archive of the other.
How can I retrieve the data from the archive table without changing the entity type using Entity Framework and Linq?
When you map your tables to EF entities you can automatically create classes for the entities. Why do you want to avoid creating separate classes for different tables? If you want a common contract for the two so that you can pass them to other functions that perform the same operations on both, I would add an interface to the generated entities instead. That way you can use the auto generated entities but still be able to treat them as "one"
You can always do a .Select(x=>new SomeTypeOfObject{Prop1 = x.Prop1, Prop2 = x.Prop2})

Linq To SQL : Modeling Associations

I have three tables Projects, Users and ProjectMembers. The ProjectMembers table is a mapping table and has only two columns ProjectId and UserId.
In my object model i have two classes Project and User. The Project class has a property IEnumerable<User> Members
I am using an external xml map file for mapping linq to sql associations. I am able to get the Project and the User data but I dont know how to map the Members association.
This sounds like a Many-to-Many mapping (Projects <-> Users).
In which case you are going to run into problems using Linq To SQL. To cut a long story short it does not really support that mapping. There are several workarounds which you can find on google, one of which is altering the partial class to provide the access to the Members/Projects collection on the Project and User classes respectively.
e.g. http://www.iaingalloway.com/2015/06/many-to-many-relationships-in-linq-to-sql.html

Resources