3. Usage
Prev | Chapter 13. Slice: Distributed Persistence | Next

## 3. Usage

Slice is activated via the following property settings:

### 3.1. How to activate Slice Runtime?

The basic configuration property is

             <property name="openjpa.BrokerFactory" value="slice"/>

This critical configuration activates a specialized object management kernel that can work against multiple databases.

### 3.2. How to configure each database slice?

Each database slice is identified by a logical name unique within a persistent unit. The list of the slices is specified by `openjpa.slice.Names` property. For example, specify three slices named `"One"`, `"Two"` and `"Three"` as follows:

           <property name="openjpa.slice.Names" value="One, Two, Three"/>

This property is not mandatory. If this property is not specified then the configuration is scanned for logical slice names. Any property `"abc"` of the form `openjpa.slice.XYZ.abc` will register a slice with logical name `"XYZ"`.

The order of the names is significant when no `openjpa.slice.Master` property is not specified. The persistence unit is then scanned to find all configured slice names and they are ordered alphabetically.

Each database slice properties can be configured independently. For example, the following configuration will register two slices with logical name `One` and `Two`.

            <property name="openjpa.slice.One.ConnectionURL" value="jdbc:mysql:localhost//slice1"/>
            <property name="openjpa.slice.Two.ConnectionURL" value="jdbc:mysql:localhost//slice2"/>

Any OpenJPA specific property can be configured per slice basis. For example, the following configuration will use two different JDBC drivers for slice `One` and `Two`.

            <property name="openjpa.slice.One.ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
            <property name="openjpa.slice.Two.ConnectionDriverName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/>

Any property if unspecified for a particular slice will be defaulted by corresponding OpenJPA property. For example, consider following three slices

             <property name="openjpa.slice.One.ConnectionURL"          value="jdbc:mysql:localhost//slice1"/>
             <property name="openjpa.slice.Two.ConnectionURL"          value="jdbc:mysql:localhost//slice2"/>
             <property name="openjpa.slice.Three.ConnectionURL"        value="jdbc:oracle:localhost//slice3"/>

             <property name="openjpa.ConnectionDriverName"     value="com.mysql.jdbc.Driver"/>
             <property name="openjpa.slice.Three.ConnectionDriverName" value="oracle.jdbc.Driver"/>

In this example, `Three` will use slice-specific `oracle.jdbc.Driver` driver while slice `One` and `Two` will use the driver `com.mysql.jdbc.Driver` as specified by `openjpa.ConnectionDriverName` property value.

A connection pool may also be used with Slice by using the `openjpa.ConnectionProperties` property. For example to use commons-dbcp with Derby you might use the following properties :

                    <property name="openjpa.BrokerFactory" value="slice"/>
                    <property name="openjpa.ConnectionDriverName" value="org.apache.commons.dbcp.BasicDataSource"/>
                    <property name="openjpa.slice.Names" value="One,Two"/>
                    <property name="openjpa.slice.Master" value="Two"/>

                    <property name="openjpa.slice.One.ConnectionProperties" value="Url=jdbc:derby:target/database/openjpa-slice1;create=true, DriverClassName=org.apache.derby.jdbc.EmbeddedDriver"/>
                    <property name="openjpa.slice.Two.ConnectionProperties" value="Url=jdbc:derby:target/database/openjpa-slice2;create=true, DriverClassName=org.apache.derby.jdbc.EmbeddedDriver"/>

                    <property name="openjpa.jdbc.DBDictionary" value="derby"/>

### Note

Be aware that you need to set the DBDictionary when using commons-dbcp.

### 3.3. Implement DistributionPolicy interface

Slice needs to determine which slice will persist a new instance. The application can only decide this policy (for example, all PurchaseOrders before April 30 goes to slice `One`, all the rest goes to slice `Two`). This is why the application has to implement `org.apache.openjpa.slice.DistributionPolicy` and specify the implementation class in configuration

              <property name="openjpa.slice.DistributionPolicy" value="com.acme.foo.MyOptimialDistributionPolicy"/>

The interface `org.apache.openjpa.slice.DistributionPolicy` is simple with a single method. The complete listing of the documented interface follows:

    public interface DistributionPolicy {
        /**
         * Gets the name of the slice where a given instance will be stored.
         *
         * @param pc The newly persistent or to-be-merged object.
         * @param slices name of the configured slices.
         * @param context persistence context managing the given instance.
         *
         * @return identifier of the slice. This name must match one of the
         * configured slice names.
         * @see DistributedConfiguration#getSliceNames()
         */
        String distribute(Object pc, List<String> slices, Object context);
    }

While implementing a distribution policy the most important thing to remember is collocation constraint. Because Slice can not establish or query any cross-database relationship, all the related instances must be stored in the same database slice. Slice can determine the closure of a root object by traversal of cascaded relationships. Hence user-defined policy has to only decide the database for the root instance that is the explicit argument to `EntityManager.persist()` call. Slice will ensure that all other related instances that get persisted by cascade are assigned to the same database slice as that of the root instance. However, the user-defined distribution policy must return the same slice identifier for the instances that are logically related but not cascaded for persist.

### 3.4. Implement ReplicationPolicy interface

The entities that are enumerated in `openjpa.slice.ReplicatedTypes` property can be stored in multiple slices as identical copies. Specify the implementation class of `ReplicationPolicy` in configuration as

              <property name="openjpa.slice.ReplicationPolicy" value="com.acme.foo.MyReplicationPolicy"/>

Prev | Up | Next
2. Salient Features | Home | 4. Configuration Properties