1

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

2 に答える 2

2

いいえ、それは不可能です。HQL コードは SQL に変換され、データベース上で実行されます。通常、Java メソッドは SQL に変換できず、データベースは Java コードにアクセスできません。

このような問題が発生した場合、たとえば次の 3 つの方法で対処できます。これらの可能性はどれも完璧ではありません。

1) WHERE、GROUP BY、および HAVING を使用して、HQL (または SQL) でメソッドのロジックを記述します。あなたの例では、 getOc​​currences() メソッドは行数を返すようですが、これはおそらく「HAVING COUNT(...) > 5」で処理できます。

2) データベースのストアド プロシージャを使用します。これらはpです。元。PL/SQL で記述されたプロシージャ (Oracle の場合)。それらは select ステートメントでアクセスできます。ただし、選択したデータベースの独立性が失われます。

3) 必要以上の行をロードし、後で Java コードでフィルタリングします。

于 2012-05-08T14:46:40.837 に答える
0

解決策はあなた次第ですが、検討できるオプションをいくつか追加します。

すべてのケースでハッシュを事前に計算できた場合は、パラメーター化された名前付きクエリを使用します。

@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();

もう 1 つのオプションは、ハッシュ ロジックをもう少し深く掘り下げて、それで何を達成したいかを判断することです。これを念頭に置いて、Criteria APIを使用してクエリを作成し、そのハッシュによって表されるすべての制限を追加できます。これは少し難しいので、ハッシュがコンテキストに依存しすぎることが判明した場合は、このオプションを破棄してください (つまり、何を保持しているか、およびアプリケーションのコンテキストに大きく依存している場合)。

3 番目のオプションは、すべての結果(またはパラメーターまたはCriteria APIのいずれかを介して可能な限り最小の結果セット) を取得し、特定のフィルター処理ロジックを作成することです。

于 2012-05-08T17:31:05.560 に答える