001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb.plugins.cmp.jdbc2.keygen;
023:
024: import org.jboss.deployment.DeploymentException;
025: import org.jboss.ejb.EntityEnterpriseContext;
026: import org.jboss.ejb.plugins.cmp.jdbc.JDBCUtil;
027: import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCFieldBridge;
028: import org.jboss.ejb.plugins.cmp.jdbc2.CreateCommand;
029: import org.jboss.ejb.plugins.cmp.jdbc2.JDBCStoreManager2;
030: import org.jboss.ejb.plugins.cmp.jdbc2.PersistentContext;
031: import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCCMPFieldBridge2;
032: import org.jboss.ejb.plugins.cmp.jdbc2.bridge.JDBCEntityBridge2;
033: import org.jboss.logging.Logger;
034:
035: import java.lang.reflect.Method;
036: import java.sql.Connection;
037: import java.sql.PreparedStatement;
038: import java.sql.ResultSet;
039: import java.sql.SQLException;
040:
041: import javax.ejb.CreateException;
042: import javax.ejb.DuplicateKeyException;
043:
044: /**
045: * Abstract create command
046: * @author <a href="mailto:jep@worldleaguesports.com">Jesper Pedersen</a>
047: * @version <tt>$Revision: 57209 $</tt>
048: */
049: public abstract class AbstractCreateCommand implements CreateCommand {
050: protected JDBCEntityBridge2 entityBridge;
051: protected Logger log;
052: protected JDBCCMPFieldBridge2 pkField;
053: protected String pkSql;
054:
055: public void init(JDBCStoreManager2 manager)
056: throws DeploymentException {
057: this .entityBridge = (JDBCEntityBridge2) manager
058: .getEntityBridge();
059: this .log = Logger.getLogger(getClass().getName() + "."
060: + entityBridge.getEntityName());
061:
062: final JDBCFieldBridge[] pkFields = entityBridge
063: .getPrimaryKeyFields();
064: if (pkFields.length > 1) {
065: throw new DeploymentException(
066: "This entity-command cannot be used with composite primary keys!");
067: }
068:
069: this .pkField = (JDBCCMPFieldBridge2) pkFields[0];
070: this .pkSql = "";
071: }
072:
073: public Object execute(Method m, Object[] args,
074: EntityEnterpriseContext ctx) throws CreateException {
075: Object pk;
076: PersistentContext pctx = (PersistentContext) ctx
077: .getPersistenceContext();
078: if (ctx.getId() == null) {
079: Connection con = null;
080: PreparedStatement ps = null;
081: ResultSet rs = null;
082: try {
083: if (log.isDebugEnabled()) {
084: log.debug("executing sql: " + pkSql);
085: }
086:
087: con = entityBridge.getDataSource().getConnection();
088: ps = con.prepareStatement(pkSql);
089: rs = ps.executeQuery();
090:
091: if (!rs.next()) {
092: throw new CreateException("pk-sql " + pkSql
093: + " returned no results!");
094: }
095:
096: pk = pkField.loadArgumentResults(rs, 1);
097: pctx.setFieldValue(pkField.getRowIndex(), pk);
098: pk = entityBridge.extractPrimaryKeyFromInstance(ctx);
099: } catch (SQLException e) {
100: log.error("Failed to execute pk sql. error code: "
101: + e.getErrorCode() + ", sql state: "
102: + e.getSQLState(), e);
103: throw new CreateException("Failed to execute pk sql: "
104: + e.getMessage() + ", error code: "
105: + e.getErrorCode() + ", sql state: "
106: + e.getSQLState());
107: } finally {
108: JDBCUtil.safeClose(rs);
109: JDBCUtil.safeClose(ps);
110: JDBCUtil.safeClose(con);
111: }
112:
113: if (pk == null) {
114: log.error("Primary key for created instance is null.");
115: throw new CreateException(
116: "Primary key for created instance is null.");
117: }
118:
119: pctx.setPk(pk);
120: } else {
121: // insert-after-ejb-post-create
122: try {
123: pctx.flush();
124: } catch (SQLException e) {
125: if ("23000".equals(e.getSQLState())) {
126: throw new DuplicateKeyException(
127: "Unique key violation or invalid foreign key value: pk="
128: + ctx.getId());
129: } else {
130: throw new CreateException(
131: "Failed to create instance: pk="
132: + ctx.getId() + ", state="
133: + e.getSQLState() + ", msg="
134: + e.getMessage());
135: }
136: }
137: pk = ctx.getId();
138: }
139: return pk;
140: }
141: }
|