mirror of
https://github.com/berkeleydb/je.git
synced 2024-11-15 09:46:25 +00:00
625 lines
36 KiB
HTML
625 lines
36 KiB
HTML
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||
|
<!-- NewPage -->
|
||
|
<html lang="en">
|
||
|
<head>
|
||
|
<!-- Generated by javadoc (1.8.0_151) on Tue Oct 31 17:36:47 EDT 2017 -->
|
||
|
<title>com.sleepycat.persist.evolve (Oracle - Berkeley DB Java Edition API)</title>
|
||
|
<meta name="date" content="2017-10-31">
|
||
|
<link rel="stylesheet" type="text/css" href="../../../../style.css" title="Style">
|
||
|
<script type="text/javascript" src="../../../../script.js"></script>
|
||
|
</head>
|
||
|
<body>
|
||
|
<script type="text/javascript"><!--
|
||
|
try {
|
||
|
if (location.href.indexOf('is-external=true') == -1) {
|
||
|
parent.document.title="com.sleepycat.persist.evolve (Oracle - Berkeley DB Java Edition API)";
|
||
|
}
|
||
|
}
|
||
|
catch(err) {
|
||
|
}
|
||
|
//-->
|
||
|
</script>
|
||
|
<noscript>
|
||
|
<div>JavaScript is disabled on your browser.</div>
|
||
|
</noscript>
|
||
|
<!-- ========= START OF TOP NAVBAR ======= -->
|
||
|
<div class="topNav"><a name="navbar.top">
|
||
|
<!-- -->
|
||
|
</a>
|
||
|
<div class="skipNav"><a href="#skip.navbar.top" title="Skip navigation links">Skip navigation links</a></div>
|
||
|
<a name="navbar.top.firstrow">
|
||
|
<!-- -->
|
||
|
</a>
|
||
|
<ul class="navList" title="Navigation">
|
||
|
<li><a href="../../../../overview-summary.html">Overview</a></li>
|
||
|
<li class="navBarCell1Rev">Package</li>
|
||
|
<li>Class</li>
|
||
|
<li><a href="package-use.html">Use</a></li>
|
||
|
<li><a href="package-tree.html">Tree</a></li>
|
||
|
<li><a href="../../../../deprecated-list.html">Deprecated</a></li>
|
||
|
<li><a href="../../../../index-all.html">Index</a></li>
|
||
|
<li><a href="../../../../help-doc.html">Help</a></li>
|
||
|
</ul>
|
||
|
<div class="aboutLanguage"><b>Berkeley DB Java Edition</b><br><font size=\"-1\"> version 7.5.11</font>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="subNav">
|
||
|
<ul class="navList">
|
||
|
<li><a href="../../../../com/sleepycat/persist/package-summary.html">Prev Package</a></li>
|
||
|
<li><a href="../../../../com/sleepycat/persist/model/package-summary.html">Next Package</a></li>
|
||
|
</ul>
|
||
|
<ul class="navList">
|
||
|
<li><a href="../../../../index.html?com/sleepycat/persist/evolve/package-summary.html" target="_top">Frames</a></li>
|
||
|
<li><a href="package-summary.html" target="_top">No Frames</a></li>
|
||
|
</ul>
|
||
|
<ul class="navList" id="allclasses_navbar_top">
|
||
|
<li><a href="../../../../allclasses-noframe.html">All Classes</a></li>
|
||
|
</ul>
|
||
|
<div>
|
||
|
<script type="text/javascript"><!--
|
||
|
allClassesLink = document.getElementById("allclasses_navbar_top");
|
||
|
if(window==top) {
|
||
|
allClassesLink.style.display = "block";
|
||
|
}
|
||
|
else {
|
||
|
allClassesLink.style.display = "none";
|
||
|
}
|
||
|
//-->
|
||
|
</script>
|
||
|
</div>
|
||
|
<a name="skip.navbar.top">
|
||
|
<!-- -->
|
||
|
</a></div>
|
||
|
<!-- ========= END OF TOP NAVBAR ========= -->
|
||
|
<div class="header">
|
||
|
<h1 title="Package" class="title">Package com.sleepycat.persist.evolve</h1>
|
||
|
<div class="docSummary">
|
||
|
<div class="block">Utilities for managing class evolution of persistent objects.</div>
|
||
|
</div>
|
||
|
<p>See: <a href="#package.description">Description</a></p>
|
||
|
</div>
|
||
|
<div class="contentContainer">
|
||
|
<ul class="blockList">
|
||
|
<li class="blockList">
|
||
|
<table class="typeSummary" border="0" cellpadding="3" cellspacing="0" summary="Interface Summary table, listing interfaces, and an explanation">
|
||
|
<caption><span>Interface Summary</span><span class="tabEnd"> </span></caption>
|
||
|
<tr>
|
||
|
<th class="colFirst" scope="col">Interface</th>
|
||
|
<th class="colLast" scope="col">Description</th>
|
||
|
</tr>
|
||
|
<tbody>
|
||
|
<tr class="altColor">
|
||
|
<td class="colFirst"><a href="../../../../com/sleepycat/persist/evolve/Conversion.html" title="interface in com.sleepycat.persist.evolve">Conversion</a></td>
|
||
|
<td class="colLast">
|
||
|
<div class="block">Converts an old version of an object value to conform to the current class
|
||
|
or field definition.</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr class="rowColor">
|
||
|
<td class="colFirst"><a href="../../../../com/sleepycat/persist/evolve/EvolveListener.html" title="interface in com.sleepycat.persist.evolve">EvolveListener</a></td>
|
||
|
<td class="colLast">
|
||
|
<div class="block">The listener interface called during eager entity evolution.</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</li>
|
||
|
<li class="blockList">
|
||
|
<table class="typeSummary" border="0" cellpadding="3" cellspacing="0" summary="Class Summary table, listing classes, and an explanation">
|
||
|
<caption><span>Class Summary</span><span class="tabEnd"> </span></caption>
|
||
|
<tr>
|
||
|
<th class="colFirst" scope="col">Class</th>
|
||
|
<th class="colLast" scope="col">Description</th>
|
||
|
</tr>
|
||
|
<tbody>
|
||
|
<tr class="altColor">
|
||
|
<td class="colFirst"><a href="../../../../com/sleepycat/persist/evolve/Converter.html" title="class in com.sleepycat.persist.evolve">Converter</a></td>
|
||
|
<td class="colLast">
|
||
|
<div class="block">A mutation for converting an old version of an object value to conform to
|
||
|
the current class or field definition.</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr class="rowColor">
|
||
|
<td class="colFirst"><a href="../../../../com/sleepycat/persist/evolve/Deleter.html" title="class in com.sleepycat.persist.evolve">Deleter</a></td>
|
||
|
<td class="colLast">
|
||
|
<div class="block">A mutation for deleting an entity class or field.</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr class="altColor">
|
||
|
<td class="colFirst"><a href="../../../../com/sleepycat/persist/evolve/EntityConverter.html" title="class in com.sleepycat.persist.evolve">EntityConverter</a></td>
|
||
|
<td class="colLast">
|
||
|
<div class="block">A subclass of Converter that allows specifying keys to be deleted.</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr class="rowColor">
|
||
|
<td class="colFirst"><a href="../../../../com/sleepycat/persist/evolve/EvolveConfig.html" title="class in com.sleepycat.persist.evolve">EvolveConfig</a></td>
|
||
|
<td class="colLast">
|
||
|
<div class="block">Configuration properties for eager conversion of unevolved objects.</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr class="altColor">
|
||
|
<td class="colFirst"><a href="../../../../com/sleepycat/persist/evolve/EvolveConfigBeanInfo.html" title="class in com.sleepycat.persist.evolve">EvolveConfigBeanInfo</a></td>
|
||
|
<td class="colLast"> </td>
|
||
|
</tr>
|
||
|
<tr class="rowColor">
|
||
|
<td class="colFirst"><a href="../../../../com/sleepycat/persist/evolve/EvolveEvent.html" title="class in com.sleepycat.persist.evolve">EvolveEvent</a></td>
|
||
|
<td class="colLast">
|
||
|
<div class="block">The event passed to the EvolveListener interface during eager entity
|
||
|
evolution.</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr class="altColor">
|
||
|
<td class="colFirst"><a href="../../../../com/sleepycat/persist/evolve/EvolveStats.html" title="class in com.sleepycat.persist.evolve">EvolveStats</a></td>
|
||
|
<td class="colLast">
|
||
|
<div class="block">Statistics accumulated during eager entity evolution.</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr class="rowColor">
|
||
|
<td class="colFirst"><a href="../../../../com/sleepycat/persist/evolve/Mutation.html" title="class in com.sleepycat.persist.evolve">Mutation</a></td>
|
||
|
<td class="colLast">
|
||
|
<div class="block">The base class for all mutations.</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr class="altColor">
|
||
|
<td class="colFirst"><a href="../../../../com/sleepycat/persist/evolve/Mutations.html" title="class in com.sleepycat.persist.evolve">Mutations</a></td>
|
||
|
<td class="colLast">
|
||
|
<div class="block">A collection of mutations for configuring class evolution.</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr class="rowColor">
|
||
|
<td class="colFirst"><a href="../../../../com/sleepycat/persist/evolve/Renamer.html" title="class in com.sleepycat.persist.evolve">Renamer</a></td>
|
||
|
<td class="colLast">
|
||
|
<div class="block">A mutation for renaming a class or field without changing the instance or
|
||
|
field value.</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</li>
|
||
|
<li class="blockList">
|
||
|
<table class="typeSummary" border="0" cellpadding="3" cellspacing="0" summary="Exception Summary table, listing exceptions, and an explanation">
|
||
|
<caption><span>Exception Summary</span><span class="tabEnd"> </span></caption>
|
||
|
<tr>
|
||
|
<th class="colFirst" scope="col">Exception</th>
|
||
|
<th class="colLast" scope="col">Description</th>
|
||
|
</tr>
|
||
|
<tbody>
|
||
|
<tr class="altColor">
|
||
|
<td class="colFirst"><a href="../../../../com/sleepycat/persist/evolve/DeletedClassException.html" title="class in com.sleepycat.persist.evolve">DeletedClassException</a></td>
|
||
|
<td class="colLast">
|
||
|
<div class="block">While reading from an index, an instance of a deleted class version was
|
||
|
encountered.</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr class="rowColor">
|
||
|
<td class="colFirst"><a href="../../../../com/sleepycat/persist/evolve/IncompatibleClassException.html" title="class in com.sleepycat.persist.evolve">IncompatibleClassException</a></td>
|
||
|
<td class="colLast">
|
||
|
<div class="block">A class has been changed incompatibly and no mutation has been configured to
|
||
|
handle the change or a new class version number has not been assigned.</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</li>
|
||
|
</ul>
|
||
|
<a name="package.description">
|
||
|
<!-- -->
|
||
|
</a>
|
||
|
<h2 title="Package com.sleepycat.persist.evolve Description">Package com.sleepycat.persist.evolve Description</h2>
|
||
|
<div class="block">Utilities for managing class evolution of persistent objects.
|
||
|
|
||
|
<h1>Class Evolution</h1>
|
||
|
|
||
|
<p>For persistent data that is not short lived, changes to persistent classes
|
||
|
are almost inevitable. Some changes are compatible with existing types, and
|
||
|
data conversion for these changes is performed automatically and transparently.
|
||
|
Other changes are not compatible with existing types. Mutations can be used to
|
||
|
explicitly manage many types of incompatible changes.</p>
|
||
|
|
||
|
<p>Not all incompatible class changes can be handled via mutations. For
|
||
|
example, complex refactoring may require a transformation that manipulates
|
||
|
multiple entity instances at once. Such changes are not possible with
|
||
|
mutations but can be made by performing a <a href="#storeConversion">store
|
||
|
conversion</a>.</p>
|
||
|
|
||
|
<p>The different categories of type changes are described below.</p>
|
||
|
|
||
|
<h2>Key Field Changes</h2>
|
||
|
|
||
|
<p>Unlike entity data, key data is not versioned. Therefore, the physical key
|
||
|
format for an index is fixed once the index has been opened, and the changes
|
||
|
allowed for key fields are very limited. The only changes allowed for key
|
||
|
fields are:</p>
|
||
|
<ul>
|
||
|
<li>The name of a key field may be changed, as long as this change is
|
||
|
accompanied by a <a href="../../../../com/sleepycat/persist/evolve/Renamer.html" title="class in com.sleepycat.persist.evolve"><code>Renamer</code></a> mutation.</li>
|
||
|
<li>A primitive type may be changed to its corresponding primitive wrapper
|
||
|
type. This is a compatible change.</li>
|
||
|
<li>For primary key fields and fields of a composite key class, a primitive
|
||
|
wrapper type may be changed to its corresponding primitive type. This is
|
||
|
allowed because these key fields with reference types may never have null
|
||
|
values. This is a compatible change.</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>Any other changes to a key field are incompatible and may be made only by
|
||
|
performing a <a href="#storeConversion">store conversion</a>.</p>
|
||
|
|
||
|
<p>Key ordering, including the behavior of a custom <code>Comparable</code>, is also fixed, since keys are stored in order in the
|
||
|
index. The specifications for key ordering may not be changed, and the
|
||
|
developer is responsible for not changing the behavior of a <code>Comparable</code>
|
||
|
key class. <strong>WARNING:</strong>: Changing the behavior of a <code>Comparable</code> key class is likely to make the index unusable.</p>
|
||
|
|
||
|
<h2>Compatible Type Changes</h2>
|
||
|
|
||
|
<p>Entity data, unlike key data, is versioned. Therefore, some changes can be
|
||
|
made compatibly and other changes can be handled via mutations. Compatible
|
||
|
changes are defined below. To make a compatible class change, a mutation is
|
||
|
not required; however, the class version must be assigned a new (greater)
|
||
|
integer value.</p>
|
||
|
|
||
|
<p>Changes to a class hierarchy are compatible in some cases. A new class may
|
||
|
be inserted in the hierarchy. A class may be deleted from the hierarchy as
|
||
|
long as one of the following is true: 1) it contains no persistent fields, 2)
|
||
|
any persistent fields are deleted with field Deleter mutations, or 3) the class
|
||
|
is deleted with a class Deleter mutation. Classes in an existing hierarchy may
|
||
|
not be reordered compatibly, and fields may not moved from one class to another
|
||
|
compatibly; for such changes a class Converter mutation is required.</p>
|
||
|
|
||
|
<p>Changes to field types in entity class definitions are compatible when they
|
||
|
conform to the Java Language Specification definitions for <a
|
||
|
href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.2">Widening
|
||
|
Primitive Conversions</a> and <a
|
||
|
href="http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.5">Widening
|
||
|
Reference Conversions</a>. For example, a smaller integer
|
||
|
type may be changed to a larger integer type, and a reference type may be
|
||
|
changed to one of its supertypes. Automatic widening conversions are performed
|
||
|
as described in the Java Language Specification.</p>
|
||
|
|
||
|
<p>Primitive types may also be compatibly changed to their corresponding
|
||
|
primitive wrapper types, or to the wrapper type for a widened primitive type.
|
||
|
However, changing from a primitive wrapper type to a primitive type is not a
|
||
|
compatible change since existing null values could not be represented.</p>
|
||
|
|
||
|
<p>Integer primitive types (byte, short, char, int, long) and their primitive
|
||
|
wrapper types may be compatibly changed to the BigInteger type.</p>
|
||
|
|
||
|
<p>Enum values may be added compatibly, but may not be deleted or renamed. As
|
||
|
long as new values are declared after existing values, the default sort order
|
||
|
for enum key fields will match the declaration order, i.e, the default sort
|
||
|
order will match the enum ordinal order. If a new value is inserted (declared
|
||
|
before an existing value), it will be sorted after all existing values but
|
||
|
before newly added values. However, these ordering rules are only guaranteed
|
||
|
for enums containing up to 631 values and only if existing values are not
|
||
|
reordered. If more than 631 values are declared or the declarations of
|
||
|
existing values are reordered, then the default sort order will be arbitrary
|
||
|
and will not match the declaration (ordinal) order.</p>
|
||
|
|
||
|
<p>In addition, adding fields to a class is a compatible change. When a
|
||
|
persistent instance of a class is read that does not contain the new field, the
|
||
|
new field is initialized by the default constructor.</p>
|
||
|
|
||
|
<p>All other changes to instance fields are considered incompatible.
|
||
|
Incompatible changes may be handled via mutations, as described next.</p>
|
||
|
|
||
|
<p>Note that whenever a class is changed, either compatibly or incompatibly, a
|
||
|
new (higher) class version number must be assigned. See <a href="../../../../com/sleepycat/persist/model/Entity.html#version--"><code>Entity.version()</code></a> and <a href="../../../../com/sleepycat/persist/model/Persistent.html#version--"><code>Persistent.version()</code></a> for information on assigning
|
||
|
class version numbers.</p>
|
||
|
|
||
|
<h2>Mutations</h2>
|
||
|
|
||
|
<p>There are three types of mutations: <a href="../../../../com/sleepycat/persist/evolve/Renamer.html" title="class in com.sleepycat.persist.evolve"><code>Renamer</code></a>, <a href="../../../../com/sleepycat/persist/evolve/Deleter.html" title="class in com.sleepycat.persist.evolve"><code>Deleter</code></a> and <a href="../../../../com/sleepycat/persist/evolve/Converter.html" title="class in com.sleepycat.persist.evolve"><code>Converter</code></a>.</p>
|
||
|
|
||
|
<p>A class or field can be renamed using a <a href="../../../../com/sleepycat/persist/evolve/Renamer.html" title="class in com.sleepycat.persist.evolve"><code>Renamer</code></a>. Renaming is not expensive, since it
|
||
|
does not involve conversion of instance data.</p>
|
||
|
|
||
|
<p>A class or field can be deleted using a <a href="../../../../com/sleepycat/persist/evolve/Deleter.html" title="class in com.sleepycat.persist.evolve"><code>Deleter</code></a>.</p>
|
||
|
<ul>
|
||
|
<li>Deleting an entity class causes removal of the primary and secondary
|
||
|
indices for the store, on other words, removal of all store entities for that
|
||
|
class and its subclasses. Removal is performed when the store is opened. A
|
||
|
<a href="../../../../com/sleepycat/persist/evolve/Deleter.html" title="class in com.sleepycat.persist.evolve"><code>Deleter</code></a> should be used for an entity class
|
||
|
in all of the following circumstances:
|
||
|
<ul>
|
||
|
<li>When removing the entity class itself.</li>
|
||
|
<li>When removing <a href="../../../../com/sleepycat/persist/model/Entity.html" title="annotation in com.sleepycat.persist.model"><code>Entity</code></a> from the class
|
||
|
to make it non-persistent.</li>
|
||
|
<li>When removing <a href="../../../../com/sleepycat/persist/model/Entity.html" title="annotation in com.sleepycat.persist.model"><code>Entity</code></a> from the class
|
||
|
and adding <a href="../../../../com/sleepycat/persist/model/Persistent.html" title="annotation in com.sleepycat.persist.model"><code>Persistent</code></a>, to use it as an
|
||
|
embedded persistent class but not an entity class. The version of the class
|
||
|
must be incremented in this case.</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
|
||
|
<li>Deleting a non-entity class does not itself cause deletion of instance
|
||
|
data, but is needed to inform DPL that the deleted class will not be used.
|
||
|
Instances of the deleted class must be handled (discarded or converted to
|
||
|
another class) by <a href="../../../../com/sleepycat/persist/evolve/Deleter.html" title="class in com.sleepycat.persist.evolve"><code>Deleter</code></a> or <a href="../../../../com/sleepycat/persist/evolve/Converter.html" title="class in com.sleepycat.persist.evolve"><code>Converter</code></a> mutations for the field or enclosing
|
||
|
class that contain embedded instances of the deleted class. A <a href="../../../../com/sleepycat/persist/evolve/Deleter.html" title="class in com.sleepycat.persist.evolve"><code>Deleter</code></a> should be used for a non-entity class in
|
||
|
all of the following circumstances:
|
||
|
<ul>
|
||
|
<li>When removing the persistent class itself.</li>
|
||
|
<li>When removing <a href="../../../../com/sleepycat/persist/model/Persistent.html" title="annotation in com.sleepycat.persist.model"><code>Persistent</code></a> from the
|
||
|
class to make it non-persistent.</li>
|
||
|
<li>When removing <a href="../../../../com/sleepycat/persist/model/Persistent.html" title="annotation in com.sleepycat.persist.model"><code>Persistent</code></a> from the
|
||
|
class and adding <a href="../../../../com/sleepycat/persist/model/Entity.html" title="annotation in com.sleepycat.persist.model"><code>Entity</code></a>, to use it as an
|
||
|
entity class but not an embedded persistent class. The version of the class
|
||
|
must be incremented in this case.</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
|
||
|
<li>Deleting a field causes automatic conversion of the instances containing
|
||
|
that field, in order to discard the field values.</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>Other incompatible changes are handled by creating a <a href="../../../../com/sleepycat/persist/evolve/Converter.html" title="class in com.sleepycat.persist.evolve"><code>Converter</code></a> mutation and implementing a <a href="../../../../com/sleepycat/persist/evolve/Conversion.html#convert-java.lang.Object-"><code>Conversion.convert</code></a> method that
|
||
|
manipulates the raw objects and/or simple values directly. The <code>convert</code>
|
||
|
method is passed an object of the old incompatible type and it returns an
|
||
|
object of a current type.</p>
|
||
|
|
||
|
<p>Conversions can be specified in two ways: for specific fields or for all
|
||
|
instances of a class. A different <a href="../../../../com/sleepycat/persist/evolve/Converter.html" title="class in com.sleepycat.persist.evolve"><code>Converter</code></a> constructor is used in each case.
|
||
|
Field-specific conversions are used instead of class conversions when both are
|
||
|
applicable.</p>
|
||
|
|
||
|
<p>Note that a class conversion may be not specified for an enum class. A
|
||
|
field conversion, or a class conversion for the class declaring the field, may
|
||
|
be used.</p>
|
||
|
|
||
|
<p>Note that each mutation is applied to a specific class version number. The
|
||
|
class version must be explicitly specified in a mutation for two reasons:</p>
|
||
|
<ol>
|
||
|
<li>This provides safety in the face of multiple unconverted versions of a
|
||
|
given type. Without a version, a single conversion method would have to handle
|
||
|
multiple input types, and would have to distinguish between them by examining
|
||
|
the data or type information.</li>
|
||
|
<li>This allows arbitrary changes to be made. For example, a series of name
|
||
|
changes may reuse a given name for more than one version. To identify the
|
||
|
specific type being converted or renamed, a version number is needed.</li>
|
||
|
</ol>
|
||
|
<p>See <a href="../../../../com/sleepycat/persist/model/Entity.html#version--"><code>Entity.version()</code></a> and <a href="../../../../com/sleepycat/persist/model/Persistent.html#version--"><code>Persistent.version()</code></a> for information on assigning
|
||
|
class version numbers.</p>
|
||
|
|
||
|
<p>Mutations are therefore responsible for converting each existing
|
||
|
incompatible class version to the current version as defined by a current class
|
||
|
definition. For example, consider that class-version A-1 is initially changed
|
||
|
to A-2 and a mutation is added for converting A-1 to A-2. If later changes in
|
||
|
version A-3 occur before converting all A-1 instances to version A-2, the
|
||
|
converter for A-1 will have to be changed. Instead of converting from A-1 to
|
||
|
A-2 it will need to convert from A-1 to A-3. In addition, a mutation
|
||
|
converting A-2 to A-3 will be needed.</p>
|
||
|
|
||
|
<p>When a <a href="../../../../com/sleepycat/persist/evolve/Converter.html" title="class in com.sleepycat.persist.evolve"><code>Converter</code></a> mutation applies to a
|
||
|
given object, other mutations that may apply to that object are not
|
||
|
automatically performed. It is the responsibility of the <a href="../../../../com/sleepycat/persist/evolve/Converter.html" title="class in com.sleepycat.persist.evolve"><code>Converter</code></a> to return an object that conforms to
|
||
|
the current class definition, including renaming fields and classes. If the
|
||
|
input object has nested objects or superclasses that also need conversion, the
|
||
|
converter must perform these nested conversions before returning the final
|
||
|
converted object. This rule avoids the complexity and potential errors that
|
||
|
could result if a converter mutation were automatically combined with other
|
||
|
mutations in an arbitrary manner.</p>
|
||
|
|
||
|
<p>The <a href="../../../../com/sleepycat/persist/EntityStore.html#evolve-com.sleepycat.persist.evolve.EvolveConfig-"><code>EntityStore.evolve</code></a>
|
||
|
method may optionally be used to ensure that all instances of an old class
|
||
|
version are converted to the current version.</p>
|
||
|
|
||
|
<h2>Other Metadata Changes</h2>
|
||
|
|
||
|
<p>When a class that happens to be an entity class is renamed, it remains an
|
||
|
entity class. When a field that happens to be a primary or
|
||
|
secondary key field is renamed, its metadata remains intact as well.</p>
|
||
|
|
||
|
<p>When the <a href="../../../../com/sleepycat/persist/model/SecondaryKey.html" title="annotation in com.sleepycat.persist.model"><code>SecondaryKey</code></a> annotation is
|
||
|
added to an <em>existing</em> field, a new index is created automatically. The
|
||
|
new index will be populated by reading the entire primary index when the
|
||
|
primary index is opened.</p>
|
||
|
|
||
|
<p>When the <a href="../../../../com/sleepycat/persist/model/SecondaryKey.html" title="annotation in com.sleepycat.persist.model"><code>SecondaryKey</code></a> annotation is
|
||
|
included with a <em>new</em> field, a new index is created automatically. The
|
||
|
new field is required to be a reference type (not a primitive) and must be
|
||
|
initialized to null (the default behavior) in the default constructor.
|
||
|
Entities will be indexed by the field when they are stored with a non-null key
|
||
|
value.</p>
|
||
|
|
||
|
<p>When a field with the <a href="../../../../com/sleepycat/persist/model/SecondaryKey.html" title="annotation in com.sleepycat.persist.model"><code>SecondaryKey</code></a>
|
||
|
annotation is deleted, or when the <a href="../../../../com/sleepycat/persist/model/SecondaryKey.html" title="annotation in com.sleepycat.persist.model"><code>SecondaryKey</code></a> annotation is removed from a field
|
||
|
without deleting it, the secondary index is removed (dropped). Removal occurs
|
||
|
when the store is opened.</p>
|
||
|
|
||
|
<p>The <a href="../../../../com/sleepycat/persist/model/SecondaryKey.html#relate--"><code>SecondaryKey.relate</code></a> property may NOT be changed. All other properties of a
|
||
|
<a href="../../../../com/sleepycat/persist/model/SecondaryKey.html" title="annotation in com.sleepycat.persist.model"><code>SecondaryKey</code></a> may be changed, although
|
||
|
avoiding changes that cause foreign key integrity errors is the responsibility
|
||
|
of the application developer. For example, if the <a href="../../../../com/sleepycat/persist/model/SecondaryKey.html#relatedEntity--"><code>SecondaryKey.relatedEntity()</code></a> property is added but
|
||
|
not all existing secondary keys reference existing primary keys for the related
|
||
|
entity, foreign key integrity errors may occur.</p>
|
||
|
|
||
|
<p>The <a href="../../../../com/sleepycat/persist/model/PrimaryKey.html" title="annotation in com.sleepycat.persist.model"><code>PrimaryKey</code></a> annotation may NOT be
|
||
|
removed from a field in an entity class.</p>
|
||
|
|
||
|
<p>The <a href="../../../../com/sleepycat/persist/model/PrimaryKey.html#sequence--"><code>PrimaryKey.sequence()</code></a> property may be
|
||
|
added, removed, or changed to a different name.</p>
|
||
|
|
||
|
<p>The <a href="../../../../com/sleepycat/persist/model/Persistent.html#proxyFor--"><code>Persistent.proxyFor()</code></a> property may NOT
|
||
|
be added, removed, or changed to a different class.</p>
|
||
|
|
||
|
<h2>Warnings on Testing and Backups</h2>
|
||
|
|
||
|
<p>The application developer is responsible for verifying that class evolution
|
||
|
works properly before deploying with a changed set of persistent classes. The
|
||
|
DPL will report errors when old class definitions cannot be evolved, for
|
||
|
example, when a mutation is missing. To test that no such errors will occur,
|
||
|
application test cases must include instances of all persistent classes.</p>
|
||
|
|
||
|
<p>Converter mutations require special testing. Since the application
|
||
|
conversion method is allowed to return instances of any type, the DPL cannot
|
||
|
check that the proper type is returned until the data is accessed. To avoid
|
||
|
data access errors, application test cases must cover converter mutations for
|
||
|
all potential input and output types.</p>
|
||
|
|
||
|
<p>When secondary keys are dropped or entity classes are deleted, the
|
||
|
underlying databases are deleted and cannot be recovered from the store. This
|
||
|
takes place when the store is opened. It is strongly recommended that a backup
|
||
|
of the entire store is made before opening the store and causing class
|
||
|
evolution to proceed.</p>
|
||
|
|
||
|
<h2><a name="storeConversion">Store Conversion</a></h2>
|
||
|
|
||
|
<p>When mutations are not sufficient for handling class changes, a full store
|
||
|
conversion may be performed. This is necessary for two particular types of
|
||
|
class changes:</p>
|
||
|
<ul>
|
||
|
<li>A change to a physical key format, for example, a change from type
|
||
|
<code>int</code> to type <code>long</code>.</li>
|
||
|
<li>A conversion that involves multiple entities at once, for example,
|
||
|
combining two separate entity classes into a new single entity class.</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>To perform a full store conversion, a program is written that performs the
|
||
|
following steps to copy the data from the old store to a new converted
|
||
|
store:</p>
|
||
|
<ol>
|
||
|
<li>The old store is opened as a <a href="../../../../com/sleepycat/persist/raw/RawStore.html" title="class in com.sleepycat.persist.raw"><code>RawStore</code></a> and
|
||
|
the new store is opened as an <a href="../../../../com/sleepycat/persist/EntityStore.html" title="class in com.sleepycat.persist"><code>EntityStore</code></a>.</li>
|
||
|
<li>All entities are read from the old store. Entities are read using a <a href="../../../../com/sleepycat/persist/raw/RawStore.html" title="class in com.sleepycat.persist.raw"><code>RawStore</code></a> to allow access to entities for which no
|
||
|
compatible class exists.</li>
|
||
|
<li>The <a href="../../../../com/sleepycat/persist/raw/RawObject.html" title="class in com.sleepycat.persist.raw"><code>RawObject</code></a> entities are then converted
|
||
|
to the format desired. Raw objects can be arbitrarily manipulated as needed.
|
||
|
The updated raw objects must conform to the new evolved class definitions.</li>
|
||
|
<li>The updated raw entities are converted to live objects by calling the
|
||
|
<a href="../../../../com/sleepycat/persist/model/EntityModel.html#convertRawObject-com.sleepycat.persist.raw.RawObject-"><code>EntityModel.convertRawObject</code></a> method of the new store. This method converts
|
||
|
raw objects obtained from a different store, as long as they conform to the new
|
||
|
evolved class definitions.</li>
|
||
|
<li>The new live objects are written to the new <a href="../../../../com/sleepycat/persist/EntityStore.html" title="class in com.sleepycat.persist"><code>EntityStore</code></a> using a <a href="../../../../com/sleepycat/persist/PrimaryIndex.html" title="class in com.sleepycat.persist"><code>PrimaryIndex</code></a> as usual.</li>
|
||
|
</ol>
|
||
|
|
||
|
<p>To perform such a conversion, two separate stores must be open at once.
|
||
|
Both stores may be in the same <a href="../../../../com/sleepycat/je/Environment.html" title="class in com.sleepycat.je"><code>Environment</code></a>, if
|
||
|
desired, by giving them different store names. But since all data is being
|
||
|
rewritten, there are performance advantages to creating the new store in a new
|
||
|
fresh environment: the data will be compacted as it is written, and the old
|
||
|
store can be removed very quickly by deleting the old environment directory
|
||
|
after the conversion is complete.</p>
|
||
|
|
||
|
<!-- begin JE only -->
|
||
|
|
||
|
<h2><a name="repUpgrade">Upgrading a Replication Group</a></h2>
|
||
|
|
||
|
<p>When changes to persistent classes are made in a <a href="../../../../com/sleepycat/je/rep/ReplicatedEnvironment.html" title="class in com.sleepycat.je.rep"><code>ReplicatedEnvironment</code></a>, special handling is necessary when
|
||
|
the application is upgraded on the nodes in the replication group. Upgraded
|
||
|
means that the application on a node is stopped, the updated application
|
||
|
classes are installed, and the application is started again.</p>
|
||
|
|
||
|
<p>As usual in any sort of replication group upgrade, the Replica nodes must be
|
||
|
upgraded first and the Master node must be upgraded last. If an upgraded node
|
||
|
is elected Master before all of the Replica nodes have been upgraded, either
|
||
|
because of a user error or an unexpected failover, the <a href="../../../../com/sleepycat/persist/evolve/IncompatibleClassException.html" title="class in com.sleepycat.persist.evolve"><code>IncompatibleClassException</code></a> will be thrown.</p>
|
||
|
|
||
|
<p>There are two considerations that must be taken into account during the
|
||
|
upgrade process: new indexes that are temporarily unavailable on a Replica,
|
||
|
and exceptions that result from renamed entity classes and secondary keys.</p>
|
||
|
|
||
|
<p>Note that these considerations only apply when a hot upgrade is performed,
|
||
|
i.e., when the replication group will contain a mix of upgraded and
|
||
|
non-upgraded nodes. If all nodes in the group are first taken down and then
|
||
|
the nodes are upgraded and restarted, then no special considerations are
|
||
|
necessary and this documentation is not applicable.</p>
|
||
|
|
||
|
<h3>Defining New Indexes in a Replication Group</h3>
|
||
|
|
||
|
<p>When a new entity class is added, which defines a new <code>PrimaryIndex</code>, or a new secondary key is added, which defines a new <code>SecondaryIndex</code>, the indexes will not be immediately available on an upgraded
|
||
|
node. A new index will not be fully available (i.e., on every node) until all
|
||
|
the nodes have been upgraded, the index has been created (and populated, in the
|
||
|
case of a secondary index) on the Master node, and the index has been
|
||
|
replicated to each Replica node via the replication stream.</p>
|
||
|
|
||
|
<p>When a node is first upgraded it will start out as a Replica node, and any
|
||
|
newly defined indexes will not be available. The application has two choices
|
||
|
for handling this condition.</p>
|
||
|
<ol>
|
||
|
<li>An application may be able to coordinate among its nodes, by its own means,
|
||
|
to inform all nodes when an index has been created and populated on the Master.
|
||
|
Such an application can choose to access a new index only after it knows the
|
||
|
index is available. Such coordination is not directly supported by JE,
|
||
|
although a transaction with a <a href="../../../../com/sleepycat/je/CommitToken.html" title="class in com.sleepycat.je"><code>CommitToken</code></a> may be used
|
||
|
to simplify the coordination process.</li>
|
||
|
|
||
|
<li>An application may call <a href="../../../../com/sleepycat/persist/EntityStore.html#getPrimaryIndex-java.lang.Class-java.lang.Class-"><code>getPrimaryIndex</code></a> or <a href="../../../../com/sleepycat/persist/EntityStore.html#getSecondaryIndex-com.sleepycat.persist.PrimaryIndex-java.lang.Class-java.lang.String-"><code>getSecondaryIndex</code></a> to
|
||
|
determine whether an index is available. An <a href="../../../../com/sleepycat/persist/IndexNotAvailableException.html" title="class in com.sleepycat.persist"><code>IndexNotAvailableException</code></a> is thrown by these methods
|
||
|
when the index has not yet been created or when a secondary index is currently
|
||
|
being populated via the replication stream.</li>
|
||
|
</ol>
|
||
|
|
||
|
<p>When an upgraded node is elected Master (this is typically near the end of
|
||
|
the the upgrade process), it must call <a href="../../../../com/sleepycat/persist/EntityStore.html#getPrimaryIndex-java.lang.Class-java.lang.Class-"><code>getPrimaryIndex</code></a> to create
|
||
|
each new primary index, and <a href="../../../../com/sleepycat/persist/EntityStore.html#getSecondaryIndex-com.sleepycat.persist.PrimaryIndex-java.lang.Class-java.lang.String-"><code>getSecondaryIndex</code></a> to
|
||
|
create and populate each new secondary index. A newly elected Master node that
|
||
|
was just upgraded should be prepared for a delay when <a href="../../../../com/sleepycat/persist/EntityStore.html#getSecondaryIndex-com.sleepycat.persist.PrimaryIndex-java.lang.Class-java.lang.String-"><code>getSecondaryIndex</code></a> is
|
||
|
called to create and populate a new secondary index.</p>
|
||
|
|
||
|
<h3>Renaming Entity Classes and Keys in a Replication Group</h3>
|
||
|
|
||
|
<p>When a DPL entity class or secondary key field is renamed by an application
|
||
|
using a <a href="../../../../com/sleepycat/persist/evolve/Renamer.html" title="class in com.sleepycat.persist.evolve"><code>Renamer</code></a> mutation, this will result
|
||
|
internally in the underlying database for that entity class or secondary key
|
||
|
being renamed. The actual renaming of the database first occurs on the
|
||
|
upgraded Master node and is then replicated to each Replica node.</p>
|
||
|
|
||
|
<p>When the application on a Master or Replica node first accesses the store
|
||
|
<em>after</em> the database has been renamed, a <a href="../../../../com/sleepycat/je/rep/DatabasePreemptedException.html" title="class in com.sleepycat.je.rep"><code>DatabasePreemptedException</code></a> will be thrown. When this
|
||
|
happens, the application must close any cursors and transactions that are open
|
||
|
for that store, and then close the store and reopen it.</p>
|
||
|
|
||
|
<!-- end JE only --></div>
|
||
|
</div>
|
||
|
<!-- ======= START OF BOTTOM NAVBAR ====== -->
|
||
|
<div class="bottomNav"><a name="navbar.bottom">
|
||
|
<!-- -->
|
||
|
</a>
|
||
|
<div class="skipNav"><a href="#skip.navbar.bottom" title="Skip navigation links">Skip navigation links</a></div>
|
||
|
<a name="navbar.bottom.firstrow">
|
||
|
<!-- -->
|
||
|
</a>
|
||
|
<ul class="navList" title="Navigation">
|
||
|
<li><a href="../../../../overview-summary.html">Overview</a></li>
|
||
|
<li class="navBarCell1Rev">Package</li>
|
||
|
<li>Class</li>
|
||
|
<li><a href="package-use.html">Use</a></li>
|
||
|
<li><a href="package-tree.html">Tree</a></li>
|
||
|
<li><a href="../../../../deprecated-list.html">Deprecated</a></li>
|
||
|
<li><a href="../../../../index-all.html">Index</a></li>
|
||
|
<li><a href="../../../../help-doc.html">Help</a></li>
|
||
|
</ul>
|
||
|
<div class="aboutLanguage"><b>Berkeley DB Java Edition</b><br><font size=\"-1\"> version 7.5.11</font>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div class="subNav">
|
||
|
<ul class="navList">
|
||
|
<li><a href="../../../../com/sleepycat/persist/package-summary.html">Prev Package</a></li>
|
||
|
<li><a href="../../../../com/sleepycat/persist/model/package-summary.html">Next Package</a></li>
|
||
|
</ul>
|
||
|
<ul class="navList">
|
||
|
<li><a href="../../../../index.html?com/sleepycat/persist/evolve/package-summary.html" target="_top">Frames</a></li>
|
||
|
<li><a href="package-summary.html" target="_top">No Frames</a></li>
|
||
|
</ul>
|
||
|
<ul class="navList" id="allclasses_navbar_bottom">
|
||
|
<li><a href="../../../../allclasses-noframe.html">All Classes</a></li>
|
||
|
</ul>
|
||
|
<div>
|
||
|
<script type="text/javascript"><!--
|
||
|
allClassesLink = document.getElementById("allclasses_navbar_bottom");
|
||
|
if(window==top) {
|
||
|
allClassesLink.style.display = "block";
|
||
|
}
|
||
|
else {
|
||
|
allClassesLink.style.display = "none";
|
||
|
}
|
||
|
//-->
|
||
|
</script>
|
||
|
</div>
|
||
|
<a name="skip.navbar.bottom">
|
||
|
<!-- -->
|
||
|
</a></div>
|
||
|
<!-- ======== END OF BOTTOM NAVBAR ======= -->
|
||
|
<p class="legalCopy"><small><font size=1>Copyright (c) 2002, 2017 Oracle and/or its affiliates. All rights reserved.</font> </small></p>
|
||
|
</body>
|
||
|
</html>
|