001: package org.hibernate.id.insert;
002:
003: import org.hibernate.exception.JDBCExceptionHelper;
004: import org.hibernate.pretty.MessageHelper;
005: import org.hibernate.engine.SessionImplementor;
006: import org.hibernate.id.PostInsertIdentityPersister;
007:
008: import java.sql.PreparedStatement;
009: import java.sql.SQLException;
010: import java.sql.ResultSet;
011: import java.io.Serializable;
012:
013: /**
014: * Abstract InsertGeneratedIdentifierDelegate implementation where the
015: * underlying strategy requires an subsequent select after the insert
016: * to determine the generated identifier.
017: *
018: * @author Steve Ebersole
019: */
020: public abstract class AbstractSelectingDelegate implements
021: InsertGeneratedIdentifierDelegate {
022: private final PostInsertIdentityPersister persister;
023:
024: protected AbstractSelectingDelegate(
025: PostInsertIdentityPersister persister) {
026: this .persister = persister;
027: }
028:
029: public final Serializable performInsert(String insertSQL,
030: SessionImplementor session, Binder binder) {
031: try {
032: // prepare and execute the insert
033: PreparedStatement insert = session.getBatcher()
034: .prepareStatement(insertSQL, false);
035: try {
036: binder.bindValues(insert);
037: insert.executeUpdate();
038: } finally {
039: session.getBatcher().closeStatement(insert);
040: }
041: } catch (SQLException sqle) {
042: throw JDBCExceptionHelper.convert(session.getFactory()
043: .getSQLExceptionConverter(), sqle,
044: "could not insert: "
045: + MessageHelper.infoString(persister),
046: insertSQL);
047: }
048:
049: final String selectSQL = getSelectSQL();
050:
051: try {
052: //fetch the generated id in a separate query
053: PreparedStatement idSelect = session.getBatcher()
054: .prepareStatement(selectSQL);
055: try {
056: bindParameters(session, idSelect, binder.getEntity());
057: ResultSet rs = idSelect.executeQuery();
058: try {
059: return getResult(session, rs, binder.getEntity());
060: } finally {
061: rs.close();
062: }
063: } finally {
064: session.getBatcher().closeStatement(idSelect);
065: }
066:
067: } catch (SQLException sqle) {
068: throw JDBCExceptionHelper.convert(session.getFactory()
069: .getSQLExceptionConverter(), sqle,
070: "could not retrieve generated id after insert: "
071: + MessageHelper.infoString(persister),
072: insertSQL);
073: }
074: }
075:
076: /**
077: * Get the SQL statement to be used to retrieve generated key values.
078: *
079: * @return The SQL command string
080: */
081: protected abstract String getSelectSQL();
082:
083: /**
084: * Bind any required parameter values into the SQL command {@link #getSelectSQL}.
085: *
086: * @param session The session
087: * @param ps The prepared {@link #getSelectSQL SQL} command
088: * @param entity The entity being saved.
089: * @throws SQLException
090: */
091: protected void bindParameters(SessionImplementor session,
092: PreparedStatement ps, Object entity) throws SQLException {
093: }
094:
095: /**
096: * Extract the generated key value from the given result set.
097: *
098: * @param session The session
099: * @param rs The result set containing the generated primay key values.
100: * @param entity The entity being saved.
101: * @return The generated identifier
102: * @throws SQLException
103: */
104: protected abstract Serializable getResult(
105: SessionImplementor session, ResultSet rs, Object entity)
106: throws SQLException;
107:
108: }
|