From 6ada436c53a038351e73d292a1ce390b85033587 Mon Sep 17 00:00:00 2001 From: andyjefferson Date: Mon, 28 Jun 2021 16:02:57 +0100 Subject: [PATCH] Remove insertPostProcessing from MappingCallbacks. Merge insert and update post processing into setPostProcessing(...) on JavaTypeMapping, and add specific callback in UpdateRequest rather than just dumping it into postUpdate. Remove MappingCallbacks from some of the Oracle type mappings that don't need any actual relationship management (what MappingCallbacks is intended for). Add placeholder for setPostProcessing on OracleCollection/OracleMap/OracleArray for when we want to handle BLOB/CLOB in a join table (#14). Fixes #365. --- .../store/rdbms/mapping/MappingCallbacks.java | 13 +--- ...tInsert.java => ColumnMappingPostSet.java} | 12 +-- .../column/ColumnMappingPostUpdate.java | 34 -------- .../column/OracleBlobColumnMapping.java | 10 +-- .../column/OracleClobColumnMapping.java | 10 +-- .../rdbms/mapping/java/ArrayMapping.java | 4 - .../rdbms/mapping/java/CollectionMapping.java | 4 - .../rdbms/mapping/java/EmbeddedPCMapping.java | 4 - .../rdbms/mapping/java/JavaTypeMapping.java | 73 +++++------------ .../store/rdbms/mapping/java/MapMapping.java | 5 -- .../mapping/java/OracleArrayMapping.java | 6 ++ .../mapping/java/OracleBitSetMapping.java | 46 +++-------- .../mapping/java/OracleCollectionMapping.java | 7 ++ .../rdbms/mapping/java/OracleMapMapping.java | 7 ++ .../java/OracleSerialisedObjectMapping.java | 48 +++--------- .../java/OracleSerialisedPCMapping.java | 44 ++--------- .../mapping/java/OracleStringLobMapping.java | 47 ++++------- .../mapping/java/PersistableMapping.java | 4 - .../rdbms/mapping/java/ReferenceMapping.java | 9 --- .../java/SerialisedLocalFileMapping.java | 4 - .../mapping/java/SingleCollectionMapping.java | 8 -- .../store/rdbms/request/InsertRequest.java | 78 ++++++++++++------- .../store/rdbms/request/UpdateRequest.java | 78 ++++++++++++++----- .../store/rdbms/Localisation.properties | 2 +- .../store/rdbms/Localisation_es.properties | 2 +- 25 files changed, 201 insertions(+), 358 deletions(-) rename src/main/java/org/datanucleus/store/rdbms/mapping/column/{ColumnMappingPostInsert.java => ColumnMappingPostSet.java} (77%) delete mode 100644 src/main/java/org/datanucleus/store/rdbms/mapping/column/ColumnMappingPostUpdate.java diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/MappingCallbacks.java b/src/main/java/org/datanucleus/store/rdbms/mapping/MappingCallbacks.java index a2ef1852c..321e06bd9 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/MappingCallbacks.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/MappingCallbacks.java @@ -22,20 +22,11 @@ import org.datanucleus.state.ObjectProvider; /** - * Interface defining a series of callbacks that are called when this mapping goes through - * certain lifecycle events. This interface would be implemented by any type of mapping that handles - * a relation and so may need to perform action just before or just after a lifecycle event. + * Interface defining a series of callbacks that are called when this mapping goes through certain lifecycle events. + * This interface would be implemented by any type of mapping that handles a relation and so may need to perform action just before or just after a lifecycle event. */ public interface MappingCallbacks { - /** - * Hook so that we can handle any post-processing on the insert of a particular field. - * For example with Oracle we need to insert "EMPTY_CLOB" and then immediately after do a SELECT of it - * and update the contents of the CLOB/BLOB. - * @param op ObjectProvider - */ - void insertPostProcessing(ObjectProvider op); - /** * Method called after the insert of the object so that additional operations can be performed if necessary. * @param op ObjectProvider of the owner diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/column/ColumnMappingPostInsert.java b/src/main/java/org/datanucleus/store/rdbms/mapping/column/ColumnMappingPostSet.java similarity index 77% rename from src/main/java/org/datanucleus/store/rdbms/mapping/column/ColumnMappingPostInsert.java rename to src/main/java/org/datanucleus/store/rdbms/mapping/column/ColumnMappingPostSet.java index 130ceb225..91c6523f7 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/column/ColumnMappingPostInsert.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/column/ColumnMappingPostSet.java @@ -20,15 +20,15 @@ import org.datanucleus.state.ObjectProvider; /** - * Interface implemented by any ColumnMapping that requires a post-insert step. + * Interface implemented by any ColumnMapping that requires a post-set (insert/update) step. * For example, with Oracle CLOB/BLOB the INSERT will just put "EMPTY_CLOB" or "EMPTY_BLOB" and this will SELECT the column and update it. */ -public interface ColumnMappingPostInsert +public interface ColumnMappingPostSet { /** - * Perform any INSERT post processing on this column, using the provided value. - * @param op ObjectProvider for object being inserted - * @param value The value to use on the insert + * Perform any post "set" processing on this column, using the provided value. + * @param op ObjectProvider for object being set + * @param value The value to use on the set */ - void insertPostProcessing(ObjectProvider op, Object value); + void setPostProcessing(ObjectProvider op, Object value); } \ No newline at end of file diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/column/ColumnMappingPostUpdate.java b/src/main/java/org/datanucleus/store/rdbms/mapping/column/ColumnMappingPostUpdate.java deleted file mode 100644 index 22a0ced2c..000000000 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/column/ColumnMappingPostUpdate.java +++ /dev/null @@ -1,34 +0,0 @@ -/********************************************************************** -Copyright (c) 2021 Andy Jefferson and others. All rights reserved. -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -Contributors: - ... -**********************************************************************/ -package org.datanucleus.store.rdbms.mapping.column; - -import org.datanucleus.state.ObjectProvider; - -/** - * Interface implemented by any ColumnMapping that requires a post-UPDATE step. - * For example, with Oracle CLOB/BLOB the UPDATE will just put "EMPTY_CLOB" or "EMPTY_BLOB" and this will SELECT the column and update it. - */ -public interface ColumnMappingPostUpdate -{ - /** - * Perform any UPDATE post processing on this column, using the provided value. - * @param op ObjectProvider for object being updated - * @param value The value to use on the UPDATE - */ - void updatePostProcessing(ObjectProvider op, Object value); -} \ No newline at end of file diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/column/OracleBlobColumnMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/column/OracleBlobColumnMapping.java index 9ff56ed2a..a6fca1de1 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/column/OracleBlobColumnMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/column/OracleBlobColumnMapping.java @@ -72,7 +72,7 @@ * Mapping for an Oracle BLOB column. * Extends the standard JDBC handler so that we can insert an empty BLOB, and then update it (Oracle non-standard behaviour). */ -public class OracleBlobColumnMapping extends AbstractColumnMapping implements ColumnMappingPostInsert, ColumnMappingPostUpdate +public class OracleBlobColumnMapping extends AbstractColumnMapping implements ColumnMappingPostSet { /** * Constructor. @@ -295,13 +295,7 @@ public boolean includeInSQLFetchStatement() } @Override - public void updatePostProcessing(ObjectProvider op, Object value) - { - updateBlobColumn(op, getJavaTypeMapping().getTable(), this, (byte[])value); // TODO Remove byte[] cast - } - - @Override - public void insertPostProcessing(ObjectProvider op, Object value) + public void setPostProcessing(ObjectProvider op, Object value) { updateBlobColumn(op, getJavaTypeMapping().getTable(), this, (byte[])value); // TODO Remove byte[] cast } diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/column/OracleClobColumnMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/column/OracleClobColumnMapping.java index 55094342d..89ffacd8a 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/column/OracleClobColumnMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/column/OracleClobColumnMapping.java @@ -60,7 +60,7 @@ * Mapping for an Oracle CLOB column. * Extends the standard JDBC handler so that we can insert an empty CLOB, and then update it (Oracle non-standard behaviour). */ -public class OracleClobColumnMapping extends ClobColumnMapping implements ColumnMappingPostInsert, ColumnMappingPostUpdate +public class OracleClobColumnMapping extends ClobColumnMapping implements ColumnMappingPostSet { public OracleClobColumnMapping(JavaTypeMapping mapping, RDBMSStoreManager storeMgr, Column col) { @@ -175,13 +175,7 @@ public Object getObject(ResultSet rs, int param) } @Override - public void insertPostProcessing(ObjectProvider op, Object value) - { - updateClobColumn(op, getJavaTypeMapping().getTable(), this, (String)value); // TODO Remove String cast - } - - @Override - public void updatePostProcessing(ObjectProvider op, Object value) + public void setPostProcessing(ObjectProvider op, Object value) { updateClobColumn(op, getJavaTypeMapping().getTable(), this, (String)value); // TODO Remove String cast } diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/java/ArrayMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/java/ArrayMapping.java index 3181c32df..437c5474a 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/java/ArrayMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/java/ArrayMapping.java @@ -73,10 +73,6 @@ protected boolean containerIsStoredInSingleColumn() // ---------------------- Implementation of MappingCallbacks ---------------------------------- - public void insertPostProcessing(ObjectProvider op) - { - } - /** * Method to be called after the insert of the owner class element. * @param ownerOP ObjectProvider of the owner diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/java/CollectionMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/java/CollectionMapping.java index 84ef30841..eb3dfb9fd 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/java/CollectionMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/java/CollectionMapping.java @@ -55,10 +55,6 @@ public Class getJavaType() // --------------- Implementation of MappingCallbacks ------------------- - public void insertPostProcessing(ObjectProvider ownerOP) - { - } - /** * Method to be called after the insert of the owner class element. * @param ownerOP ObjectProvider of the owner diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/java/EmbeddedPCMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/java/EmbeddedPCMapping.java index e91d24371..aa46bcfca 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/java/EmbeddedPCMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/java/EmbeddedPCMapping.java @@ -46,10 +46,6 @@ public void initialize(AbstractMemberMetaData mmd, Table table, ClassLoaderResol initialize(mmd, table, clr, mmd.getEmbeddedMetaData(), mmd.getTypeName(), ObjectProvider.EMBEDDED_PC); } - public void insertPostProcessing(ObjectProvider op) - { - } - /** * MappingCallback called when the owning object is being fetched. * @param op ObjectProvider of the owning object diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/java/JavaTypeMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/java/JavaTypeMapping.java index e02a92de4..7d49f40d4 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/java/JavaTypeMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/java/JavaTypeMapping.java @@ -31,8 +31,7 @@ import org.datanucleus.state.ObjectProvider; import org.datanucleus.store.rdbms.RDBMSStoreManager; import org.datanucleus.store.rdbms.mapping.column.ColumnMapping; -import org.datanucleus.store.rdbms.mapping.column.ColumnMappingPostInsert; -import org.datanucleus.store.rdbms.mapping.column.ColumnMappingPostUpdate; +import org.datanucleus.store.rdbms.mapping.column.ColumnMappingPostSet; import org.datanucleus.store.rdbms.table.Table; import org.datanucleus.util.Localiser; @@ -802,15 +801,14 @@ else if (role == FieldRole.ROLE_MAP_VALUE) } /** - * Accessor for whether any of the column mappings requires INSERT post processing. - * TODO Not yet utilised, see RDBMS-14 - * @return True if a column needs an INSERT post processing call + * Accessor for whether any of the column mappings requires INSERT/UPDATE post processing. + * @return True if a column needs an INSERT/UPDATE post processing call */ - public boolean requiresInsertPostProcessing() + public boolean requiresSetPostProcessing() { for (int i=0; i> OracleArrayMapping.performSetPostProc - DO NOTHING"); + } + /** * Method to be called after the insert of the owner class element. * @param ownerOP ObjectProvider of the owner diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleBitSetMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleBitSetMapping.java index 9a664e52e..9a75b8f10 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleBitSetMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleBitSetMapping.java @@ -25,22 +25,21 @@ import org.datanucleus.exceptions.NucleusDataStoreException; import org.datanucleus.state.ObjectProvider; -import org.datanucleus.store.rdbms.mapping.MappingCallbacks; import org.datanucleus.store.rdbms.mapping.column.BlobImpl; -import org.datanucleus.store.rdbms.mapping.column.OracleBlobColumnMapping; +import org.datanucleus.store.rdbms.mapping.column.ColumnMappingPostSet; import org.datanucleus.store.types.converters.ArrayConversionHelper; import org.datanucleus.util.Localiser; /** * Mapping for a BitSet type for Oracle. */ -public class OracleBitSetMapping extends BitSetMapping implements MappingCallbacks +public class OracleBitSetMapping extends BitSetMapping { /** - * Method to handle post-processing of the insert of the BLOB/CLOB for Oracle. - * @param op ObjectProvider of the owner + * Retrieve the empty BLOB created by the insert statement and write out the current BLOB field value to the Oracle BLOB object + * @param op the current ObjectProvider */ - public void insertPostProcessing(ObjectProvider op) + public void performSetPostProcessing(ObjectProvider op) { Object value = op.provideField(mmd.getAbsoluteFieldNumber()); if (value == null) @@ -86,36 +85,9 @@ else if (value instanceof java.util.BitSet) // Do nothing } - // Update the BLOB - OracleBlobColumnMapping.updateBlobColumn(op, getTable(), getColumnMapping(0), bytes); - } - - /** - * Method to be called after the insert of the owner class element. - * @param op ObjectProvider of the owner - **/ - public void postInsert(ObjectProvider op) - { - } - - /** - * Method to be called after any update of the owner class element. - * @param op ObjectProvider of the owner - */ - public void postUpdate(ObjectProvider op) - { - insertPostProcessing(op); - } - - public void deleteDependent(ObjectProvider op) - { - } - - public void postFetch(ObjectProvider op) - { - } - - public void preDelete(ObjectProvider op) - { + if (columnMappings[0] instanceof ColumnMappingPostSet) + { + ((ColumnMappingPostSet)columnMappings[0]).setPostProcessing(op, bytes); + } } } \ No newline at end of file diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleCollectionMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleCollectionMapping.java index 2812f2ffe..24e5cef6f 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleCollectionMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleCollectionMapping.java @@ -25,6 +25,7 @@ import org.datanucleus.ExecutionContext; import org.datanucleus.state.ObjectProvider; import org.datanucleus.store.rdbms.mapping.column.OracleBlobColumnMapping; +import org.datanucleus.util.NucleusLogger; /** * Oracle variant of the CollectionMapping for cases where we are serialising the field into a single column. @@ -32,6 +33,11 @@ */ public class OracleCollectionMapping extends CollectionMapping { + public void performSetPostProcessing(ObjectProvider op) + { + NucleusLogger.GENERAL.info(">> OracleCollectionMapping.performSetPostProc - DO NOTHING"); + } + /** * Retrieve the empty BLOB created by the insert statement and write out the * current BLOB field value to the Oracle BLOB object. @@ -120,6 +126,7 @@ public void postUpdate(ObjectProvider ownerOP) } } + // TODO This should really just be the generate the contents of the BLOB followed by call to OracleBlobColumnMapping.updateBlobColumn postInsert(ownerOP); } else diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleMapMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleMapMapping.java index 4aab9b14d..e2039e90f 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleMapMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleMapMapping.java @@ -27,6 +27,7 @@ import org.datanucleus.ExecutionContext; import org.datanucleus.state.ObjectProvider; import org.datanucleus.store.rdbms.mapping.column.OracleBlobColumnMapping; +import org.datanucleus.util.NucleusLogger; /** * Oracle variant of the MapMapping for cases where we are serialising the field into a single column. @@ -34,6 +35,11 @@ */ public class OracleMapMapping extends MapMapping { + public void performSetPostProcessing(ObjectProvider op) + { + NucleusLogger.GENERAL.info(">> OracleMapMapping.performSetPostProc - DO NOTHING"); + } + /** * Retrieve the empty BLOB created by the insert statement and write out the * current BLOB field value to the Oracle CLOB object. @@ -143,6 +149,7 @@ public void postUpdate(ObjectProvider ownerOP) } } + // TODO This should really just be the generate the contents of the BLOB followed by call to OracleBlobColumnMapping.updateBlobColumn postInsert(ownerOP); } else diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleSerialisedObjectMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleSerialisedObjectMapping.java index d3bd5c3a7..c3c7f1050 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleSerialisedObjectMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleSerialisedObjectMapping.java @@ -23,27 +23,18 @@ import java.io.ObjectOutputStream; import org.datanucleus.state.ObjectProvider; -import org.datanucleus.store.rdbms.mapping.MappingCallbacks; -import org.datanucleus.store.rdbms.mapping.column.OracleBlobColumnMapping; +import org.datanucleus.store.rdbms.mapping.column.ColumnMappingPostSet; /** - * Mapping for Object and Serializable types. + * Mapping for Object and Serializable types with Oracle. */ -public class OracleSerialisedObjectMapping extends SerialisedMapping implements MappingCallbacks +public class OracleSerialisedObjectMapping extends SerialisedMapping { /** - * @see org.datanucleus.store.rdbms.mapping.MappingCallbacks#postFetch(org.datanucleus.state.ObjectProvider) - */ - public void postFetch(ObjectProvider sm) - { - } - - /** - * Retrieve the empty BLOB created by the insert statement and write out the - * current BLOB field value to the Oracle BLOB object + * Retrieve the empty BLOB created by the insert statement and write out the current BLOB field value to the Oracle BLOB object * @param op the current ObjectProvider */ - public void insertPostProcessing(ObjectProvider op) + public void performSetPostProcessing(ObjectProvider op) { // Generate the contents for the BLOB byte[] bytes = new byte[0]; @@ -63,29 +54,10 @@ public void insertPostProcessing(ObjectProvider op) } } - // Update the BLOB - OracleBlobColumnMapping.updateBlobColumn(op, getTable(), getColumnMapping(0), bytes); - } - - /** - * @see org.datanucleus.store.rdbms.mapping.MappingCallbacks#postInsert(org.datanucleus.state.ObjectProvider) - */ - public void postInsert(ObjectProvider op) - { - } - - /** - * @see org.datanucleus.store.rdbms.mapping.MappingCallbacks#postUpdate(org.datanucleus.state.ObjectProvider) - */ - public void postUpdate(ObjectProvider op) - { - insertPostProcessing(op); - } - - /** - * @see org.datanucleus.store.rdbms.mapping.MappingCallbacks#preDelete(org.datanucleus.state.ObjectProvider) - */ - public void preDelete(ObjectProvider op) - { + if (columnMappings[0] instanceof ColumnMappingPostSet) + { + // Update the BLOB + ((ColumnMappingPostSet)columnMappings[0]).setPostProcessing(op, bytes); + } } } \ No newline at end of file diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleSerialisedPCMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleSerialisedPCMapping.java index d4be78d7b..7a0d2e6c9 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleSerialisedPCMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleSerialisedPCMapping.java @@ -24,20 +24,18 @@ import org.datanucleus.ExecutionContext; import org.datanucleus.state.ObjectProvider; -import org.datanucleus.store.rdbms.mapping.MappingCallbacks; -import org.datanucleus.store.rdbms.mapping.column.OracleBlobColumnMapping; +import org.datanucleus.store.rdbms.mapping.column.ColumnMappingPostSet; /** * Mapping for a serialised persistable object for Oracle. */ -public class OracleSerialisedPCMapping extends SerialisedPCMapping implements MappingCallbacks +public class OracleSerialisedPCMapping extends SerialisedPCMapping { /** - * Retrieve the empty BLOB created by the insert statement and write out the - * current BLOB field value to the Oracle BLOB object + * Retrieve the empty BLOB created by the insert statement and write out the current BLOB field value to the Oracle BLOB object * @param op the current ObjectProvider */ - public void insertPostProcessing(ObjectProvider op) + public void performSetPostProcessing(ObjectProvider op) { Object value = op.provideField(mmd.getAbsoluteFieldNumber()); ObjectProvider sm = null; @@ -75,40 +73,14 @@ public void insertPostProcessing(ObjectProvider op) } // Update the BLOB - OracleBlobColumnMapping.updateBlobColumn(op, getTable(), getColumnMapping(0), bytes); + if (columnMappings[0] instanceof ColumnMappingPostSet) + { + ((ColumnMappingPostSet)columnMappings[0]).setPostProcessing(op, bytes); + } if (sm != null) { sm.unsetStoringPC(); } } - - /** - * @see org.datanucleus.store.rdbms.mapping.MappingCallbacks#postInsert(org.datanucleus.state.ObjectProvider) - */ - public void postInsert(ObjectProvider op) - { - } - - /** - * @see org.datanucleus.store.rdbms.mapping.MappingCallbacks#postUpdate(org.datanucleus.state.ObjectProvider) - */ - public void postUpdate(ObjectProvider op) - { - insertPostProcessing(op); - } - - /** - * @see org.datanucleus.store.rdbms.mapping.MappingCallbacks#postFetch(org.datanucleus.state.ObjectProvider) - */ - public void postFetch(ObjectProvider op) - { - } - - /** - * @see org.datanucleus.store.rdbms.mapping.MappingCallbacks#preDelete(org.datanucleus.state.ObjectProvider) - */ - public void preDelete(ObjectProvider op) - { - } } \ No newline at end of file diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleStringLobMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleStringLobMapping.java index fa1574441..9aa8a7c19 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleStringLobMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/java/OracleStringLobMapping.java @@ -23,25 +23,22 @@ **********************************************************************/ package org.datanucleus.store.rdbms.mapping.java; -import org.datanucleus.exceptions.NucleusException; -import org.datanucleus.metadata.JdbcType; import org.datanucleus.state.ObjectProvider; import org.datanucleus.store.rdbms.RDBMSPropertyNames; -import org.datanucleus.store.rdbms.mapping.MappingCallbacks; +import org.datanucleus.store.rdbms.mapping.column.ColumnMappingPostSet; import org.datanucleus.store.rdbms.mapping.column.OracleBlobColumnMapping; import org.datanucleus.store.rdbms.mapping.column.OracleClobColumnMapping; /** * Mapping for a String type for Oracle when stored in a BLOB or CLOB column. */ -public class OracleStringLobMapping extends StringMapping implements MappingCallbacks +public class OracleStringLobMapping extends StringMapping { /** - * Retrieve the empty BLOB/CLOB locator created by the insert statement - * and write out the current BLOB/CLOB field value to the Oracle BLOB/CLOB object + * Retrieve the empty BLOB/CLOB locator created by the insert statement and write out the current BLOB/CLOB field value to the Oracle BLOB/CLOB object * @param op The ObjectProvider owner of this field */ - public void insertPostProcessing(ObjectProvider op) + public void performSetPostProcessing(ObjectProvider op) { // Generate the contents for the BLOB/CLOB String value = (String)op.provideField(mmd.getAbsoluteFieldNumber()); @@ -63,34 +60,16 @@ else if (value.length() == 0) } // Update BLOB/CLOB value - if (mmd.getColumnMetaData()[0].getJdbcType() == JdbcType.BLOB) + if (columnMappings[0] instanceof ColumnMappingPostSet) { - OracleBlobColumnMapping.updateBlobColumn(op, getTable(), getColumnMapping(0), value.getBytes()); - } - else if (mmd.getColumnMetaData()[0].getJdbcType() == JdbcType.CLOB) - { - OracleClobColumnMapping.updateClobColumn(op, getTable(), getColumnMapping(0), value); - } - else - { - throw new NucleusException("AssertionError: Only JDBC types BLOB and CLOB are allowed!"); + if (columnMappings[0] instanceof OracleBlobColumnMapping) + { + ((ColumnMappingPostSet)columnMappings[0]).setPostProcessing(op, value.getBytes()); + } + else if (columnMappings[0] instanceof OracleClobColumnMapping) + { + ((ColumnMappingPostSet)columnMappings[0]).setPostProcessing(op, value); + } } } - - public void postInsert(ObjectProvider op) - { - } - - public void postFetch(ObjectProvider op) - { - } - - public void postUpdate(ObjectProvider op) - { - insertPostProcessing(op); - } - - public void preDelete(ObjectProvider op) - { - } } \ No newline at end of file diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/java/PersistableMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/java/PersistableMapping.java index e9998ca64..73dacbed5 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/java/PersistableMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/java/PersistableMapping.java @@ -795,10 +795,6 @@ public void postFetch(ObjectProvider op) { } - public void insertPostProcessing(ObjectProvider op) - { - } - /** * Method executed just after the insert of the owning object, allowing any necessary action * to this field and the object stored in it. diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/java/ReferenceMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/java/ReferenceMapping.java index 53736e8bc..41ac900d7 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/java/ReferenceMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/java/ReferenceMapping.java @@ -751,15 +751,6 @@ public void postFetch(ObjectProvider op) { } - /** - * Method executed just after the insert of the owning object, allowing any necessary action - * to this field and the object stored in it. - * @param op ObjectProvider for the owner. - */ - public void insertPostProcessing(ObjectProvider op) - { - } - /** * Method executed just after the insert of the owning object, allowing any necessary action * to this field and the object stored in it. diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/java/SerialisedLocalFileMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/java/SerialisedLocalFileMapping.java index e91dbedb7..ec1f8b478 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/java/SerialisedLocalFileMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/java/SerialisedLocalFileMapping.java @@ -99,10 +99,6 @@ public Class getJavaType() return mmd.getType(); } - public void insertPostProcessing(ObjectProvider op) - { - } - public void postInsert(final ObjectProvider op) { Object val = op.provideField(mmd.getAbsoluteFieldNumber()); diff --git a/src/main/java/org/datanucleus/store/rdbms/mapping/java/SingleCollectionMapping.java b/src/main/java/org/datanucleus/store/rdbms/mapping/java/SingleCollectionMapping.java index 468d6fed6..58657e81c 100644 --- a/src/main/java/org/datanucleus/store/rdbms/mapping/java/SingleCollectionMapping.java +++ b/src/main/java/org/datanucleus/store/rdbms/mapping/java/SingleCollectionMapping.java @@ -138,14 +138,6 @@ public String getJavaTypeForColumnMapping(int index) return wrappedMapping.getJavaTypeForColumnMapping(index); } - public void insertPostProcessing(ObjectProvider op) - { - if (wrappedMapping instanceof MappingCallbacks) - { - ((MappingCallbacks) wrappedMapping).insertPostProcessing(op); - } - } - public void postInsert(ObjectProvider op) { if (wrappedMapping instanceof MappingCallbacks) diff --git a/src/main/java/org/datanucleus/store/rdbms/request/InsertRequest.java b/src/main/java/org/datanucleus/store/rdbms/request/InsertRequest.java index a3d2c59b6..3e1999328 100644 --- a/src/main/java/org/datanucleus/store/rdbms/request/InsertRequest.java +++ b/src/main/java/org/datanucleus/store/rdbms/request/InsertRequest.java @@ -100,7 +100,10 @@ public class InsertRequest extends Request { private static final int IDPARAMNUMBER = 1; - private final MappingCallbacks[] callbacks; + /** callback mappings will have their postInsert method called after the update */ + private final List mappingCallbacks; + + private final List postSetMappings; /** Numbers of fields in the INSERT statement (excluding PK). */ private final int[] insertFieldNumbers; @@ -189,7 +192,8 @@ public InsertRequest(DatastoreClass table, AbstractClassMetaData cmd, ClassLoade table.provideExternalMappings(consumer, MappingType.EXTERNAL_INDEX); table.provideUnmappedColumns(consumer); - callbacks = (MappingCallbacks[])consumer.getMappingCallbacks().toArray(new MappingCallbacks[consumer.getMappingCallbacks().size()]); + mappingCallbacks = consumer.getMappingCallbacks(); + postSetMappings = consumer.getPostSetMappings(); stmtMappings = consumer.getStatementMappings(); versionStmtMapping = consumer.getVersionStatementMapping(); discriminatorStmtMapping = consumer.getDiscriminatorStatementMapping(); @@ -502,14 +506,16 @@ else if (vermd != null && vermd.getFieldName() != null) } // Execute any mapping actions on the insert of the fields (e.g Oracle CLOBs/BLOBs) - for (int i = 0; i < callbacks.length; ++i) + if (postSetMappings != null) { - if (NucleusLogger.PERSISTENCE.isDebugEnabled()) + for (JavaTypeMapping m : postSetMappings) { - NucleusLogger.PERSISTENCE.debug(Localiser.msg("052222", op.getObjectAsPrintable(), - ((JavaTypeMapping)callbacks[i]).getMemberMetaData().getFullFieldName())); + if (NucleusLogger.PERSISTENCE.isDebugEnabled()) + { + NucleusLogger.PERSISTENCE.debug(Localiser.msg("052222", op.getObjectAsPrintable(), m.getMemberMetaData().getFullFieldName())); + } + m.performSetPostProcessing(op); } - callbacks[i].insertPostProcessing(op); } // Update the insert status for this table via the StoreManager @@ -585,22 +591,24 @@ else if (vermd != null && vermd.getFieldName() != null) throw new NucleusDataStoreException(msg, exceptions.toArray(new Throwable[exceptions.size()])); } - // Execute any mapping actions now that we have inserted the element - // (things like inserting any association parent-child). - for (int i = 0; i < callbacks.length; ++i) + // Execute any mapping actions now that we have inserted the element (things like inserting any association parent-child). + if (mappingCallbacks != null) { - try + for (MappingCallbacks m : mappingCallbacks) { - if (NucleusLogger.PERSISTENCE.isDebugEnabled()) + try + { + if (NucleusLogger.PERSISTENCE.isDebugEnabled()) + { + NucleusLogger.PERSISTENCE.debug(Localiser.msg("052209", IdentityUtils.getPersistableIdentityForId(op.getInternalObjectId()), + ((JavaTypeMapping)m).getMemberMetaData().getFullFieldName())); + } + m.postInsert(op); + } + catch (NotYetFlushedException e) { - NucleusLogger.PERSISTENCE.debug(Localiser.msg("052209", IdentityUtils.getPersistableIdentityForId(op.getInternalObjectId()), - ((JavaTypeMapping)callbacks[i]).getMemberMetaData().getFullFieldName())); + op.updateFieldAfterInsert(e.getPersistable(), ((JavaTypeMapping) m).getMemberMetaData().getAbsoluteFieldNumber()); } - callbacks[i].postInsert(op); - } - catch (NotYetFlushedException e) - { - op.updateFieldAfterInsert(e.getPersistable(), ((JavaTypeMapping) callbacks[i]).getMemberMetaData().getAbsoluteFieldNumber()); } } } @@ -717,7 +725,11 @@ private class InsertMappingConsumer implements MappingConsumer Map assignedColumns = new HashMap(); - List mc = new ArrayList(); + /** Mappings that require post-set processing. */ + List postSetMappings; + + /** Mappings that require callbacks calling. */ + List callbackMappings = null; boolean initialized = false; @@ -929,9 +941,21 @@ else if (!insertFields.contains(abs_field_num)) statementMappings[mmd.getAbsoluteFieldNumber()].addParameterOccurrence(parametersIndex); } } + if (m.requiresSetPostProcessing()) + { + if (postSetMappings == null) + { + postSetMappings = new ArrayList<>(); + } + postSetMappings.add(m); + } if (m instanceof MappingCallbacks) { - mc.add(m); + if (callbackMappings == null) + { + callbackMappings = new ArrayList<>(); + } + callbackMappings.add((MappingCallbacks)m); } } @@ -1232,12 +1256,14 @@ private StatementMappingIndex[] processExternalMapping(JavaTypeMapping mapping, return stmtExprIndex; } - /** - * @return Returns the mappingCallbacks. - */ - public List getMappingCallbacks() + public List getPostSetMappings() + { + return postSetMappings; + } + + public List getMappingCallbacks() { - return mc; + return callbackMappings; } /** diff --git a/src/main/java/org/datanucleus/store/rdbms/request/UpdateRequest.java b/src/main/java/org/datanucleus/store/rdbms/request/UpdateRequest.java index fc0c30477..d3519217c 100644 --- a/src/main/java/org/datanucleus/store/rdbms/request/UpdateRequest.java +++ b/src/main/java/org/datanucleus/store/rdbms/request/UpdateRequest.java @@ -86,8 +86,10 @@ public class UpdateRequest extends Request private final String updateStmtOptimistic; /** callback mappings will have their postUpdate method called after the update */ - private final MappingCallbacks[] callbacks; - + private final List mappingCallbacks; + + private final List postSetMappings; + /** the index for the expression in the update sql statement. */ private StatementMappingDefinition stmtMappingDefinition; @@ -244,7 +246,8 @@ else if (cmd.getIdentityType() == IdentityType.DATASTORE) } updateStmtOptimistic = consumer.getStatement(); - callbacks = (MappingCallbacks[])consumer.getMappingCallbacks().toArray(new MappingCallbacks[consumer.getMappingCallbacks().size()]); + mappingCallbacks = consumer.getMappingCallbacks(); + postSetMappings = consumer.getPostSetMappings(); whereFieldNumbers = consumer.getWhereFieldNumbers(); updateFieldNumbers = consumer.getUpdateFieldNumbers(); } @@ -457,6 +460,19 @@ else if (mmds[i].isUpdateUser()) // TODO Batching : when we use batching here we need to process these somehow throw new NucleusOptimisticException(Localiser.msg("052203", op.getObjectAsPrintable(), op.getInternalObjectId(), "" + currentVersion), op.getObject()); } + + // Execute any post-set mappings + if (postSetMappings != null) + { + for (JavaTypeMapping m : postSetMappings) + { + if (NucleusLogger.PERSISTENCE.isDebugEnabled()) + { + NucleusLogger.PERSISTENCE.debug(Localiser.msg("052222", op.getObjectAsPrintable(), m.getMemberMetaData().getFullFieldName())); + } + m.performSetPostProcessing(op); + } + } } finally { @@ -483,21 +499,23 @@ else if (mmds[i].isUpdateUser()) } // Execute any mapping actions now that we have done the update - for (int i=0; i postSetMappings; + + /** Mappings that require callbacks calling. */ + List callbackMappings = null; /** for UPDATE statement **/ StringBuilder columnAssignments = new StringBuilder(); @@ -692,9 +714,21 @@ public void consumeMapping(JavaTypeMapping m, AbstractMemberMetaData mmd) } } + if (m.requiresSetPostProcessing()) + { + if (postSetMappings == null) + { + postSetMappings = new ArrayList<>(); + } + postSetMappings.add(m); + } if (m instanceof MappingCallbacks) { - mc.add(m); + if (callbackMappings == null) + { + callbackMappings = new ArrayList<>(); + } + callbackMappings.add((MappingCallbacks) m); } } @@ -800,12 +834,14 @@ public StatementMappingIndex getUpdateTimestampStatementMapping() return updateTimestampStatementMapping; } - /** - * @return Returns the mappingCallbacks. - */ - public List getMappingCallbacks() + public List getPostSetMappings() + { + return postSetMappings; + } + + public List getMappingCallbacks() { - return mc; + return callbackMappings; } /** diff --git a/src/main/resources/org/datanucleus/store/rdbms/Localisation.properties b/src/main/resources/org/datanucleus/store/rdbms/Localisation.properties index 53720974e..76e90008c 100644 --- a/src/main/resources/org/datanucleus/store/rdbms/Localisation.properties +++ b/src/main/resources/org/datanucleus/store/rdbms/Localisation.properties @@ -319,7 +319,7 @@ 052219=Fetch of object with id "{0}" using statement "{1}" failed : {2} 052220=Search for object with id "{0}" using statement "{1}" failed : {2} 052221=A fetch request has a main table with primary key with {0} columns, yet the passed field which will join to it has {1} columns! Please report this as a DataNucleus bug! -052222=Insert of object "{0}" is calling insertPostProcessing for field "{1}" +052222=Insert/Update of object "{0}" is calling setPostProcessing for field "{1}" 052223=Locate of objects "{0}", performing SELECT on table "{1}" # diff --git a/src/main/resources/org/datanucleus/store/rdbms/Localisation_es.properties b/src/main/resources/org/datanucleus/store/rdbms/Localisation_es.properties index 5551eb116..c7741522e 100644 --- a/src/main/resources/org/datanucleus/store/rdbms/Localisation_es.properties +++ b/src/main/resources/org/datanucleus/store/rdbms/Localisation_es.properties @@ -306,7 +306,7 @@ 052219=Lee del objeto con identidad "{0}" con SQL "{1}" ha tirado un error : {2} 052220=Buscar del objeto con identidad "{0}" con SQL "{1}" ha tirado un error : {2} 052221=Una pedida de obtener datos de una tabla con llave primaria con {0} columnas, pero el campo con que necesita juntar tiene {1} columnas! Por favor, informanos por el Forum de DataNucleus! -052222=Persistencia del objeto "{0}" va a llamar insertPostProcessing para el campo "{1}" +052222=Persistencia del objeto "{0}" va a llamar setPostProcessing para el campo "{1}" 052223=Ubicacion de los objetos "{0}" va a hacer un SELECT en la tabla "{1}" #