毎日 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 を読み込んで、これを自分のリレーションに添付できます