Managing Containers

Container Properties
Container Types
Deleting and Renaming Containers

In BDB XML you store your XML Documents in containers. A container is a file on disk that contains all the data associated with your documents, including metadata and indices.

To create and open a container, you use XmlManager.createContainer(). Once a container has been created, you can not use createContainer() on it again. Instead, simply open it using: XmlManager.openContainer().

Note that you can test for the existence of a container using the XmlManager.existsContainer() method. This method should be used on closed containers. It returns 0 if the named file is not a BDB XML container. Otherwise, it returns the underlying database format number.

Alternatively, you can cause a container to be created and opened by calling openContainer() and pass it the necessary properties to allow the container to be created (see the following section for information on container open properties).

You can open a container multiple times. Each time you open a container, you receive a reference-counted handle for that container.

You close a container by calling XmlContainer.close(). Note that the container is not actually closed until the last handle for the container has been closed.

For example:

package dbxml.gettingStarted;

import com.sleepycat.dbxml.XmlContainer;
import com.sleepycat.dbxml.XmlException;
import com.sleepycat.dbxml.XmlManager;

...

XmlManager myManager = null;
XmlContainer myContainer = null;
XmlContainer myContainer2 = null;
try {
    myManager = new XmlManager();

    // Open the container. If it does not currently exist, 
    // then create it.
    myContainer = 
        myManager.createContainer("/export/xml/myContainer.bdbxml");

    // Obtain a second handle to the container. This container is closed
    // when its last handle is closed.
    myContainer2 = 
        myManager.openContainer("/export/xml/myContainer.bdbxml");
    
} catch (XmlException e) {
    // Exception handling goes here
} finally {
    try {
        if (myContainer != null) {
            myContainer.close();
        }

        if (myContainer2 != null) {
            myContainer2.close();
        }

        if (myManager != null) {
            myManager.close();
        }
    } catch (XmlException ce) {
        // Exception handling goes here
    }
} 

Container Properties

When you create or open a container, there are a large number of properties that you can specify which control various aspects of the container's behavior. The following are the properties commonly used by BDB XML applications. For a complete listing of the properties available for use, see the Javadoc.

  • XmlContainerConfig.setAllowCreate()

    Causes the container and all underlying databases to be created. It is not necessary to specify this property on the call to XmlManager.createContainer(). In addition, you need to specify it for XmlManager.openContainer(). only if the container has not already been created.

  • XmlContainer.setExclusiveCreate()

    Causes the container creation to fail if the container already exists. It is not necessary to specify this property on the call to XmlManager.createContainer(). Note that this property is meaningless unless XmlContainerConfig.setAllowCreate() is also used.

  • XmlContainerConfig.setReadOnly()

    The container is opened for read-access only.

  • XmlContainerConfig.setAllowValidation()

    Causes documents to be validated when they are loaded into the container. The default behavior is to not validate documents.

  • XmlContainerConfig.setIndexNodes()

    Determines whether indexes for the container will return nodes (if this property is set to On) or documents (if this property is set to Off).

    Note that the default index type is determined by the type of container you are creating. If you are creating a container of type NodeContainer, then this property is set to On by default. For containers of type WholedocContainer, this property is set to Off by default.

    If you want to change this property on an existing container, you must re-index the container in order for the new index type to take effect.

    For more information on index nodes, see Specifying Index Nodes.

  • XmlContainerConfig.setTransactional()

    The container supports transactions. For more information, see the Berkeley DB XML Getting Started with Transaction Processing guide.

Container Types

At creation time, every container must have a type defined for it. This container type identifies how XML documents are stored in the container. As such, the container type can only be determined at container creation time; you cannot change it on subsequent container opens.

Containers can have one of the following types specified for them:

  • Wholedoc Containers

    The container contains entire documents; the documents are stored "as is" without any manipulation of line breaks or whitespace. To cause the container to hold whole documents, set XmlContainerConfig.setNodeContainer() to false.

  • Node containers

    XmlDocuments are stored as individual nodes in the container. That is, each record in the underlying database contains a single leaf node, its attributes and attribute values if any, and its text nodes, if any. BDB XML also keeps the information it needs to reassemble the document from the individual nodes stored in the underlying databases.

    This is the default, and preferred, container type.

    To cause the documents to be stored as individual nodes, set XmlContainerConfig.setNodeContainer() to true.

  • Default container type.

    The default container type is used. You can set the default container type using XmlManager.setDefaultContainerType(). If you never set a default container type, then the container will use node-level storage.

Note that NodeContainer is generally faster to query than is WholedocContainer. On the other hand, WholedocContainer provides faster document loading times into the container than does NodeContainer because BDB XML does not have to deconstruct the document into its individual leaf nodes. For the same reason, WholedocContainer is faster at retrieving whole documents for the same reason — the document does not have to be reassembled.

Because of this, you should use NodeContainer unless one of the following conditions are true:

  • Load performance is more important to you than is query performance.

  • You want to frequently retrieve the entire XML document (as opposed to just a portion of the document).

  • Your documents are so small in size that the query advantage offered by NodeContainer is negligible or vanishes entirely. The size at which this threshold is reached is of course dependent on the physical resources available to your application (memory, CPU, disk speeds, and so forth).

Note that you should avoid using WholedocContainer if your documents tend to be greater than a megabyte in size. WholedocContainer is tuned for small documents and you will pay increasingly heavy performance penalties as your documents grow larger.

For example:

package dbxml.gettingStarted;

import com.sleepycat.dbxml.XmlContainer;
import com.sleepycat.dbxml.XmlException;
import com.sleepycat.dbxml.XmlManager;

...

XmlManager myManager = null;
XmlContainer myContainer = null;
try {
    myManager = new XmlManager();
    myManager.setDefaultContainerType(XmlContainer.WholedocContainer);

    // Create and open the container.
    myContainer = 
        myManager.createContainer("/export/xml/myContainer.bdbxml");

} catch (XmlException e) {
    // Exception handling goes here
} finally {
    try {
        if (myContainer != null) {
            myContainer.close();
        }

        if (myManager != null) {
            myManager.close();
        }
    } catch (XmlException ce) {
        // Exception handling goes here
    }
} 

Deleting and Renaming Containers

You can delete a container using XmlManager.removeContainer(). It is an error to attempt to remove an open container.

You can rename a container using XmlManager.renameContainer(). It is an error to attempt to rename an open container.

For example:

package dbxml.gettingStarted;

import com.sleepycat.dbxml.XmlException;
import com.sleepycat.dbxml.XmlManager;

...

XmlManager myManager = null;
try {
    myManager = new XmlManager();

    String currentName = "/export/xml/myContainer.bdbxml";
    String newName = "/export2/xml/myContainer.bdbxml";

    myManager.renameContainer(currentName, newName);

    myManager.removeContainer(newName);

} catch (XmlException e) {
    // Exception handling goes here
} finally {
    try {
        if (myManager != null) {
            myManager.close();
        }
    } catch (XmlException ce) {
        // Exception handling goes here
    }
}