我有一个JPA应用程序,每天都会收到GB的字符串数据。最大的存储接收器是一组字符串,可以很长并且经常重复(可能有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如何知道returend id是什么?我最初试图做一个"而不是插入"类型触发器,但意识到我不能在表格上执行这些操作。
我的函数需要返回什么才能让hibernate获取ID?或者它不是那样工作的?
我的类非常简单,只需要一个@SqlInsert Annotation
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,我可以将其附加到我的关系
答案 0 :(得分: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
关键字或使用@Column
注释装饰java字段