views:

98

answers:

4

I use Hibernate with annotations. I need to insert object into the database using a method who needs one parameter that I need to calculate, to do this I use:

SQLQuery sqlQuery = getSession().createSQLQuery(queryString);
sqlQuery.executeUpdate();

The queryString contains:

INSERT INTO TABLE(ID, NUMBER) VALUES (SEC_TABLE.NEXTVAL, 549)

The object is inserted into the database, but when I try to get the id, I get a null value.

What can I do?

When I use getHibernateTemplate().update(obj); I have not problems getting the id, but I need to customize the sql insert.

Thanks

+1  A: 

Maybe I didn't get everything but did you consider using raw JDBC either via Session#connection() (might be removed in Hibernate 4) or the new Session#doWork() API? In case you need an example, here is how you'd use it:

session.doWork(new Work() {
   public void execute(Connection conn) {
      // do work with the connection
      ...
   }
});
Pascal Thivent
If this doesn't help, please clarify your question, I didn't get the problem with the id (that is null).
Pascal Thivent
I prefer not use raw JDBC. I try to use session.doWork but it still have null value
Michel
@Michel Where do "you have null value"? I don't understand, please explain what is happening and what the expected result is.
Pascal Thivent
My object- Id = null- Number = 549Id is automatically generated but is not set in the sqlQuery.executeUpdate();
Michel
@Michel Does it work with a SQL client? with raw JDBC?
Pascal Thivent
Yes, it works...
Michel
@Michel I don't understand what problem you get with `session.doWork()`. You should consider clarifying and adding details to your question if you want to increase your chances to get an answer. In its current state, everything is unclear.
Pascal Thivent
I try to clarify. I want to do an insert and a method call stored in the database, i tryed to do it with annotations but I need to get a value at runtime so I don't know how to do it with annotations. So instead of using them, I try to use SQLQuery sqlQuery = getSession().createSQLQuery(queryString);sqlQuery.executeUpdate();
Michel
A: 

Your question is a little bit unclear, but for what I understood I think you should first make a prepared statement that reads the next value for the sequence and use that id when creating the insert statement. Also, make sure that you commit the transaction and maybe flush the session.

As a side note, if you are using Hibernate with annotations, when mapping a table to a class you can provide the id generator as a sequence. In this way, you don't have to write jdbc code to insert the entity, just plain hibernate code, i.e. getJdbcTemplate().save().

virgium03
I generate the secuence with the annotation, but when I try to see the value is null.
Michel
A: 

Here is an example of sequences using annotations:

@Id
@Column(name = "OFFER_ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "OFR_OFFERS_SEQ")
@SequenceGenerator(name = "OFR_OFFERS_SEQ", sequenceName = "OFR_OFFERS_SEQ", allocationSize = 1)
private Long offerId;

Also, the add method should look like this:

public <T> T add(final T obj) {
     return get(obj.getClass(), (Long) getHibernateTemplate().save(obj));
}
public final <T> T get(final Class<T> clazz, final Long id) {
     return (T) getHibernateTemplate().get(clazz, id);
}

The methods are from a class than extends HibernateDaoSupport from Spring, thats how they get the hibernate template.

Hope this works for you.

virgium03
Yes, I have this, but I need to do a custom insert, so I have to create an @SQLInsert or SQLQuery sqlQuery = getSession().createSQLQuery(queryString);sqlQuery.executeUpdate();
Michel
I don't understand what do you mean by a custom insert and what do you need to do with it. maybe you can elaborate more?
virgium03
I want to insert an object, but also I want to call a procedure: INSERT INTO TABLE (id, value) VALUES (NEXTVAL, crypt(?,pwd)). But i need to get the pwd reading a file, so I can't put the crypt(?,'MYPASSWORD)
Michel
Ok, it is still unclear what do you want to do. You want to read some passwords from a file and then encrypt and save them into the database? Please try to describe your whole scenario.
virgium03
Yes, I have to read a password from a file, later I have to insert an object in a table encrypting one of the fields by a procedure stored in the database with two parameters, the field value and the password readed before.
Michel
and the field value which you are trying to insert should be the id of the previously inserted entity, which supposedly is null?
virgium03
No, the field value is not the id, is another one. I don't know how to do this with annotations so I tried anothers possibilities, one of them has the problem I presented in my post, but I only want to do the thing I tell to you before.
Michel
If you are trying to load the object after you've inserted it using the stored procedure, make sure you commit the transaction or flush the session. Please provide some snippet of code because it will be clearer.
virgium03
I dont create transactions... i only use this and later releaseConnection. But I would like to use annotations, you know how can i do it?
Michel
Please submit the code you are trying to use.
virgium03
@virgium03 I have submit the code
Michel
A: 

Now I have this:

public void sql(final String query) {
    getHibernateTemplate().execute(new HibernateCallback<Object>() {
        public Object doInHibernate(Session session) throws HibernateException, SQLException {
            Query q = session.createSQLQuery(query);
            q.executeUpdate();
            return null;
        }
    });
}

The query is:

INSERT INTO TABLE (ID, VALUE) VALUES (SEC.NEXTVAL, crypt(1, paswword))

The method I use:

public void insert(MyClass object) {
    String password = confFile.getProperty("CRYPT");
    String query = createQuery(object, password);
    sql(query);
}

The problem is that when I use the methods of HibernateDaoSupport when I do .persist(object) inmediatly I have the id in the object, but when I use this method (to crypt a field value) I try to get the id but it's null. The object is correctly inserted into the database.

Michel
I realized I was wrong ... It is impossible for the object using a query automatically get the id.How I can do to get the ID resulting from that last query?
Michel
create a PreparedStatement that will contain something like this: select y.id from your_table y where ...
virgium03
or you can perform a query on sec.nextval using a prepared statement, store it in a Long variable and use this variable when creating the insertion sql.
virgium03
But to use a PreparedStatement I need the conection, but it is deprecated. Also, if someone insert another object with the same values may that I get a wrong id, isn't?
Michel