0

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

1 Answer 1

1

Assuming you have following entity class:

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

You can use Hibernate native SQL query:

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 will map java properties based on the result set column name. you can use as keyword or decorate the java field with @Column annotation

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for this, will try it out today.
Worked like a champ. Is there a .single() type method instead of .list() at the end of AddEntity?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.