|
Berkeley DB Java Edition version 3.0.12 |
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectcom.sleepycat.persist.raw.RawStore
com.sleepycat.persist.evolve.ConversionStore
public class ConversionStore
Provides access to incompatible raw data in a store for performing manual
conversions. When opening a conversion store, mutations need not be
configured for handling class incompatibilities and IncompatibleClassException
will not be thrown.
Manual conversions are needed when Mutations
are insufficient for
making complex changes to a class hierarchy or entity model. When using an
conversion store, an entity may be read even if its stored class definition
is incompatible with the current class definition or if the old class is no
longer present. Entities may be arbitrarily manipulated, converted to be
compatible with current class definitions, and written back to the
store.
Note that entities with incompatible classes may be read but not written. Entities written must always conform to the current class definitions.
After a conversion, in order to open the store as an EntityStore
or RawStore
without causing an IncompatibleClassException
,
the deleteUnusedType
method should be called for
every incompatible class. This method should be called after converting or
deleting all instances of the incompatible class.
The deleteUnusedType
method does not verify
that no instances of the given type exist, since that would require
traversing one or more primary indices. Instead, the caller is required to
have traversed all applicable indices and converted all instance of the
type. If an instance of the type still exists and is later accessed via an
EntityStore
or RawStore
, a DeletedClassException
will be thrown.
A entity store does not keep track of how many instances exist for a
given version of a class. The only way to find old versions is to iterate
through all primary indices that may contain incompatible classes and check
the types and versions. The type of a stored object is returned by RawObject.getType()
; this will either be equal to the current type (returned
by EntityModel.getRawType
) or the previously
stored type (returned by EntityModel.getAllRawTypes
). Types may be compared using the
equals
method, or the version number may be checked.
Using a Temporary Index
Conversion via a temporary index is required for performing a key conversion, since key formats may not be changed. It may also be used to avoid making a backup of the environment before performing a conversion, since the original index is not changed until the temporary index is installed, and the temporary index may be installed safely using a transaction.
For example:
// The class name and version of the entity instances to be converted.
//
String className = ...;
int classVersion = ...;
// Open the conversion store, the current index and a temporary index.
//
Environment env = ...;
ConversionStore store = new ConversionStore(env, "myStore", null);
PrimaryIndex<Object,RawObject> oldIndex = store.getPrimaryIndex(className);
PrimaryIndex<Object,RawObject> tempIndex = store.getTempIndex(className);
// Copy the instances from oldIndex to tempIndex, converting all instances
// to conform to current class definitions. (See Converter
for
// examples of conversion techniques.)
//
...
// Using a single transaction, atomically install the new index and delete
// the (now unused) type of the old instances.
//
Transaction txn = env.beginTransaction(null, null);
store.installTempIndex(txn, tempIndex);
store.deleteUnusedType(txn, className, classVersion);
txn.commit();
Using this approach, complex conversions can be performed using any number of indices at once, and a single transaction can be used to atomically commit the changes.
Note that an entire index conversion could be performed in a single transaction. However, for large indices this would use unacceptable amounts of memory to hold transactional locks. Therefore, the recommended approach for converting a large index is to copy it to a temporary index, without transactions, and then use a transaction to install the index and delete the unused types.
Constructor Summary | |
---|---|
ConversionStore(Environment env,
String storeName,
StoreConfig config)
Opens an entity store for unchecked raw data access. |
Method Summary | |
---|---|
PrimaryIndex<Object,RawObject> |
createTempIndex(String entityClass)
Opens a new temporary primary index for copying new data to a new index rather than updating an index in place. |
void |
deleteUnusedType(Transaction txn,
String className,
int classVersion)
Removes a type for which all instances have been converted. |
void |
installTempIndex(Transaction txn,
PrimaryIndex<Object,RawObject> tempIndex)
Installs a temporary primary index as the current index. |
Methods inherited from class com.sleepycat.persist.raw.RawStore |
---|
close, getConfig, getEnvironment, getModel, getMutations, getPrimaryIndex, getSecondaryIndex, getStoreName |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Constructor Detail |
---|
public ConversionStore(Environment env, String storeName, StoreConfig config) throws DatabaseException
env
- an open Berkeley DB environment.storeName
- the name of the entity store within the given
environment.config
- the store configuration, or null to use default
configuration properties.
IllegalArgumentException
- if the Environment
is
read-only or the config ReadOnly
property is true.
DatabaseException
Method Detail |
---|
public PrimaryIndex<Object,RawObject> createTempIndex(String entityClass) throws DatabaseException
Entities may be copied from the current primary index to the
temporary primary index, changing the key format in the process if
desired. When conversion is completed successfully, installTempIndex(com.sleepycat.je.Transaction, com.sleepycat.persist.PrimaryIndex
should be called. If this conversion store is closed
without calling installTempIndex(com.sleepycat.je.Transaction, com.sleepycat.persist.PrimaryIndex
, the temporary index will be
deleted. If a conversion store is opened and any residual temporary
indices exist, they will be deleted.
Conversion via a temporary index is required for performing a key conversion, since key formats may not be changed. It may also be used to avoid making a backup of the environment before performing a conversion, since the original index is not changed until the temporary index is installed, and the temporary index may be installed safely using a transaction.
DatabaseException
public void installTempIndex(Transaction txn, PrimaryIndex<Object,RawObject> tempIndex) throws DatabaseException
DatabaseException
public void deleteUnusedType(Transaction txn, String className, int classVersion)
When performing a conversion, instances of an incompatible class
version may be converted to a different type or deleted entirely. This
method is called to inform the store that such a type has no instances
and no longer requires conversion. In addition to freeing the space
taken by the unused type definition, deleting an incompatible type
allows opening an EntityStore
(or RawStore
) without
causing an IncompatibleClassException
.
This method does not verify that no instances of the given type
exist, since that would require traversing one or more primary indices.
Instead, the caller is required to have traversed all applicable indices
and converted all instance of the type. If an instance of the type
still exists and is later accessed via an EntityStore
or RawStore
, a DeletedClassException
will be thrown.
|
Berkeley DB Java Edition version 3.0.12 |
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |