Creating Entity Bindings

Entity bindings are similar to ordinary bindings in that they convert between Java objects and the stored data format of keys and values. In addition, entity bindings map between key/value pairs and entity objects. An ordinary binding is a one-to-one mapping, while an entity binding is a two-to-one mapping.

The partDataBinding, supplierDataBinding and shipmentDataBinding bindings are created below as entity bindings rather than (in the prior examples) serial bindings.

import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.ClassCatalog;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.serial.SerialSerialBinding;
...

public class SampleViews
{
    ...
    public SampleViews(SampleDatabase db)
    {
        ClassCatalog catalog = db.getClassCatalog();
        SerialBinding partKeyBinding =
            new SerialBinding(catalog, PartKey.class);
        EntityBinding partDataBinding =
            new PartBinding(catalog, PartKey.class, PartData.class);
        SerialBinding supplierKeyBinding =
            new SerialBinding(catalog, SupplierKey.class);
        EntityBinding supplierDataBinding =
            new SupplierBinding(catalog, SupplierKey.class,
                                SupplierData.class);
        SerialBinding shipmentKeyBinding =
            new SerialBinding(catalog, ShipmentKey.class);
        EntityBinding shipmentDataBinding =
            new ShipmentBinding(catalog, ShipmentKey.class,
                                ShipmentData.class);
        SerialBinding cityKeyBinding =
            new SerialBinding(catalog, String.class);
        ...
    }
} 

The entity bindings will be used in the next section to construct stored map objects.

The PartBinding class is defined below.

public class SampleViews
{
    ...
    private static class PartBinding extends SerialSerialBinding {
        private PartBinding(ClassCatalog classCatalog,
                            Class keyClass,
                            Class dataClass)
        {
            super(classCatalog, keyClass, dataClass);
        }

        public Object entryToObject(Object keyInput, Object dataInput)
        {
            PartKey key = (PartKey) keyInput;
            PartData data = (PartData) dataInput;
            return new Part(key.getNumber(), data.getName(),
                            data.getColor(), data.getWeight(), 
                            data.getCity());
        }

        public Object objectToKey(Object object)
        {
            Part part = (Part) object;
            return new PartKey(part.getNumber());
        }

        public Object objectToData(Object object)
        {
            Part part = (Part) object;
            return new PartData(part.getName(), part.getColor(),
                                part.getWeight(), part.getCity());
        }
    }
    ...
} 

In general, an entity binding is any class that implements the EntityBinding interface, just as an ordinary binding is any class that implements the EntryBinding interface. In the prior examples the built-in SerialBinding class (which implements EntryBinding) was used and no application-defined binding classes were needed.

In this example, application-defined binding classes are used that extend the SerialSerialBinding abstract base class. This base class implements EntityBinding and provides the conversions between key/value bytes and key/value objects, just as the SerialBinding class does. The application-defined entity class implements the abstract methods defined in the base class that map between key/value objects and entity objects.

Three abstract methods are implemented for each entity binding. The entryToObject() method takes as input the key and data objects, which have been deserialized automatically by the base class. As output, it returns the combined Part entity.

The objectToKey() and objectToData() methods take an entity object as input. As output they return the part key or data object that is extracted from the entity object. The key or data will then be serialized automatically by the base class.

The SupplierBinding and ShipmentBinding classes are very similar to the PartBinding class.

public class SampleViews
{
    ...
    private static class SupplierBinding extends SerialSerialBinding {
        private SupplierBinding(ClassCatalog classCatalog,
                                Class keyClass,
                                Class dataClass)
        {
            super(classCatalog, keyClass, dataClass);
        }

        public Object entryToObject(Object keyInput, Object dataInput)
        {
            SupplierKey key = (SupplierKey) keyInput;
            SupplierData data = (SupplierData) dataInput;
            return new Supplier(key.getNumber(), data.getName(),
                                data.getStatus(), data.getCity());
        }

        public Object objectToKey(Object object)
        {
            Supplier supplier = (Supplier) object;
            return new SupplierKey(supplier.getNumber());
        }

        public Object objectToData(Object object)
        {
            Supplier supplier = (Supplier) object;
            return new SupplierData(supplier.getName(),
                                    supplier.getStatus(), 
                                    supplier.getCity());
        }
    }

    private static class ShipmentBinding extends SerialSerialBinding {
        private ShipmentBinding(ClassCatalog classCatalog,
                                Class keyClass,
                                Class dataClass)
        {
            super(classCatalog, keyClass, dataClass);
        }

        public Object entryToObject(Object keyInput, Object dataInput)
        {
            ShipmentKey key = (ShipmentKey) keyInput;
            ShipmentData data = (ShipmentData) dataInput;
            return new Shipment(key.getPartNumber(), 
                                key.getSupplierNumber(),
                                data.getQuantity());
        }

        public Object objectToKey(Object object)
        {
            Shipment shipment = (Shipment) object;
            return new ShipmentKey(shipment.getPartNumber(),
                                   shipment.getSupplierNumber());
        }

        public Object objectToData(Object object)
        {
            Shipment shipment = (Shipment) object;
            return new ShipmentData(shipment.getQuantity());
        }
    }
    ...
}