[FrontPage] [TitleIndex] [WordIndex

Configuration of a Transactional WFS

If you like to enable transactions with your WFS, you have to adapt the configuration of your featuretypes.

1. Requirements

2. Configuration

2.1. Enabling a non-transactional WFS to be transactional

Per default a deegree2 WFS is non-transactional. You can enable it if you set the transaction attributes to true:

<deegreewfs:transaction update="true" delete="true" insert="true"/>

3. Defining WFS-T feature equality / what the heck are these 'deegreewfs:!IdentityPart' elements?

Deegree offers a mechanism to prevent the insertion of multiple instances of equal features, i.e. a possibility to use property-equivalence additional to gml:id-equivalence as a means of deciding if a new feature has to be inserted (or is just an instance of a stored feature).

3.1. Facts

3.2. Example

Consider the following example. It is assumed that our WFS-T allready contains the following feature.

<Employee gml:id="EMP_01">
  <name>Jon Arbuckle</name>
  <position>Manager</position>
  <inRoom>
    <Room gml:id="ROOM_01">
      <number>313</number>
      <numberOfDesks>5</numberOfDesks>
    </Room>
  </inRoom>
</Employee>

Now, a new employee joins the company, this means following Insert is to be performed (notice the equality of the room numbers):

NOTE: no gml:id is given, because the insert opertation uses idgen="generateNew".

<Employee>
  <name>Garfield</name>
  <position>Manager's pet</position>
  <inRoom>
    <Room>
      <number>313</number>
    <Room>
  </inRoom>
</Employee>

After this insert it is expected that only the new employee is inserted and the room (because of the equality of the room number) is only present once. A GetFeature request to this WFS will have following result:

NOTE, the <inRoom> property of the Garfield feature holds an xlink:href to gml:id of the contents of the <inRoom> property of the 'John Arbuckle' feature.

<Employee gml:id="EMP_01">
  <name>Jon Arbuckle</name>
  <position>Manager</position>
  <inRoom>
    <Room gml:id="ROOM_01">
      <number>313</number>
      <numberOfDesks>5</numberOfDesks>
    </Room>
  </inRoom>
</Employee>
<Employee gml:id="EMP_02">
  <name>Garfield</name>
  <position>Manager's pet</position>
  <inRoom xlink:href="ROOM_01"/>
</Employee>

So we managed to store the "Garfield" feature without storing the <Room> feature twice. Hence we identified the already stored <Room> feature by means of the <number> property instead of the gml:id attribute of the <Room> feature.

Here's the corresponding annotated schema. Notice the "deegreewfs:IdentityPart" elements.

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:deegreewfs="http://www.deegree.org/wfs" xmlns:dgjdbc="http://www.deegree.org/jdbc" xmlns:app="http://www.deegree.org/app" targetNamespace="http://www.deegree.org/app" elementFormDefault="qualified" attributeFormDefault="unqualified">
  <xsd:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/feature.xsd"/>
  <xsd:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/3.1.1/base/geometryAggregates.xsd"/>
  <!-- configuration of the persistence backend to be used -->
  <xsd:annotation>
    <xsd:appinfo>
      ...
      </xsd:appinfo>
  </xsd:annotation>
  <!-- ====================================================================== -->
  <xsd:element name="Employee" type="app:EmployeeType" substitutionGroup="gml:_Feature">
    <xsd:annotation>
      <xsd:appinfo>
        <deegreewfs:table>EMPLOYEE</deegreewfs:table>
        <deegreewfs:gmlId prefix="EMP_">
          <deegreewfs:MappingField field="ID" type="INTEGER"/>
          <deegreewfs:IdGenerator type="DB_SEQ">
            <deegreewfs:param name="sequence">FID_seq</deegreewfs:param>
          </deegreewfs:IdGenerator>
          <deegreewfs:IdentityPart>true</deegreewfs:IdentityPart>
        </deegreewfs:gmlId>
        <deegreewfs:visible>true</deegreewfs:visible>
        <deegreewfs:transaction update="true" delete="true" insert="true"/>
      </xsd:appinfo>
    </xsd:annotation>
  </xsd:element>
  <!-- ====================================================================== -->
  <xsd:complexType name="EmployeeType">
    <xsd:complexContent>
      <xsd:extension base="gml:AbstractFeatureType">
        <xsd:sequence>
          <!-- simple (string) valued property 'name' -->
          <xsd:element name="name" type="xsd:string">
            <xsd:annotation>
              <xsd:appinfo>
                <deegreewfs:IdentityPart>false</deegreewfs:IdentityPart>
                <deegreewfs:Content>
                  <deegreewfs:MappingField field="NAME" type="VARCHAR"/>
                </deegreewfs:Content>
              </xsd:appinfo>
            </xsd:annotation>
          </xsd:element>
          <!-- simple (string) valued property 'position' -->
          <xsd:element name="position" type="xsd:string">
            <xsd:annotation>
              <xsd:appinfo>
                <deegreewfs:IdentityPart>false</deegreewfs:IdentityPart>
                <deegreewfs:Content>
                  <deegreewfs:MappingField field="POSITION" type="VARCHAR"/>
                </deegreewfs:Content>
              </xsd:appinfo>
            </xsd:annotation>
          </xsd:element>
          <!-- complex valued property 'inRoom' -->
          <xsd:element name="inRoom" type="gml:FeaturePropertyType">
            <xsd:annotation>
              <xsd:appinfo>
                <deegreewfs:IdentityPart>false</deegreewfs:IdentityPart>
                <deegreewfs:Content type="app:Room">
                  <deegreewfs:Relation>
                    <deegreewfs:From fk="true">
                      <deegreewfs:MappingField field="IN_ROOM" type="INTEGER"/>
                    </deegreewfs:From>
                    <deegreewfs:To>
                      <deegreewfs:MappingField field="ID" type="INTEGER"/>
                    </deegreewfs:To>
                  </deegreewfs:Relation>
                </deegreewfs:Content>
              </xsd:appinfo>
            </xsd:annotation>
          </xsd:element>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <!-- ====================================================================== -->
  <xsd:element name="Room" type="app:RoomType" substitutionGroup="gml:_Feature">
    <xsd:annotation>
      <xsd:appinfo>
        <deegreewfs:table>ROOM</deegreewfs:table>
        <deegreewfs:gmlId prefix="ROOM_">
          <deegreewfs:MappingField field="ID" type="INTEGER"/>
          <deegreewfs:IdGenerator type="DB_SEQ">
            <deegreewfs:param name="sequence">FID_seq</deegreewfs:param>
          </deegreewfs:IdGenerator>
          <deegreewfs:IdentityPart>false</deegreewfs:IdentityPart>
        </deegreewfs:gmlId>
        <deegreewfs:visible>true</deegreewfs:visible>
        <deegreewfs:transaction update="true" delete="true" insert="true"/>
      </xsd:appinfo>
    </xsd:annotation>
  </xsd:element>
  <!-- ====================================================================== -->
  <xsd:complexType name="RoomType">
    <xsd:complexContent>
      <xsd:extension base="gml:AbstractFeatureType">
        <xsd:sequence>
          <!-- simple (string) valued property 'name' -->
          <xsd:element name="number" type="xsd:string">
            <xsd:annotation>
              <xsd:appinfo>
                <deegreewfs:IdentityPart>true</deegreewfs:IdentityPart>
                <deegreewfs:Content>
                  <deegreewfs:MappingField field="NUMBER" type="VARCHAR"/>
                </deegreewfs:Content>
              </xsd:appinfo>
            </xsd:annotation>
          </xsd:element>
          <!-- simple (integer) valued property 'numberOfDesks' -->
          <xsd:element name="numberOfDesks" type="xsd:integer">
            <xsd:annotation>
              <xsd:appinfo>
                <deegreewfs:IdentityPart>false</deegreewfs:IdentityPart>
                <deegreewfs:Content>
                  <deegreewfs:MappingField field="NUMBER_OF_DESKS" type="INTEGER"/>
                </deegreewfs:Content>
              </xsd:appinfo>
            </xsd:annotation>
          </xsd:element>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
  <!-- ====================================================================== -->
</xsd:schema>

3.3. How are the deegreewfs:IdentityPart elements used?

You can use deegreewfs:IdentityPart inside deegreewfs:gmlId-elements and in the annotation of of property elements:

<deegreewfs:gmlId prefix="EMP_">
  <deegreewfs:MappingField field="ID" type="INTEGER"/>
  <deegreewfs:IdGenerator type="DB_SEQ">
    <deegreewfs:param name="sequence">FID_seq</deegreewfs:param>
  </deegreewfs:IdGenerator>
  <deegreewfs:IdentityPart>true</deegreewfs:IdentityPart>
</deegreewfs:gmlId>

<xsd:element name="name" type="xsd:string">
  <xsd:annotation>
    <xsd:appinfo>
      <deegreewfs:IdentityPart>false</deegreewfs:IdentityPart>
      <deegreewfs:Content>
        <deegreewfs:MappingField field="NAME" type="VARCHAR"/>
      </deegreewfs:Content>
    </xsd:appinfo>
  </xsd:annotation>
</xsd:element>

4. Set foreign key information

Some best practices and heuristics to set the foreign key attributes in WFS schema documents. This is only necessary for transactional WFS.

4.1. Why foreign key information is needed

4.2. How to set the foreign key information


CategoryDeegree2


2018-04-20 12:04