I have a JPA app that is receiving GBs of string data each day. The biggest storage sink is a set of strings that can be pretty long and are repeated very often (maybe 1000 unique strings and I might get tens of thousands of repetitions). To this end I've created a function (needs work, I am pretty bad at postgresql) seen here:
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;
The idea is attempt to insert the row, unless the string already exists, then return an existing ID to be used by the other side of the relationship (many objects have the same "servicename" in this example.
How does hibernate know what the returend id was? I originally tried to do an "Instead of Insert" type trigger, but realized I can't do these on tables.
What does my function need to return for hibernate to pick up on the ID? Or does it not work that way?
My class is very simple and just needs a @SqlInsert Annotation
public class ServiceName implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private int id;
@Index(name = "name")
private String name;
EDIT
Using the answer below I have done the following:
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));
And this works just fine. Entity reads the ID back in and I can attach this to my relation