this.currentErrors.clear();
currentErrors.putAll(validateAll());
if (currentErrors.size() > 0)
{
throw new PersistenceException("Field validation errors in persistent '" + myMetaData.getName() + "': ",
getErrors());
}
/*
* Go through all the fields, setting to their default values if they
* are null
*/
String oneFieldName = null;
Object oneFieldValue = null;
for (Iterator i = myMetaData.getFieldNames().iterator(); i.hasNext();)
{
oneFieldName = (String) i.next();
oneFieldValue = getField(oneFieldName);
if (getField(oneFieldName) == null)
{
setField(oneFieldName, myMetaData.getDefaultValue(oneFieldName));
}
else if (oneFieldValue.toString().equals(""))
{
setField(oneFieldName, myMetaData.getDefaultValue(oneFieldName));
}
}
boolean needComma = false;
haveAllKeys(false, true);
if (getHelper() != null)
{
getHelper().beforeAdd(this);
}
SuperString sqlCommand = new SuperString(96);
sqlCommand.append("INSERT INTO ");
sqlCommand.append(myMetaData.getTableName());
sqlCommand.append(" (");
SuperString valuesCommand = new SuperString(64);
valuesCommand.append(") VALUES (");
boolean needCommaValues = false;
String identityFieldName = null;
for (Iterator i = myMetaData.getFieldNames().iterator(); i.hasNext();)
{
oneFieldName = (String) i.next();
checkField(oneFieldName, getFieldString(oneFieldName));
if ("identity".equals(myMetaData.getAutoIncremented(oneFieldName)))
{
identityFieldName = oneFieldName;
continue;
}
if (needComma)
{
sqlCommand.append(", ");
}
sqlCommand.append(myMetaData.getDBFieldName(oneFieldName));
needComma = true;
if (needCommaValues)
{
valuesCommand.append(", ");
}
if (myMetaData.isAutoIncremented(oneFieldName))
{
/*
* If identityFieldName is not null, we've already used the one
* (and only) identity for this table
*/
if ((identityFieldName == null) && myMetaData.isKeyField(oneFieldName)
&& myMetaData.getDatabaseType().isIdentitySupported()
&& (myMetaData.getIdGenerator(oneFieldName) == null))
{
// Native auto-inc is supported using "IDENTITY" type
// syntax
identityFieldName = oneFieldName;
valuesCommand.append(myMetaData.getDatabaseType().getInsertIdentitySyntax());
}
else
{
setAutoIncrement(oneFieldName);
valuesCommand.append("?");
}
}
else
{
valuesCommand.append("?");
}
needCommaValues = true;
} /* for each field */
//Now we merge the values of the parallel loops
sqlCommand.append(valuesCommand);
sqlCommand.append(")");
try
{
Connection myConnection = null;
PreparedStatement ps = null;
Statement s = null;
ResultSet rs = null;
try
{
if (currentTransaction != null)
{
myConnection = currentTransaction.getConnection();
}
else
{
try
{
myConnection = myDataSource.getConnection();
}
catch (ConcurrentModificationException cme)
{
addError(cme);
throw new PersistenceException("Unable to prepare statement", cme, getErrors());
}
}
ps = myConnection.prepareStatement(sqlCommand.toString());
// Lock the DB table so we can retrieve the identity field
// in a concurrent-safe fashion
this.lock();
// populate the fields for the update
int count = 1;
for (Iterator i = myMetaData.getFieldNames().iterator(); i.hasNext();)
{
oneFieldName = (String) i.next();
if ("identity".equals(myMetaData.getAutoIncremented(oneFieldName)))
{
continue;
}
//ACR: Changed to properly set based on types. Still some
// work
//to do for blobs....
this.setPreparedStatementObject(ps, count, oneFieldName);
count++;
//}
} /* for each field */
if (log.isDebugEnabled())
{
log.debug("Executing: " + sqlCommand.toString() + "(" + ps.toString() + ") on " + toString());
}
int updateCount = ps.executeUpdate();
if ((updateCount == 0) && (getCheckZeroUpdate()))
{
throw new PersistenceException("No records updated", getErrors());
}
ps.close();
ps = null;
if (identityFieldName != null)
{
s = myConnection.createStatement();
rs = s.executeQuery(myMetaData.getDatabaseType().getRetrieveIdentitySyntax(myMetaData,
identityFieldName));
if (rs.next())
{
String identityValue = rs.getString(1);
setField(identityFieldName, identityValue);
rs.close();
rs = null;
s.close();
s = null;
}
else
{
throw new PersistenceException("No value returned for identity field: " + identityFieldName,
getErrors());
}
}
}
catch (ClassCastException cce)
{
addError(cce);
throw new PersistenceException("Unable to add record to database" + toString() + ":" + cce.getMessage()
+ " (" + sqlCommand + ")", getErrors());
}
catch (PersistenceException de)
{
addError(de);
throw new PersistenceException("Unable to add record to database" + toString() + ":" + de.getMessage()
+ " (" + sqlCommand + ")", getErrors());
}
finally
{
//unlock the DB table
this.unlock();
cleanUp(myConnection, s, rs, ps);
}
setStatus(Persistent.CURRENT);
if (getHelper() != null)
{
getHelper().afterAdd(this);
}
}
catch (SQLException se)
{
addError(se);
throw new PersistenceException(se, getErrors());
}
} /* add() */