tonyaugustine wrote:
I'm trying to use this in my project. We are using Hibernate 3.6. When I try to compile landrain's TriggerAssignedIdentityGenerator class, it gives me compilation error that, it can't find org.hibernate.IdentifierGeneratorFactory and org.hibernate.util.NamedGeneratedKeysHelper. Looks like they have been removed from the 3.6 version of hibernate.
Yes, the code must be updated for the newer versions of Hibernate (I believe since 3.5.0, but I haven't checked exactly).
Please, see hereafter for an update with hibernate 3.6.0.Final. One line has changed in the executeAndExtract method + some imports. The changes are marked with "del" and "add" tags:
Code:
package jpl.hibernate.util;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.id.AbstractPostInsertGenerator;
[del]import org.hibernate.id.IdentifierGeneratorFactory;[/del]
[add]import org.hibernate.id.IdentifierGeneratorHelper;[/add]
import org.hibernate.id.PostInsertIdentityPersister;
import org.hibernate.id.SequenceIdentityGenerator.NoCommentsInsert;
import org.hibernate.id.insert.AbstractReturningDelegate;
import org.hibernate.id.insert.IdentifierGeneratingInsert;
import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
[del]import org.hibernate.util.NamedGeneratedKeysHelper;[/del]
/**
* A generator with immediate retrieval through JDBC3 {@link java.sql.Connection#prepareStatement(String, String[]) getGeneratedKeys}.
* The value of the identity column must be set from a "before insert trigger"
* <p/>
* This generator only known to work with newer Oracle drivers compiled for
* JDK 1.4 (JDBC3). The minimum version is 10.2.0.1
* <p/>
* Note: Due to a bug in Oracle drivers, sql comments on these insert statements
* are completely disabled.
*
* @author Jean-Pol Landrain
*/
public class TriggerAssignedIdentityGenerator extends AbstractPostInsertGenerator {
public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(PostInsertIdentityPersister persister, Dialect dialect, boolean isGetGeneratedKeysEnabled) throws HibernateException {
return new Delegate(persister, dialect);
}
public static class Delegate extends AbstractReturningDelegate {
private final Dialect dialect;
private final String[] keyColumns;
public Delegate(PostInsertIdentityPersister persister, Dialect dialect) {
super(persister);
this.dialect = dialect;
this.keyColumns = getPersister().getRootTableKeyColumnNames();
if (keyColumns.length > 1) {
throw new HibernateException("trigger assigned identity generator cannot be used with multi-column keys");
}
}
public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
NoCommentsInsert insert = new NoCommentsInsert(dialect);
return insert;
}
protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
return session.getBatcher().prepareStatement(insertSQL, keyColumns);
}
protected Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
insert.executeUpdate();
[del]return IdentifierGeneratorFactory.getGeneratedIdentity(NamedGeneratedKeysHelper.getGeneratedKey(insert), getPersister().getIdentifierType());[/del]
[add]return IdentifierGeneratorHelper.getGeneratedIdentity(insert.getGeneratedKeys(), getPersister().getIdentifierType());[/add]
}
}
}
tonyaugustine wrote:
Does that mean hibernate itself has created a mechanism to refresh the ids generated by a trigger. If so can someone post an annotation sample how to do it.
It exists a trigger-identity in NHibernate. But I am not aware of anything similar in Hibernate up to now.
tonyaugustine wrote:
Also will it work if I try to persist a parent and child object with a single call. The ids for both parent & child are generated by triggers.
It works if the two entities, parent and child, are declared with this identity generator (in case you're using annotations and you need this idgen on all or many of your entities, see two posts above in order to use the annotations at package level).