Hi,
while working on the GeoServer synchronisation problem
I stumbled into what seems a serious limitation of the
Geotools datastore design.

In particular I need to insert features into a database
whose feature id is provided by the user and should be
maintained as-is. In the synch case the fid is a UUID
generated on another node for a newly inserted feature,
and of course to keep the net in synch all nodes must
use the same identity.

For that particular case I worked around the issue in
the versioning data store by leveraging some knowledge
of the internal implementation, by knowing that the
feature returned from the writer is a MutableFIDFeature
one [1]

That is old JDBC code, and internally the custom UUID FID
mapper first tries to unpack the primary key, checking
if it's a valid UUID, if so it reuses the value,
otherwise it generates a new one.

Just today I stumbled into a user having the same need against
the new JDBC data stores.
I'm wondering if/how we can generalize a bit more this behavior,
also under the consideration that the WFS standard itself
allows the primary keys to be both generated or assigned
in transactions [2]

Of course one way is to replicate sort of the same trick
for JDBCFeatureStore, leveraging the knowledge of the
feature returned by the writer to stick a FID into it,
and then change JDBCDataStore.getNextValue() so that it
also takes the current Feature and tries to unpack the
primary key instead of blindly trying to generate a new
value.
This would also be an acceptable solution to me btw,
and I guess it would cover 90% of what is needed:
shapefile datastore cannot accept user provided pks,
the only other one I can think of that would need
to use assigned values is probably the WFS data store
one (and maybe the SDE one? not sure).

Opinions?

Cheers
Andrea


[1] -----------------------------------------------------

     public List<FeatureId> addFeatures(
             FeatureCollection<SimpleFeatureType, SimpleFeature> 
collection) throws IOException {
         List<FeatureId> addedFids = new LinkedList<FeatureId>();
         String typeName = getSchema().getTypeName();
         SimpleFeature feature = null;
         SimpleFeature newFeature;
         FeatureWriter<SimpleFeatureType, SimpleFeature> writer = 
getDataStore()
                 .getFeatureWriterAppend(typeName, getTransaction());

         Iterator iterator = collection.iterator();
         try {

             while (iterator.hasNext()) {
                 feature = (SimpleFeature) iterator.next();
                 newFeature = (SimpleFeature) writer.next();
                 try {
                     newFeature.setAttributes(feature.getAttributes());
                 } catch (Exception writeProblem) {
                     throw new DataSourceException("Could not create " + 
typeName
                             + " out of provided feature: " + 
feature.getID(), writeProblem);
                 }

                 // preserve the FID, it could come from another node
                 ((MutableFIDFeature) newFeature).setID(feature.getID());

                 writer.write();
                 addedFids.add(newFeature.getIdentifier());
             }
         } finally {
             collection.close(iterator);
             writer.close();
         }
         return addedFids;
     }


[2] -----------------------------------------------------

    <xsd:simpleType name="IdentifierGenerationOptionType">
       <xsd:restriction base="xsd:string">
          <xsd:enumeration value="UseExisting">
             <xsd:annotation>
                <xsd:documentation>
                   The UseExsiting value indicates that WFS should not
                   generate a new feature identifier for the feature
                   being inserted into the repositry.  Instead, the WFS
                   should use the identifier encoded if the feature.
                   If a duplicate exists then the WFS should raise an
                   exception.
                </xsd:documentation>
             </xsd:annotation>
          </xsd:enumeration>
          <xsd:enumeration value="ReplaceDuplicate">
             <xsd:annotation>
                <xsd:documentation>
                   The ReplaceDuplicate value indicates that WFS should
                   not generate a new feature identifier for the feature
                   being inserted into the repositry.  Instead, the WFS
                   should use the identifier encoded if the feature.
                   If a duplicate exists then the WFS should replace the
                   existing feature instance with the one encoded in the
                   Insert action.
                </xsd:documentation>
             </xsd:annotation>
          </xsd:enumeration>
          <xsd:enumeration value="GenerateNew">
             <xsd:annotation>
                <xsd:documentation>
                   The GenerateNew value indicates that WFS should
                   generate a new unique feature identifier for the
                   feature being inserted into the repositry.
                </xsd:documentation>
             </xsd:annotation>
          </xsd:enumeration>
       </xsd:restriction>
    </xsd:simpleType>


-- 
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.

------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Geotools-devel mailing list
Geotools-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geotools-devel

Reply via email to