1 package org.apache.ojb.broker.util.sequence; 2 3 17 18 import java.sql.ResultSet ; 19 import java.sql.SQLException ; 20 import java.sql.Statement ; 21 22 import org.apache.commons.logging.Log; 23 import org.apache.commons.logging.LogFactory; 24 import org.apache.ojb.broker.PersistenceBroker; 25 import org.apache.ojb.broker.accesslayer.JdbcAccess; 26 import org.apache.ojb.broker.metadata.ClassDescriptor; 27 import org.apache.ojb.broker.metadata.FieldDescriptor; 28 import org.apache.ojb.broker.metadata.fieldaccess.PersistentField; 29 30 31 82 public class SequenceManagerNativeImpl extends AbstractSequenceManager 83 { 84 private Log log = LogFactory.getLog(SequenceManagerNativeImpl.class); 85 86 99 private static volatile long tempKey = -1; 100 101 public SequenceManagerNativeImpl(PersistenceBroker broker) 102 { 103 super(broker); 104 } 105 106 public void afterStore(JdbcAccess dbAccess, ClassDescriptor cld, Object obj) throws SequenceManagerException 107 { 108 FieldDescriptor identityField = extractIdentityColumnField(cld); 109 if(identityField != null) 110 { 111 ifNotReadOnlyFail(identityField); 112 long newId = getLastInsert(cld, identityField); 113 setFieldValue(obj, identityField, new Long (newId)); 114 } 115 } 116 117 124 private FieldDescriptor extractIdentityColumnField(ClassDescriptor cld) 125 { 126 FieldDescriptor[] pkFields = cld.getPkFields(); 127 for(int i = 0; i < pkFields.length; i++) 128 { 129 if(pkFields[i].isAutoIncrement() && pkFields[i].isAccessReadOnly()) 132 { 133 return pkFields[i]; 134 } 135 } 136 return null; 137 } 138 139 private void ifNotReadOnlyFail(FieldDescriptor field) throws SequenceManagerException 140 { 141 if(!field.isAccessReadOnly()) 143 { 144 throw new SequenceManagerException("Can't find Identity column: Identity columns/fields need to be declared as" + 145 " 'autoincrement' with 'readonly' access in field-descriptor"); 146 } 147 } 148 149 private long getLastInsert(ClassDescriptor cld, FieldDescriptor field) throws SequenceManagerException 150 { 151 long newId = 0; 152 Statement stmt = null; 153 if(field != null) 154 { try 156 { 157 stmt = getBrokerForClass().serviceConnectionManager().getConnection().createStatement(); 158 ResultSet rs = stmt.executeQuery(lastInsertSelect(cld.getFullTableName())); 159 if(!rs.next()) 160 { 161 throw new SequenceManagerException("Could not find native identifier"); 162 } 163 newId = rs.getLong(1); 164 rs.close(); 165 if(log.isDebugEnabled()) log.debug("After store - newid=" + newId); 166 } 167 catch(Exception e) 168 { 169 throw new SequenceManagerException(e); 170 } 171 finally 172 { 173 try 174 { 175 if(stmt != null) stmt.close(); 176 } 177 catch(SQLException e) 178 { 179 if(log.isDebugEnabled()) 180 log.debug("Threw SQLException while in getLastInsert and closing stmt", e); 181 } 183 } 184 } 185 else 186 { 187 throw new SequenceManagerException("No autoincrement field declared, please check repository for " + cld); 188 } 189 return newId; 190 } 191 192 195 protected String lastInsertSelect(String tableName) 196 { 197 return getBrokerForClass().serviceConnectionManager(). 198 getSupportedPlatform().getLastInsertIdentityQuery(tableName); 199 } 200 201 private void setFieldValue(Object obj, FieldDescriptor field, Long identifier) throws SequenceManagerException 202 { 203 Object result = field.getJdbcType().sequenceKeyConversion(identifier); 204 result = field.getFieldConversion().sqlToJava(result); 205 PersistentField pf = field.getPersistentField(); 206 pf.set(obj, result); 207 } 208 209 212 protected long getUniqueLong(FieldDescriptor field) throws SequenceManagerException 213 { 214 220 return --tempKey; 221 } 222 } 223 | Popular Tags |