Reputation: 6124
I have an entity, which has multiple @ManyToOne
associated objects. Currently I modelled all associated objects fetch type to LAZY
.
Actually I am writing REST API
to support various functionalities like
@ManytoOne
annotation resolving to just an id @ManytoOne
annotation resolving to the entire object@ManytoOne
annotation resolving to a partial object@ManytoOne
annotation resolving to just an idMy application was built using spring-boot jpa repository. Obviously the above variations in the REST API
can be solved by writing named query for each API
. If I do so, at one point there will be multiple named queries for each associated objects. But I am expecting a better approach to model and querying the entities.
Any suggestions are appreciated.
Upvotes: 1
Views: 249
Reputation: 131456
In your case, queries which the structure is statically defined is really not suitable as you will indeed multiply the number of queries to write/modify/maintain.
JPA and Spring Data provide alternatives to create flexible queries and set the eager fetching dynamically :
JPA 2 - Criteria : Focused on dynamically build queries and eager fetching of the relationships.
It is powerful but requires a important part of boiler plate code to create you criterias.
JPA 2.1 - Entity Graph : Focused on eager fetching of the relationships.
This focus on eagerly fetched of the relationships.
It is very simple and doesn't require boiler plate code.
Just add the hint in the Query/Criteria
you create.
It can be used with JPQL queries or Criterias.
Spring Data - Specifications : Focused on dynamically build queries. It is a wrapper/enhancer of JPA Criteria with a Domain Driven Design vision. It is powerful but it is also verbose to setup.
Spring Data - Query by example : Focused on dynamically build queries. It is very simple, client friendly. It has some limitations and I don't think that the API be designed to set the fetch mode of the relationships of the queried entity.
For your requirement I would introduce two repository methods.
The first one would use the Criteria + Entity Graph to benefit from dynamically build queries and a simple way to set the eager fetching of the relationships for these cases :
Get an entity with @ManytoOne annotation resolving to just an id
Get an entity with @ManytoOne annotation resolving to the entire object
Get an entity with @ManytoOne annotation resolving to a partial object
And the second one method would use the Entity Graph + JPQL to only benefit from eager fetching for this one :
Fetch entities with @ManytoOne annotation resolving to just an id
With Criteria + Entity Graph, you could get a single method that does everything but having a complex method that does a lot of things is not necessarily the best choice.
Upvotes: 1
Reputation: 4558
From my understanding, you should use Query by Example
The Query by Example API consists of three parts:
- Probe: The actual example of a domain object with populated fields.
ExampleMatcher
: TheExampleMatcher
carries details on how to match particular fields. It can be reused across multipleExamples
.Example
: AnExample
consists of the probe and theExampleMatcher
. It is used to create the query.Query by Example is well suited for several use cases:
- Querying your data store with a set of static or dynamic constraints.
- Frequent refactoring of the domain objects without worrying about breaking existing queries.
- Working independently from the underlying data store API.
Query by Example also has several limitations:
- No support for nested or grouped property constraints, such as
firstname = ?0 or (firstname = ?1 and lastname = ?2)
.- Only supports starts/contains/ends/regex matching for strings and exact matching for other property types.
Upvotes: 1