Reputation: 6543
I would like in HQL to use the result of a abstract method in my "where" clause. Can this be done?
Something like this:
@NamedQuery(name="getMailRelations", query="Select mr from MailRelation mr where mr.getOccurrences() > 5"
I have a mapped super class something like this
@Entity
@Table(name="Mail_Entity", schema="relations")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="relationType", discriminatorType=DiscriminatorType.STRING)
@PersistenceContext(name="domas")
public abstract class MailRelation {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
@ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH, CascadeType.PERSIST})
@JoinColumn(name="mailId", referencedColumnName="mailId", nullable=false)
private Mail mail;
public void setMail(Mail mail) {
this.mail = mail;
if(!mail.getMailRelations().contains(this))
mail.addMailRelation(this);
}
public abstract int getOccurrences();
public Mail getMail() {
return mail;
// and more code......
Upvotes: 1
Views: 5644
Reputation: 10055
The solution is up to you, but I'm adding some additional options you can consider:
If you manage to precalculate the hash in all cases, use a parametrized named query:
@NamedQuery(name="getMailRelations", query="Select mr from MailRelation mr where :occurrences > 5"
then, you can call the query and add the parameter "occurrences":
String precalculatedHash = //your code here.
entityManager.createNamedQuery("getMailRelations",MailRelation.class).setParameter("occurrences", precalculatedHash).getResultList();
Another option is to go a little deeper with your hash logic, and determine what do you want to achieve with it. With that in mind you can use Criteria API to create a query and add all the restrictions represented by that hash. This can be a little tricky, so discard this option if the hash proves to be too context-depending (and I mean if it relies a lot on what do you have persisted, and the context of your application).
The third option is to bring all the results (or the smallest set of results possible, through either parameters or, again, Criteria API), and make your particular filtering logic.
Upvotes: 0
Reputation: 5303
No, that is impossible. The HQL code is translated into SQL and executed on the database. Generally Java methods can't be translated into SQL, and the database does not have any access to your Java code.
If you have a problem like this, there are for example these three possibilities to handle it. None of these possibilities is perfect.
1) You write the logic of the method in HQL (or SQL) using WHERE, GROUP BY and HAVING. In your example the getOccurrences() method seems to return a number of rows, which perhaps can be handled by `HAVING COUNT(...) > 5'.
2) You use database stored procedures. These are p. ex. procedures written in PL/SQL (in the case of Oracle). They can be accessed in select statements. But you loose the independency of the chosen database.
3) You load more rows than necessary and filter later in your Java code.
Upvotes: 2