Storing Objects in the Directory
Referenceable Objects and References
You can think of the serialized state of an object as a copy of the object in a different representation. Sometimes it is not appropriate to store that representation in the directory. This is because the serialized state might be too large or it might be inadequate for your needs (the application, for example, might need more information than can be supplied by the serialized form). Or, you might need the object in a different form.For reasons such as these, the JNDI defines a reference for use when (the serialized form of) an object cannot be stored in the directory directly. You store an object with an associated reference in the directory indirectly by storing its reference. It might be useful to think of the distinction between a serialized object and a JNDI reference as that between a copy of a Java object and a Java object reference.
What's in a Reference? A reference is represented by the class Reference. A Reference consists of an ordered list of addresses and class information about the object being referenced. Each address is represented by a subclass of RefAddr and contains information on how to construct the object.
References are commonly used to represent connections to a network service such as a database, directory, or file system. Each address may then identify for that service a communication endpoint that contains information on how to contact the service. Multiple addresses might arise for various reasons, such as the need for replication or multiple access points (that is, the object offers interfaces over more than one communication mechanism).
A reference also contains information to assist in creating an instance of the object to which the reference refers. It contains the Java class name of that object, as well as the class name and location of the object factory to be used to create the object.
Referenceable Objects An object whose class implements the Referenceable interface has an associated reference. The Referenceable interface has one method, getReference(), which returns the reference of the object.
The following example shows a Fruit class that implements the Referenceable interface.
The reference of a Fruit instance consists of a single address (of class StringRefAddr). This address contains the fruit type with which the instance was created. For example, if the instance was created using new Fruit("orange"), then its address type would be "fruit" and its address contents "orange". The reference contains two additional pieces of information: the fully qualified name of the Fruit class (in this case, simply "Fruit") and the fully qualified name of the object factory class that can be used to create instances of Fruit (in this case, "FruitFactory"). Object factories are described in the Object Factories lesson.public class Fruit implements Referenceable { String fruit; public Fruit(String f) { fruit = f; } public Reference getReference() throws NamingException { return new Reference( Fruit.class.getName(), new StringRefAddr("fruit", fruit), FruitFactory.class.getName(), null); // Factory location } public String toString() { return fruit; } }
Binding a Referenceable Object You might remember the Fruit class from the Adding a Binding That Has Attributes example. The following example is a simplification of that example.
After creating an instance of Fruit, you invoke Context.bind(), DirContext.bind(), Context.rebind(), or DirContext.rebind() to add it to the directory.
The service provider implementation of bind()/rebind() first extracts the reference from the object being bound (by using Referenceable.getReference()) and then stores that reference in the directory. When that object is subsequently looked up from the directory, its corresponding object factory will convert the reference into an instance of the object (conversion details are described in the Object Factories lesson).// Create the object to be bound Fruit fruit = new Fruit("orange"); ... // Perform bind ctx.bind("cn=favorite", fruit);This produces the following output, "orange", produced by Fruit.toString().// Read the object back Fruit f2 = (Fruit) ctx.lookup("cn=favorite"); System.out.println(f2);# java RefObj orangeFrom the perspective of the application using the JNDI, it is dealing only with bind() and lookup(). The service provider takes care of getting the reference from the object and converting it to/from the actual object itself.
Note that you can store a Referenceable object in the directory only if the underlying service provider supports it. Sun's LDAP service provider supports storing both References and Referenceable objects.
Binding a Reference Binding a Referenceable object is more elegant than binding a Reference directly. This is because you can simply bind the object instead of first getting its reference. However, you can also bind a Reference directly. See the Remote Objects section for an example of binding a Reference.
Storing Objects in the Directory