LDAP SDK persistence framework part 2: Supported data types

Another very important aspect of the persistence framework being developed for the UnboundID LDAP SDK for Java is the set of data types that it supports. In order to be able to correctly store and retrieve Java objects in a directory server, the LDAP SDK has to now how to encode Java values to LDAP attributes, and then decode the values of those attributes back to their Java representations. The LDAP SDK provides an abstract LDAPFieldEncoder class which defines the API needed to achieve this, as well as other things like generating LDAP attribute type definitions for a particular field or method. The @LDAPField, @LDAPFieldGetter, and @LDAPFieldSetter annotation types all include elements that allow you to specify the type of encoder that should be used when interacting with the associated field or method.

If the encoderClass element isn’t provided in the annotation, then the LDAP SDK will use an instance of the DefaultLDAPFieldEncoder class. This class supports a pretty broad range of data types, including:

  • boolean primitives
  • double primitives
  • float primitives
  • int primitives
  • long primitives
  • short primitives
  • byte[] objects
  • char[] objects
  • java.lang.Boolean objects
  • java.lang.Double objects
  • java.lang.Float objects
  • java.lang.Integer objects
  • java.lang.Long objects
  • java.lang.Short objects
  • java.lang.String objects
  • java.lang.StringBuffer objects
  • java.lang.StringBuilder objects
  • java.math.BigDecimal objects
  • java.math.BigInteger objects
  • java.util.Date objects
  • java.util.UUID objects
  • java.util.concurrent.atomic.AtomicInteger objects
  • java.util.concurrent.atomic.AtomicLong objects
  • com.unboundid.ldap.sdk.DN objects
  • com.unboundid.ldap.sdk.Filter objects
  • com.unboundid.ldap.sdk.LDAPURL objects
  • com.unboundid.ldap.sdk.RDN objects

In addition, it also supports arrays of all of the above types for dealing with multi-valued attributes. In the future, I intend to add add support for using java.util.Lists and java.util.Sets for all of the above types as well, but that’s not in the current implementation, and generics make that a bit tricky.

For most of the above data types, the value stored in the directory server is simply the string representation of the associated primitive or object. However, there are a few special cases:

  • boolean primitives and java.lang.Boolean objects are always stored using values of “TRUE” or “FALSE” (in all uppercase), as per the LDAP Boolean syntax.
  • byte[] objects are used to represent the raw bytes that comprise the attribute value
  • char[] objects are used to represent the raw characters that comprise the attribute value
  • java.util.Date objects are encoded using the LDAP generalized time syntax

Even though the default field encoder supports a number of primitive types (although it doesn’t support either byte or char in order to avoid confusion), I would generally recommend that you use the corresponding objects in the java.lang package instead. The reason for this is that primitives can’t have a null value, so it’s not possible to distinguish between cases in which there is no value and cases where there is a value that happens to be the same as the default value for that primitive (zero for numeric types and false for boolean). If you use the corresponding object types instead, then they can have null values, and you can use that to determine if a value has been assigned.

If you need to store some other kind of object in the directory that isn’t in this list, then you’ll need to create your own subclass of LDAPFieldEncoder with the appropriate logic for encoding and decoding values. If this is necessary, then I’d strongly recommend using DefaultLDAPFieldEncoder as a starting point.