0

毎日 GB 単位の文字列データを受信する JPA アプリがあります。最大のストレージ シンクは、非常に長く、非常に頻繁に繰り返される一連の文字列です (おそらく 1000 個の一意の文字列と、何万回も繰り返される可能性があります)。この目的のために、ここに見られる関数を作成しました(作業が必要です、私はpostgresqlがかなり苦手です):

CREATE OR REPLACE FUNCTION dedup_srvice_name(in_id bigint,in_name varchar)
RETURNS SETOF servicename
LANGUAGE plpgsql
AS $function$
DECLARE found_row servicename%ROWTYPE;
BEGIN

SELECT  into found_row  * from servicename where servicename.name = in_name LIMIT      1;
IF found_row IS NULL THEN
    INSERT INTO  servicename VALUES(in_id,in_name) returning id,name;       
    ELSE
    RETURN NEXT found_row;
    RETURN;
    END IF;               

  RETURN;
END;

文字列がすでに存在しない限り、行を挿入してから、関係の反対側で使用される既存の ID を返すという考え方です (この例では、多くのオブジェクトが同じ "servicename" を持っています。

hibernate は戻り値 ID をどのように認識しますか? 私はもともと「挿入の代わりに」タイプのトリガーを実行しようとしましたが、テーブルではこれらを実行できないことに気付きました。

休止状態が ID を取得するために関数が返す必要があるものは何ですか? それとも、そのようには機能しませんか?

私のクラスは非常に単純で、@SqlInsert アノテーションが必要なだけです

public class ServiceName implements Serializable {

private static final long serialVersionUID = 1L;

@Id
private int id;

@Index(name = "name")
private String name;

編集

以下の回答を使用して、次のことを行いました。

            SQLQuery query = session.createSQLQuery("select id,name from dedup_srvice_name(?,?)");

            query.setParameter(0, 0).setParameter(theName);

            List<ServiceName> names = query.addEntity(ServiceName.class).list();                
            software.setName(names.get(0));

そして、これはうまく機能します。エンティティは ID を読み込んで、これを自分のリレーションに添付できます

4

1 に答える 1

1

次のエンティティ クラスがあると仮定します。

@Entity
public class MyString {
  private long id;
  private String name;
  // getters & setters..
}

Hibernate ネイティブ SQL クエリを使用できます。

Session session = // obtain hibernate session somehow..
String sql = // sql to call your db function..
List<MyString> mystrings = session.createSQLquery(sql).addEntity(MyString.class).list();

Hibernate は、結果セットの列名に基づいて Java プロパティをマップします。キーワードを使用するか、注釈asでJavaフィールドを装飾できます@Column

于 2013-07-02T02:38:29.957 に答える