Added: incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_remote.xml URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_remote.xml?rev=433761&view=auto ============================================================================== --- incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_remote.xml (added) +++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_remote.xml Tue Aug 22 14:28:53 2006 @@ -0,0 +1,604 @@ + + <chapter id="ref_guide_remote"> + <title>Remote and Offline Operation</title> + <indexterm zone="ref_guide_remote"> + <primary>remote</primary> + </indexterm> + <indexterm> + <primary>offline</primary> + <see>remote</see> + </indexterm> + <para> + The standard JPA runtime environment is + <emphasis>local</emphasis> and <emphasis>online</emphasis>. It is + <emphasis>local</emphasis> in that components such as + <classname>EntityManager</classname>s and queries connect directly to + the datastore and execute their actions in the same JVM as the code using + them. It is <emphasis>online</emphasis> in that all changes to managed + objects must be made in the context of an active <classname> + EntityManager</classname>. + These two properties, combined with the fact that <classname> + EntityManager</classname>s cannot be serialized for storage or network + transfer, make the standard JPA runtime difficult to + incorporate into some enterprise and client/server program designs. + </para> + <para> + OpenJPA extends the standard runtime to add <emphasis>remote</emphasis> + and <emphasis>offline</emphasis> capabilities in the form of enhanced + <link linkend="ref_guide_detach">Detach and Attach APIs</link> and + <link linkend="ref_guide_event">Remote Commit Events</link>. + The following sections explain these capabilities in detail. + </para> + <section id="ref_guide_detach"> + <title>Detach and Attach</title> + <indexterm zone="ref_guide_detach"> + <primary>detachment</primary> + </indexterm> + <indexterm> + <primary>attachment</primary> + <see>detachment</see> + </indexterm> +<!-- ### EJBDOC : more specific links to EM detach discussion --> + <para> + The JPA Overview describes the specification's standard + detach and attach APIs in <xref linkend="jpa_overview_em"/>. + This section enumerates OpenJPA's enhancements to the standard behavior. + </para> + <section id="ref_guide_detach_behavior"> + <title>Detach Behavior</title> + <indexterm zone="ref_guide_detach_behavior"> + <primary>detachment</primary> + <secondary>behavior</secondary> + </indexterm> + <para> + In JPA, objects detach automatically when they are + serialized or when a <link linkend="jpa_overview_emfactory_perscontext">persistence + context</link> ends. The specification does not define any way to + explicitly detach objects. The extended + <ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html"><classname>OpenJPAEntityManager</classname></ulink>, however, allows + you to explicitly detach objects at any time. + </para> + <programlisting format="linespecific"> +public Object detach (Object pc): +public Object[] detachAll (Object... pcs): +public Collection detachAll (Collection pcs): +</programlisting> + <para> + Each detach method returns detached copies of the given instances. + The copy mechanism is similar to serialization, except that only + certain fields are traversed. We will see how to control which + fields are detached in a later section. + </para> + <para><indexterm><primary>detachment</primary><secondary>of dirty objects</secondary></indexterm> + When detaching an instance that has been modified in the current + transaction (and thus made dirty), the current transaction + is flushed. This means that when subsequently re-attaching + the detached instances, OpenJPA assumes that the transaction from + which they were originally detached was committed; if + it has been rolled back, then the re-attachment process will throw + an optimistic concurrency exception. + </para> + <para> + You can stop OpenJPA from assuming the transaction will commit by + invoking <methodname>OpenJPAEntityManager.setRollbackOnly</methodname> + prior to detaching your objects. Setting the + <literal>RollbackOnly</literal> flag prevents OpenJPA from flushing + when detaching dirty objects; instead OpenJPA just runs its pre-flush + actions (see the + <methodname>OpenJPAEntityManager.preFlush</methodname> + <ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html"> + Javadoc</ulink> for details). + </para> + <para> + This allows you to use the same + instances in multiple attach/modify/detach/rollback cycles. + Alternatively, you might also prevent a flush by making your + modifications outside of a transaction (with + <literal>NontransactionalWrite</literal> enabled) before detaching. + </para> + </section> + <section id="ref_guide_attach_behavior"> + <title>Attach Behavior</title> + <indexterm zone="ref_guide_attach_behavior"> + <primary>attachment</primary> + <secondary>behavior</secondary> + </indexterm> + <para> + When attaching, OpenJPA uses several strategies to determine the + optimal way to merge changes made to the detached instance. As + you will see, these strategies can even be used to attach changes + made to a transient instance which was never detached in the first + place. + </para> + <itemizedlist> + <listitem> + <para> + If the instance was detached and + <link linkend="ref_guide_detach_graph">detached state</link> + is enabled, OpenJPA will use the detached state to determine + the object's version and primary key values. In addition, + this state will tell OpenJPA which fields were loaded at the + time of detach, and in turn where to expect changes. Loaded + detached fields with null values will set the attached + instance's corresponding fields to null. + </para> + </listitem> + <listitem> + <para> + If the instance has + <phrase> + a <literal>Version</literal> field, + </phrase> + + + OpenJPA will consider the object detached if the version + field has a non-default value, and new otherwise. + </para> + <para> + When attaching null fields in these cases, OpenJPA cannot + distinguish between a field that was unloaded and one that + was intentionally set to null. In this case, OpenJPA will use + the current + <link linkend="ref_guide_detach_graph">detach state</link> + setting to determine how to handle null fields: + fields that would have been included in the detached state + are treated as loaded, and will in turn set the + corresponding attached field to null. + </para> + </listitem> + <listitem> + <para> + If neither of the above cases apply, OpenJPA will check to + see if an instance with the same primary key values exists + in the database. If so, the object is considered detached. + Otherwise, it is considered new. + </para> + </listitem> + </itemizedlist> + <para> + These strategies will be assigned on a per-instance basis, + such that during the attachment of an object graph more than + one of the above strategies may be used. + </para> + <para> + If you attempt to attach a versioned instance whose representation + has changed in the datastore since detachment, OpenJPA will throw an + optimistic concurrency exception upon commit or flush, just as if + a normal optimistic conflict was detected. When attaching an + instance whose database record has + been deleted since detaching, or when attaching a detached + instance into a manager that has a stale version of the object, + OpenJPA will throw an optimistic concurrency exception + from the attach method. In these cases, OpenJPA sets the + <literal>RollbackOnly</literal> flag on the transaction. + </para> + </section> + <section id="ref_guide_detach_graph"> + <title>Defining the Detached Object Graph</title> + <indexterm zone="ref_guide_detach_graph"> + <primary>detachment</primary> + <secondary>defining the object graph</secondary> + </indexterm> + <para> + When detached objects lose their association with the OpenJPA + runtime, they also lose the ability to load additional state + from the datastore. It is important, therefore, to populate objects + with all the persistent state you will need before detaching them. + While you are free to do this manually, OpenJPA includes + facilities for automatically populating objects when they detach. + The <link linkend="openjpa.DetachState"><literal>openjpa.DetachState + </literal></link> configuration property determines which fields + and relations are detached by default. All settings are recursive. + They are: + </para> + <orderedlist> + <listitem> + <para><literal>loaded</literal>: Detach all fields and relations + that are already loaded, but don't include unloaded fields + in the detached graph. This is the default. + </para> + </listitem> + <listitem> + <para><literal>fgs</literal>: Detach all fields and relations in + the default fetch group, and any other fetch groups that + you have added to the current + <link linkend="ref_guide_runtime">fetch + configuration</link>. For more information on custom + fetch groups, see <xref linkend="ref_guide_fetch"/>. + </para> + </listitem> + <listitem> + <para><literal>all</literal>: Detach all fields and relations. + Be very careful when + using this mode; if you have a highly-connected domain + model, you could end up bringing every object in the + database into memory! + </para> + </listitem> + </orderedlist> + <para> + Any field that is not included in the set determined by the detach + mode is set to its Java default value in the detached instance. + </para> + <para> + The <literal>openjpa.DetachState</literal> option is actually a + plugin string (see <xref linkend="ref_guide_conf_plugins"/>) that + allows you to also configure the following options related to + detached state: + </para> + <itemizedlist> + <listitem> + <para><literal>DetachedStateField</literal>: As described in + <xref linkend="ref_guide_attach_behavior"/> above, OpenJPA can + take advantage of a <emphasis>detached state field + </emphasis> to make the attach process more efficient. + This field is added by the enhancer and is not visible to + your application. Set this property to one of the + following values: + </para> + <itemizedlist> + <listitem> + <para><literal>transient</literal>: Use a transient + detached state field. This gives the benefits of + a detached state field to local objects that are + never serialized, but retains + serialization compatibility for client tiers without + access to the enhanced versions of your classes. + This is the default. + </para> + </listitem> + <listitem> + <para><literal>true</literal>: Use a non-transient + detached state field so that objects crossing + serialization barriers can still be attached + efficiently. This requires, however, that your + client tier have the enhanced versions of your + classes and the OpenJPA libraries. + </para> + </listitem> + <listitem> + <para><literal>false</literal>: Do not use a detached + state field. + </para> + </listitem> + </itemizedlist> + <para> + You can override the setting of this property or declare + your own detached state field on individual classes using + OpenJPA's metadata extensions. See + <xref linkend="ref_guide_detach_field"/> below. + </para> + </listitem> + <listitem> + <para><literal>DetachedStateManager</literal>: Whether to use a + detached state manager. A detached state manager makes + attachment much more efficient. Like a detached state + field, however, it breaks serialization compatibility with + the unenhanced class if it isn't transient. + </para> + <para> + This setting piggybacks on the <literal>DetachedStateField + </literal> setting above. If your detached state field is + transient, the detached state manager will also be + transient. If the detached state field is disabled, the + detached state manager will also be disabled. This is + typically what you'll want. By setting <literal> + DetachedStateField</literal> to true (or transient) and + setting this property to false, however, you can use a + detached state field <emphasis role="bold">without + </emphasis> using a detached state manager. This may be + useful for debugging or for legacy OpenJPA users who find + differences between OpenJPA's behavior with a detached state + manager and OpenJPA's older behavior without one. + </para> + </listitem> + <listitem> + <para><literal>AccessUnloaded</literal>: Whether to allow access + to unloaded fields of detached objects. Defaults to true. + Set to false to throw an exception whenever an unloaded + field is accessed. This option is only available when you + use detached state managers, as determined by the settings + above. + </para> + </listitem> + </itemizedlist> + <example id="ref_guide_detach_graph_confex"> + <title>Configuring Detached State</title> + <programlisting format="linespecific"> +<property name="openjpa.DetachState" value="fgs(DetachedStateField=true)"/> +</programlisting> + </example> + <para> + You can also alter the set of fields that will be included in the + detached graph at runtime. + <ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html"><classname>OpenJPAEntityManager</classname></ulink>s expose the + following APIs for controlling detached state: + </para> + <programlisting format="linespecific"> +public static final int DETACH_LOADED; +public static final int DETACH_FGS; +public static final int DETACH_ALL; +public int getDetachState (); +public void setDetachState (int mode); +</programlisting> + <section id="ref_guide_detach_field"> + <title>Detached State Field</title> + <indexterm zone="ref_guide_detach_field"> + <primary>detachment</primary> + <secondary>detached state field</secondary> + </indexterm> + <para> + When the detached state field is enabled, the OpenJPA enhancer + adds an additional field to the enhanced version of your class. + This field of type <classname>Object</classname>. OpenJPA uses + this field for bookkeeping information, such as the versioning + data needed to detect optimistic concurrency violations when the + object is re-attached. + </para> + <para> + It is possible to define this detached state field yourself. + Declaring this field in your class metadata prevents the + enhancer from adding any extra fields to the class, and keeps + the enhanced class serialization-compatible with + the unenhanced version. + The detached state field must not be persistent. + See <xref linkend="detached-state-field"/> for details on + how to declare a detached state field. + </para> + <programlisting format="linespecific"> +import org.apache.openjpa.persistence.*; + [EMAIL PROTECTED] +public class Magazine + implements Serializable +{ + private String name; + @DetachedState private Object state; + ... +} +</programlisting> + </section> + </section> + </section> + <section id="ref_guide_event"> + <title>Remote Event Notification Framework</title> + <indexterm zone="ref_guide_event"> + <primary>remote</primary> + <secondary>events</secondary> + </indexterm> + <indexterm> + <primary>events</primary> + <secondary>remote</secondary> + <see>remote, events</see> + </indexterm> + <para><indexterm><primary>remote</primary><secondary>events</secondary><tertiary>RemoteCommitProvider</tertiary></indexterm><indexterm><primary>remote</primary><secondary>events</secondary><tertiary>RemoteCommitListener</tertiary></indexterm> + The remote event notification framework allows a subset of the + information available through OpenJPA's transaction events (see + <xref linkend="ref_guide_runtime_pm_event"/>) to be broadcast to remote + listeners. OpenJPA's <link linkend="ref_guide_cache">data cache</link>, for + example, uses remote events to remain synchronized when deployed in + multiple JVMs. + </para> + + <para> + To enable remote events, you must configure the <classname> + EntityManagerFactory</classname> to use a + <literal>RemoteCommitProvider</literal> (see below). + </para> + <para> + When a <literal>RemoteCommitProvider</literal> is properly configured, you + can register <ulink url="../apidocs/org/apache/openjpa/event/RemoteCommitListener.html"><classname>RemoteCommitListener</classname></ulink>s that will be alerted + with a list of modified object ids whenever a transaction on a remote + machine successfully commits. + </para> + <section id="ref_guide_event_conf"> + <title>Remote Commit Provider Configuration</title> + <indexterm zone="ref_guide_event_conf"> + <primary>remote</primary> + <secondary>events</secondary> + <tertiary>configuration</tertiary> + </indexterm> + <para> + OpenJPA includes built in remote commit providers for JMS and TCP + communication. + </para> + <section id="ref_guide_event_conf_jms"> + <title>JMS</title> + <indexterm zone="ref_guide_event_conf_jms"> + <primary>remote</primary> + <secondary>events</secondary> + <tertiary>JMS</tertiary> + </indexterm> + <para> + OpenJPA includes built in remote commit providers for JMS and TCP + communication. The JMS remote commit provider can be configured by + setting the <link linkend="openjpa.RemoteCommitProvider"><literal> + openjpa.RemoteCommitProvider</literal></link> property + to contain the appropriate configuration properties. The JMS + provider understands the following properties: + </para> + <itemizedlist> + <listitem> + <para><literal>Topic</literal>: The topic that the remote commit + provider should publish notifications to and subscribe + to for notifications sent from other JVMs. Defaults to + <literal>topic/OpenJPACommitProviderTopic</literal></para> + </listitem> + <listitem> + <para><literal>TopicConnectionFactory</literal>: The JNDI name of + a <classname>javax.jms.TopicConnectionFactory</classname> + factory to use for finding topics. Defaults to <literal> + java:/ConnectionFactory</literal>. This setting may + vary depending on the application server in use; consult + the application server's documentation for details + of the default JNDI name for the + <classname>javax.jms.TopicConnectionFactory</classname> + instance. For example, under Weblogic, the JNDI name + for the TopicConnectionFactory is + <literal>javax.jms.TopicConnectionFactory</literal>. + </para> + </listitem> + <listitem> + <para><literal>ExceptionReconnectAttempts</literal>: The number of + times to attempt to reconnect if the JMS system notifies + OpenJPA of a serious connection error. Defaults to 0, meaning + OpenJPA will log the error but otherwise ignore it, hoping the + connection is still valid. + </para> + </listitem> + <listitem> + <para><literal>*</literal>: All other configuration properties + will be interpreted as settings to pass to the JNDI + <classname>InitialContext</classname> on construction. For + example, you might set the <literal>java.naming.provider.url + </literal> property to the URL of the context provider. + </para> + </listitem> + </itemizedlist> + <para> + To configure a factory to use the JMS provider, your properties + might look like the following: + </para> + <note> + <para> + Because of the nature of JMS, it is important that you invoke + <methodname>EntityManagerFactory.close</methodname> + when finished with a factory. If you do not do so, a daemon + thread will stay up in the JVM, preventing the JVM from exiting. + </para> + </note> + </section> + <section id="ref_guide_event_conf_tcp"> + <title>TCP</title> + <indexterm zone="ref_guide_event_conf_tcp"> + <primary>remote</primary> + <secondary>events</secondary> + <tertiary>TCP</tertiary> + </indexterm> + <para> + The TCP remote commit provider has several options that are + defined as host specifications containing a host name or IP + address and an optional port separated by a colon. For example, + the host specification <literal>saturn.bea.com:1234</literal> + represents an <classname>InetAddress</classname> retrieved by + invoking <methodname>InetAddress.getByName ("saturn.bea.com") + </methodname> and a port of 1234. + </para> + <para><indexterm><primary>TCP provider</primary></indexterm> + The TCP provider can be configured by setting the <literal> + openjpa.RemoteCommitProvider</literal> plugin property to contain the + appropriate configuration settings. The TCP provider understands the + following properties: + </para> + <itemizedlist> + <listitem> + <para><literal>Port</literal>: The TCP port that the provider + should listen on for commit notifications. Defaults to + 5636. + </para> + </listitem> + <listitem> + <para><literal>Addresses</literal>: A semicolon-separated list of + IP addresses to which notifications should be sent. No + default value. + </para> + </listitem> + <listitem> + <para><literal>NumBroadcastThreads</literal>: The number of + threads to create for the purpose of transmitting events to + peers. You sould increase this value as the number of + concurrent transactions increases. The maximum number of + concurrent transactions is a function of the size of the + connection pool. See the the <literal>MaxActive</literal> + property of + <literal>openjpa.ConnectionFactoryProperties</literal> in + <xref linkend="ref_guide_dbsetup_builtin"/>. + Setting a value of 0 will result in behavior where the + thread invoking <methodname>commit</methodname> will + perform the broadcast directly. Defaults to 2. + </para> + </listitem> + <listitem> + <para><literal>RecoveryTimeMillis</literal>: Amount of time to + wait in milliseconds before attempting to reconnect to a + peer of the cluster when connectivity to the peer is lost. + Defaults to 15000. + </para> + </listitem> + <listitem> + <para><literal>MaxIdle</literal>: The number of TCP sockets + (channels) to keep open to each peer in the cluster for + the transmission of events. Defaults to 2. + </para> + </listitem> + <listitem> + <para><literal>MaxActive</literal>: The maximum allowed number + of TCP sockets (channels) to open simultaneously + between each peer in the cluster. + Defaults to 2. + </para> + </listitem> + </itemizedlist> + <para> + To configure a factory to use the TCP provider, your properties + might look like the following: + </para> + <example id="ref_guide_event_conf_tcpex"> + <title>TCP Remote Commit Provider Configuration</title> + <programlisting format="linespecific"> +<property name="openjpa.RemoteCommitProvider" + value="tcp(Addresses=10.0.1.10;10.0.1.11;10.0.1.12;10.0.1.13)"/> +</programlisting> + </example> + </section> + <section id="ref_guide_event_conf_common"> + <title>Common Properties</title> + <indexterm zone="ref_guide_event_conf_common"> + <primary>remote</primary> + <secondary>events</secondary> + <tertiary>common properties</tertiary> + </indexterm> + <para> + In addition to the provider-specific configuration options above, + all providers accept the following plugin properties: + </para> + <itemizedlist> + <listitem> + <para><literal>TransmitPersistedObjectIds</literal>: Whether + remote commit events will include the object ids of + instances persisted in the transaction. By default only + the class names of types persisted in the transaction are + sent. This results in smaller events and more efficient + network utilization. If you have registered your own + remote commit listeners, however, you may require the + persisted object ids as well. + </para> + </listitem> + </itemizedlist> + <para> + To transmit persisted object ids in our remote commit events + using the JMS provider, we modify the previous example as follows: + </para> + </section> + </section> + <section id="ref_guide_event_customization"> + <title>Customization</title> + <indexterm zone="ref_guide_event_customization"> + <primary>remote</primary> + <secondary>events</secondary> + <tertiary>customization</tertiary> + </indexterm> + <para> + You can develop additional mechanisms for remote event notification be + by creating an implementation of the + <ulink url="../apidocs/org/apache/openjpa/event/RemoteCommitProvider.html"><classname> + RemoteCommitProvider</classname></ulink> interface, possibly by + extending the + <ulink url="../apidocs/org/apache/openjpa/event/AbstractRemoteCommitProvider.html"><classname>AbstractRemoteCommitProvider</classname></ulink> + abstract class. For details on particular customization needs, + contact us at <ulink url="mailto:[EMAIL PROTECTED]"> + [EMAIL PROTECTED]</ulink>. + </para> + </section> + </section> + </chapter>
