/** * Execute statement to remove entity with given identity from database using given JDBC * connection. * * @param conn CastorConnection holding connection and PersistenceFactory to be used to create * statement. * @param identity Identity of the object to remove. * @throws PersistenceException If failed to remove object from database. This could happen if a * database access error occurs, type of one of the values to bind is ambiguous or object to * be deleted does not exist. */ public void executeStatement(final CastorConnection conn, final Identity identity) throws PersistenceException { CastorStatement stmt = conn.createStatement(); try { stmt.prepareStatement(_delete); // bind the identity of the row to be stored into the preparedStatement for (ColumnValue value : _tableInfo.toSQL(identity)) { stmt.bindParameter(value.getName(), value.getValue(), value.getType()); } if (LOG.isDebugEnabled()) { LOG.debug(Messages.format("jdo.removing", _type, stmt.toString())); } // execute prepared statement int result = stmt.executeUpdate(); // throw exception if execute returned < 1 if (result < 1) { throw new SQLException("Object to be deleted does not exist!"); } } catch (SQLException ex) { LOG.fatal(Messages.format("jdo.deleteFatal", _type, stmt.toString()), ex); throw new PersistenceException(Messages.format("persist.nested", ex), ex); } finally { // close statement try { stmt.close(); } catch (SQLException e) { LOG.warn("Problem closing JDBC statement", e); } } }
/** * Load key generator definitions, check for duplicate definitions and convert them to key * generator descriptors. * * @param mapping Mapping to load key generator defintions from. * @throws MappingException If mapping contains more then one key generator definition with same * name. */ private void createKeyGenDescriptors(final MappingRoot mapping) throws MappingException { Enumeration enumeration = mapping.enumerateKeyGeneratorDef(); while (enumeration.hasMoreElements()) { KeyGeneratorDef def = (KeyGeneratorDef) enumeration.nextElement(); // resolve name of the key generator definition; if there's an alias // defined, use it; if not, fall back to the name attribute (this // is to ensure that for one key generator type (e.g. HIGH-LOW), it is // possible to define more than one instance with individual // configuration(s). String name = def.getAlias(); if (name == null) { name = def.getName(); } KeyGeneratorDescriptor desc = _keyGeneratorDescriptors.get(name); if (desc != null) { throw new MappingException(Messages.format("mapping.dupKeyGen", name)); } Properties params = new Properties(); Enumeration enumerateParam = def.enumerateParam(); while (enumerateParam.hasMoreElements()) { Param par = (Param) enumerateParam.nextElement(); params.put(par.getName(), par.getValue()); } desc = new KeyGeneratorDescriptor(name, def.getName(), params); _keyGeneratorDescriptors.put(name, desc); } }
/** * Initialize JDBC DataSource instance with the given database configuration instances and the * given class loader. * * @param database Database configuration. * @param loader ClassLoader to use. * @return The initalized DataSource. * @throws MappingException Problem related to analysing the JDO configuration. */ public static DataSource loadDataSource(final Database database, final ClassLoader loader) throws MappingException { DataSource dataSource; Param[] parameters; DatabaseChoice dbChoice = database.getDatabaseChoice(); String className = dbChoice.getDataSource().getClassName(); ClassLoader classLoader = loader; if (classLoader == null) { classLoader = Thread.currentThread().getContextClassLoader(); } try { Class dsClass = Class.forName(className, true, classLoader); dataSource = (DataSource) dsClass.newInstance(); } catch (Exception e) { String msg = Messages.format("jdo.engine.classNotInstantiable", className); LOG.error(msg, e); throw new MappingException(msg, e); } parameters = database.getDatabaseChoice().getDataSource().getParam(); setParameters(dataSource, parameters); return dataSource; }
/** * {@inheritDoc} * * @see org.castor.persist.AbstractTransactionContext * #createConnection(org.exolab.castor.persist.LockEngine) */ protected Connection createConnection(final LockEngine engine) throws ConnectionFailedException { // Get a new connection from the engine. Since the engine has no // transaction association, we must do this sort of round trip. An attempt // to have the transaction association in the engine inflates the code size // in other places. try { return engine.getDatabaseContext().getConnectionFactory().createConnection(); } catch (SQLException ex) { throw new ConnectionFailedException(Messages.format("persist.nested", ex), ex); } }
public void unmarkReadOnly(final Object o) { _operation++; Object object = supportCGLibObject(o); if (!isTracking(object)) { throw new IllegalStateException( Messages.format( "persist.internal", "Attempt to make read-write object that is not in transaction")); } // Add it to our list of read only objects. _readWriteSet.add(object); _readOnlySet.remove(object); }
/** * Build SQL statement to remove entities of the type this class is responsible for. * * @param mapTo Table name retrieved from Class Descriptor trough JDO Nature. */ private void buildStatement(final String mapTo) { // build condition for delete statement Condition condition = new AndCondition(); for (ColumnInfo col : _tableInfo.getPrimaryKey().getColumns()) { String name = col.getName(); condition.and(new Column(name).equal(new Parameter(name))); } // build delete class hierarchy that represents SQL query _delete = new Delete(mapTo); _delete.setCondition(condition); if (LOG.isTraceEnabled()) { LOG.trace(Messages.format("jdo.removing", _type, _delete.toString())); } }
/** * Set all the parameters of the given array at the given datasource by calling one of the set * methods of the datasource. * * @param dataSource The datasource to set the parameters on. * @param params The parameters to set on the datasource. * @throws MappingException If one of the parameters could not be set. */ public static void setParameters(final DataSource dataSource, final Param[] params) throws MappingException { Method[] methods = dataSource.getClass().getMethods(); for (int j = 0; j < params.length; j++) { String name = buildMethodName(params[j].getName()); String value = params[j].getValue(); boolean success = false; Exception cause = null; try { int i = 0; while (!success && (i < methods.length)) { Method method = methods[i]; Class[] types = method.getParameterTypes(); if ((method.getName().equals(name)) && (types.length == 1)) { if (types[0] == String.class) { method.invoke(dataSource, new Object[] {value}); success = true; } else if (types[0] == int.class) { method.invoke(dataSource, new Object[] {new Integer(value)}); success = true; } else if (types[0] == long.class) { method.invoke(dataSource, new Object[] {new Long(value)}); success = true; } else if (types[0] == boolean.class) { method.invoke(dataSource, new Object[] {new Boolean(value)}); success = true; } } i++; } } catch (Exception e) { cause = e; } if (!success || (cause != null)) { String msg = Messages.format("jdo.engine.datasourceParaFail", params[j].getName(), value); LOG.error(msg, cause); throw new MappingException(msg, cause); } } }
/** * {@inheritDoc} * * @see org.castor.persist.AbstractTransactionContext#closeConnections() */ protected void closeConnections() throws TransactionAbortedException { // Go through all the connections opened in this transaction and close them // one by one. Close all that can be closed, after that report error if any. Exception error = null; Iterator iter = connectionsIterator(); while (iter.hasNext()) { try { ((Connection) iter.next()).close(); } catch (SQLException ex) { error = ex; } } clearConnections(); if (error != null) { throw new TransactionAbortedException(Messages.format("persist.nested", error), error); } }
protected ClassDescriptor createClassDescriptor(final ClassMapping classMapping) throws MappingException { // If there is no SQL information for class, ignore it. if ((classMapping.getMapTo() == null) || (classMapping.getMapTo().getTable() == null)) { LOG.info(Messages.format("mapping.ignoringMapping", classMapping.getName())); return null; } // Create the class descriptor, and register the JDO nature with it. ClassDescriptorImpl clsDesc = new ClassDescriptorImpl(); clsDesc.addNature(ClassDescriptorJDONature.class.getName()); ClassDescriptorJDONature jdoNature = new ClassDescriptorJDONature(clsDesc); // Obtain the Java class. Class<?> javaClass = resolveType(classMapping.getName()); if (!Types.isConstructable(javaClass, true)) { throw new MappingException("mapping.classNotConstructable", javaClass.getName()); } clsDesc.setJavaClass(javaClass); // If this class extends another class, we need to obtain the extended // class and make sure this class indeed extends it. ClassDescriptor extDesc = getExtended(classMapping, javaClass); if (extDesc != null) { if (!(extDesc.hasNature(ClassDescriptorJDONature.class.getName()))) { throw new IllegalArgumentException("Extended class does not have a JDO descriptor"); } new ClassDescriptorJDONature(extDesc).addExtended(clsDesc); } clsDesc.setExtends(extDesc); // If this class depends on another class, obtain the class it depends upon. clsDesc.setDepends(getDepended(classMapping, javaClass)); // Create all field descriptors. FieldDescriptorImpl[] allFields = createFieldDescriptors(classMapping, javaClass); // Make sure there are no two fields with the same name. checkFieldNameDuplicates(allFields, javaClass); // Set class descriptor containing the field for (int i = 0; i < allFields.length; i++) { allFields[i].setContainingClassDescriptor(clsDesc); } // Identify identity and normal fields. Note that order must be preserved. List<FieldDescriptor> fieldList = new ArrayList<FieldDescriptor>(allFields.length); List<FieldDescriptor> idList = new ArrayList<FieldDescriptor>(); if (extDesc == null) { // Sort fields into 2 lists based on identity definition of field. for (int i = 0; i < allFields.length; i++) { if (!allFields[i].isIdentity()) { fieldList.add(allFields[i]); } else { idList.add(allFields[i]); } } if (idList.size() == 0) { // Found no identities based on identity definition of field. // Try to find identities based on identity definition on class. String[] idNames = classMapping.getIdentity(); if ((idNames == null) || (idNames.length == 0)) { // There are also no identity definitions on class. throw new MappingException("mapping.noIdentity", javaClass.getName()); } FieldDescriptor identity; for (int i = 0; i < idNames.length; i++) { identity = findIdentityByName(fieldList, idNames[i], javaClass); if (identity != null) { idList.add(identity); } else { throw new MappingException("mapping.identityMissing", idNames[i], javaClass.getName()); } } } } else { // Add all fields of extending class to field list. for (int i = 0; i < allFields.length; i++) { fieldList.add(allFields[i]); } // Add all identities of extended class to identity list. FieldDescriptor[] extIds = ((ClassDescriptorImpl) extDesc).getIdentities(); for (int i = 0; i < extIds.length; i++) { idList.add(extIds[i]); } // Search redefined identities in extending class. FieldDescriptor identity; for (int i = 0; i < idList.size(); i++) { String idName = (idList.get(i)).getFieldName(); identity = findIdentityByName(fieldList, idName, javaClass); if (identity != null) { idList.set(i, identity); } } } // Set identities on class descriptor. FieldDescriptor[] ids = new FieldDescriptor[idList.size()]; clsDesc.setIdentities(idList.toArray(ids)); // Set fields on class descriptor. FieldDescriptor[] fields = new FieldDescriptor[fieldList.size()]; clsDesc.setFields(fieldList.toArray(fields)); jdoNature.setTableName(classMapping.getMapTo().getTable()); // Set the field name used for object modification checks. jdoNature.setVersionField(classMapping.getVersion()); extractAndSetAccessMode(jdoNature, classMapping); extractAndAddCacheParams(jdoNature, classMapping, javaClass); extractAndAddNamedQueries(jdoNature, classMapping); extractAndAddNamedNativeQueries(jdoNature, classMapping); extractAndSetKeyGeneratorDescriptor(jdoNature, classMapping.getKeyGenerator()); return clsDesc; }