Source code: org/hibernate/id/insert/AbstractSelectingDelegate.java
1 package org.hibernate.id.insert;
2
3 import org.hibernate.exception.JDBCExceptionHelper;
4 import org.hibernate.pretty.MessageHelper;
5 import org.hibernate.engine.SessionImplementor;
6 import org.hibernate.id.PostInsertIdentityPersister;
7
8 import java.sql.PreparedStatement;
9 import java.sql.SQLException;
10 import java.sql.ResultSet;
11 import java.io.Serializable;
12
13 /**
14 * Abstract InsertGeneratedIdentifierDelegate implementation where the
15 * underlying strategy requires an subsequent select after the insert
16 * to determine the generated identifier.
17 *
18 * @author Steve Ebersole
19 */
20 public abstract class AbstractSelectingDelegate implements InsertGeneratedIdentifierDelegate {
21 private final PostInsertIdentityPersister persister;
22
23 protected AbstractSelectingDelegate(PostInsertIdentityPersister persister) {
24 this.persister = persister;
25 }
26
27 public final Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder) {
28 try {
29 // prepare and execute the insert
30 PreparedStatement insert = session.getBatcher().prepareStatement( insertSQL, false );
31 try {
32 binder.bindValues( insert );
33 insert.executeUpdate();
34 }
35 finally {
36 session.getBatcher().closeStatement( insert );
37 }
38 }
39 catch ( SQLException sqle ) {
40 throw JDBCExceptionHelper.convert(
41 session.getFactory().getSQLExceptionConverter(),
42 sqle,
43 "could not insert: " + MessageHelper.infoString( persister ),
44 insertSQL
45 );
46 }
47
48 final String selectSQL = getSelectSQL();
49
50 try {
51 //fetch the generated id in a separate query
52 PreparedStatement idSelect = session.getBatcher().prepareStatement( selectSQL );
53 try {
54 bindParameters( session, idSelect, binder.getEntity() );
55 ResultSet rs = idSelect.executeQuery();
56 try {
57 return getResult( session, rs, binder.getEntity() );
58 }
59 finally {
60 rs.close();
61 }
62 }
63 finally {
64 session.getBatcher().closeStatement( idSelect );
65 }
66
67 }
68 catch ( SQLException sqle ) {
69 throw JDBCExceptionHelper.convert(
70 session.getFactory().getSQLExceptionConverter(),
71 sqle,
72 "could not retrieve generated id after insert: " + MessageHelper.infoString( persister ),
73 insertSQL
74 );
75 }
76 }
77
78 /**
79 * Get the SQL statement to be used to retrieve generated key values.
80 *
81 * @return The SQL command string
82 */
83 protected abstract String getSelectSQL();
84
85 /**
86 * Bind any required parameter values into the SQL command {@link #getSelectSQL}.
87 *
88 * @param session The session
89 * @param ps The prepared {@link #getSelectSQL SQL} command
90 * @param entity The entity being saved.
91 * @throws SQLException
92 */
93 protected void bindParameters(
94 SessionImplementor session,
95 PreparedStatement ps,
96 Object entity) throws SQLException {
97 }
98
99 /**
100 * Extract the generated key value from the given result set.
101 *
102 * @param session The session
103 * @param rs The result set containing the generated primay key values.
104 * @param entity The entity being saved.
105 * @return The generated identifier
106 * @throws SQLException
107 */
108 protected abstract Serializable getResult(
109 SessionImplementor session,
110 ResultSet rs,
111 Object entity) throws SQLException;
112
113 }