【问题标题】:HQL get a value from methodHQL 从方法中获取值
【发布时间】:2012-05-17 00:23:34
【问题描述】:

我想在 HQL 中在我的“where”子句中使用抽象方法的结果。这可以做到吗?

类似这样的:

@NamedQuery(name="getMailRelations", query="Select mr from MailRelation mr where mr.getOccurrences() > 5"

我有一个类似这样的映射超类

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

【问题讨论】:

  • AFAIK 我们不能在 HQL 中使用 java 方法
  • 你能解释一下getOc​​currences方法是做什么的吗?
  • @Gamb 它只是一个示例,在这种情况下它可以返回一个数字。我不相信这个案子的意义重大,但我可能是错的?
  • 我想你可以参数化你的 NamedQuery,如果在进行查询之前可以知道出现次数,或者如果出现次数可以转换为类的属性,那么你可以直接使用它。此外,如果事件与 MailRelations 本身有关(例如在数据库中保留了多少),问题就会出现另一个转折。
  • @Gamb 在我的真实案例中,它是一个独特的哈希,不能总是预先计算。不过我喜欢这个想法!

标签: java hibernate jakarta-ee hql


【解决方案1】:

不,那是不可能的。 HQL 代码被翻译成 SQL 并在数据库上执行。一般Java方法不能翻译成SQL,数据库也无权访问你的Java代码。

如果您遇到这样的问题,例如有这三种可能性来处理它。这些可能性都不是完美的。

1) 您使用 WHERE、GROUP BY 和 HAVING 在 HQL(或 SQL)中编写方法的逻辑。在您的示例中,getOc​​currences() 方法似乎返回了许多行,这可能可以通过 `HAVING COUNT(...) > 5' 来处理。

2) 您使用数据库存储过程。这些是 p。前任。用 PL/SQL 编写的过程(在 Oracle 的情况下)。它们可以在 select 语句中访问。但是您失去了所选数据库的独立性。

3) 您加载的行数超出了必要的数量,并稍后在您的 Java 代码中进行过滤。

【讨论】:

    【解决方案2】:

    解决方案由您决定,但我添加了一些您可以考虑的其他选项:

    如果您设法在所有情况下预先计算哈希,请使用参数化命名查询:

    @NamedQuery(name="getMailRelations", query="Select mr from MailRelation mr where :occurrences > 5"
    

    然后,您可以调用查询并添加参数“occurrences”:

    String precalculatedHash = //your code here.
    entityManager.createNamedQuery("getMailRelations",MailRelation.class).setParameter("occurrences", precalculatedHash).getResultList();
    

    另一种选择是更深入地研究您的哈希逻辑,并确定您想用它实现什么。考虑到这一点,您可以使用Criteria API 创建查询并添加该哈希表示的所有限制。这可能有点棘手,所以如果哈希被证明过于依赖上下文(我的意思是如果它很大程度上依赖于你坚持的内容,以及你的应用程序的上下文),请放弃这个选项。

    第三个选项是带来所有结果(或可能的最小结果集,通过参数或Criteria API),并制定您的特定过滤逻辑。

    【讨论】:

      猜你喜欢
      • 2013-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多