Reputation: 682
I was wondering if it exist a way to tell to Hibernate to execute the query behind a @OneToMany only if a condition is satisfied. This could be a very simple example:
@Entity
public class MyEntity {
...
private Long id;
private boolean condition;
private List<AnotherEntity> anotherEntity;
@Id
@Column(name = "ID", nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Basic
@Column(name = "CONDITION")
public Boolean getCondition() {
return isContentChanged;
}
public void setIsContentChanged(Boolean condition) {
this.condition = condition;
}
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "SECOND_ID")
**@Conditional(clause = "CONDITION = true")**
public List<AnotherEntity> getAnotherEntity() {
return anotherEntity;
}
public void setAnotherEntity(List<AnotherEntity> anotherEntity) {
this.anotherEntity = anotherEntity;
}
}
@Entity
public class AnotherEntity {
private id
private secondId
...
}
So what I would like is: - if the condition in the annotation @Conditional is satisfied, Hibernate execute the query related to the @OneToMany annotation - if the condition in the annotation @Conditional is not satisfied, Hibernate do nothing with the @OneToMany annotation
I do not know if that already exist somewhere in Hibernate. Otherwise could be a great new feature.
Upvotes: 2
Views: 2886
Reputation: 21133
One way you may be able to solve this depending on the context of AnotherEntity
would be to use a Hibernate Filter. I have used something similar in the past where we had a OneToMany
of a specific entity type but only certain values were to be returned based on user access.
Other ways may include using a @Formula
or @Where
annotation.
All three of these options are available in the documentation for Hibernate 5.2, starting here.
Update:
What I am about to explain only applies to associations which are explicitly defined as LAZY
fetch types. If you keep the default EAGER
fetch type or explicitly set it to EAGER
, the following does not apply.
Given that your association is using LAZY
fetch types, you could bake the condition as a part of your data access layer queries at runtime. There isn't an annotation to this so it would be part of your code but it at least allows you to minimize the join at runtime.
For situations where your condition is true, you either specify that the collection should be loaded EAGER
if using the deprecated Hibernate Criteria API or you'll want to use a JOIN/JOIN FETCH
if using the JPA Criteria API. Note that JOIN
will only allow you to apply predicates again the collection to filter the root entities; however JOIN FETCH
will also populate the collection for you.
This won't allow you to filter the collection results but it at least provides you a means to eliminate the join while allowing the join to be part of the query at runtime based on some condition.
This is very analygous where a search form has 10 searchable fields; however you only apply the appropriate predicates to a base query if a given field has a value; however no predicate and perhaps no specific joins are added to the base query if a value is not provided to improve runtime query performance.
Upvotes: 1