View Javadoc

1   /*
2    * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3    * the spring framework, http://el4j.sf.net
4    * Copyright (C) 2009 by ELCA Informatique SA, Av. de la Harpe 22-24,
5    * 1000 Lausanne, Switzerland, http://www.elca.ch
6    *
7    * EL4J is published under the GNU Lesser General Public License (LGPL)
8    * Version 2.1. See http://www.gnu.org/licenses/
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU Lesser General Public License for more details.
14   *
15   * For alternative licensing, please contact info@elca.ch
16   */
17  package ch.elca.el4j.services.persistence.hibernate;
18  
19  import java.io.Serializable;
20  import java.sql.PreparedStatement;
21  import java.sql.SQLException;
22  
23  import org.hibernate.HibernateException;
24  import org.hibernate.dialect.Dialect;
25  import org.hibernate.engine.SessionImplementor;
26  import org.hibernate.id.AbstractPostInsertGenerator;
27  import org.hibernate.id.IdentifierGeneratorHelper;
28  import org.hibernate.id.PostInsertIdentityPersister;
29  import org.hibernate.id.SequenceIdentityGenerator.NoCommentsInsert;
30  import org.hibernate.id.insert.AbstractReturningDelegate;
31  import org.hibernate.id.insert.IdentifierGeneratingInsert;
32  import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
33  
34  /**
35   * A generator with immediate retrieval through JDBC3
36   * {@link java.sql.Connection#prepareStatement(String, String[]) getGeneratedKeys}.
37   * The value of the identity column must be set from a "before insert trigger"
38   * 
39   * This generator is tested with Oracle and only known to work with newer Oracle drivers compiled for
40   * JDK 1.4 (JDBC3). The minimum version is 10.2.0.1
41   * 
42   * Note: Due to a bug in Oracle drivers, sql comments on these insert statements
43   * are completely disabled.
44   *
45   * @svnLink $Revision: 4110 $;$Date: 2010-08-04 14:40:16 +0200 (Mi, 04. Aug 2010) $;$Author: swrelca $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/hibernate/src/main/java/ch/elca/el4j/services/persistence/hibernate/TriggerAssignedIdentityGenerator.java $
46   *
47   * @author Jean-Pol Landrain - extern (XYZ)
48   * @author Martin Zeltner (MZE)
49   */
50  public class TriggerAssignedIdentityGenerator extends AbstractPostInsertGenerator {
51  	/**
52  	 * {@inheritDoc}
53  	 */
54  	public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(
55  		PostInsertIdentityPersister persister, Dialect dialect, boolean isGetGeneratedKeysEnabled)
56  		throws HibernateException {
57  		return new Delegate(persister, dialect);
58  	}
59  
60  	/**
61  	 * Delegate for the returned generated value.
62  	 */
63  	public static class Delegate extends AbstractReturningDelegate {
64  		/**
65  		 * Use database dialect.
66  		 */
67  		private final Dialect m_dialect;
68  
69  		/**
70  		 * Are the key columns.
71  		 */
72  		private final String[] m_keyColumns;
73  
74  		/**
75  		 * @param persister Is the post insert identity persister 
76  		 * @param dialect Is the dialect of the database.
77  		 */
78  		public Delegate(PostInsertIdentityPersister persister, Dialect dialect) {
79  			super(persister);
80  			m_dialect = dialect;
81  			m_keyColumns = getPersister().getRootTableKeyColumnNames();
82  			if (m_keyColumns.length > 1) {
83  				throw new HibernateException(
84  					"trigger assigned identity generator cannot be used with multi-column keys");
85  			}
86  		}
87  
88  		/**
89  		 * Removes the comments for insertion.
90  		 * 
91  		 * {@inheritDoc}
92  		 */
93  		public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
94  			NoCommentsInsert insert = new NoCommentsInsert(m_dialect);
95  			return insert;
96  		}
97  
98  		/**
99  		 * {@inheritDoc}
100 		 */
101 		protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
102 			return session.getBatcher().prepareStatement(insertSQL, m_keyColumns);
103 		}
104 
105 		/**
106 		 * {@inheritDoc}
107 		 */
108 		protected Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
109 			insert.executeUpdate();
110 			return IdentifierGeneratorHelper.getGeneratedIdentity(
111 				insert.getGeneratedKeys(),
112 				getPersister().getIdentifierType());
113 		}
114 	}
115 }