| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>6. Persistent Fields</title><base href="display"><link rel="stylesheet" type="text/css" href="css/docbook.css"><meta name="generator" content="DocBook XSL-NS Stylesheets V1.76.1"><link rel="home" href="manual.html" title="Apache OpenJPA 2.2 User's Guide"><link rel="up" href="ref_guide_pc.html" title="Chapter 5. Persistent Classes"><link rel="prev" href="ref_guide_inverses.html" title="5. Managed Inverses"><link rel="next" href="ref_guide_fetch.html" title="7. Fetch Groups"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">6. |
| Persistent Fields |
| </th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ref_guide_inverses.html">Prev</a> </td><th width="60%" align="center">Chapter 5. |
| Persistent Classes |
| </th><td width="20%" align="right"> <a accesskey="n" href="ref_guide_fetch.html">Next</a></td></tr></table><hr></div><div class="section" title="6. Persistent Fields"><div class="titlepage"><div><div><h2 class="title" style="clear: both" id="ref_guide_pc_scos">6. |
| Persistent Fields |
| </h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_scos_restore">6.1. |
| Restoring State |
| </a></span></dt><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_scos_order">6.2. |
| Typing and Ordering |
| </a></span></dt><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_calendar_timezone">6.3. |
| Calendar Fields and TimeZones |
| </a></span></dt><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_scos_proxy">6.4. |
| Proxies |
| </a></span></dt><dd><dl><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_scos_proxy_smart">6.4.1. |
| Smart Proxies |
| </a></span></dt><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_scos_proxy_lrs">6.4.2. |
| Large Result Set Proxies |
| </a></span></dt><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_scos_proxy_custom">6.4.3. |
| Custom Proxies |
| </a></span></dt><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_scos_proxy_serial">6.4.4. |
| Serialization |
| </a></span></dt></dl></dd><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_extern">6.5. |
| Externalization |
| </a></span></dt><dd><dl><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_extern_values">6.5.1. |
| External Values |
| </a></span></dt></dl></dd></dl></div> |
| |
| <a class="indexterm" name="d5e12372"></a> |
| <p> |
| OpenJPA enhances the specification's support for persistent fields in many ways. |
| This section documents aspects of OpenJPA's persistent field handling that may |
| affect the way you design your persistent classes. |
| </p> |
| <div class="section" title="6.1. Restoring State"><div class="titlepage"><div><div><h3 class="title" id="ref_guide_pc_scos_restore">6.1. |
| Restoring State |
| </h3></div></div></div> |
| |
| <a class="indexterm" name="d5e12377"></a> |
| <a class="indexterm" name="d5e12380"></a> |
| <p> |
| While the JPA specification says that you should not use rolled back objects, |
| such objects are perfectly valid in OpenJPA. You can control whether the |
| objects' managed state is rolled back to its pre-transaction values with the |
| <a class="link" href="ref_guide_conf_openjpa.html#openjpa.RestoreState" title="5.62. openjpa.RestoreState"><code class="literal">openjpa.RestoreState</code> |
| </a> configuration property. <code class="literal">none</code> does not roll back state |
| (the object becomes hollow, and will re-load its state the next time it is |
| accessed), <code class="literal">immutable</code> restores immutable values (primitives, |
| primitive wrappers, strings) and clears mutable values so that they are reloaded |
| on next access, and <code class="literal">all</code> restores all managed values to their |
| pre-transaction state. |
| </p> |
| </div> |
| <div class="section" title="6.2. Typing and Ordering"><div class="titlepage"><div><div><h3 class="title" id="ref_guide_pc_scos_order">6.2. |
| Typing and Ordering |
| </h3></div></div></div> |
| |
| <a class="indexterm" name="d5e12390"></a> |
| <p> |
| When loading data into a field, OpenJPA examines the value you assign the field |
| in your declaration code or in your no-args constructor. If the field value's |
| type is more specific than the field's declared type, OpenJPA uses the value |
| type to hold the loaded data. OpenJPA also uses the comparator you've |
| initialized the field with, if any. Therefore, you can use custom comparators on |
| your persistent field simply by setting up the comparator and using it in your |
| field's initial value. |
| </p> |
| <div class="example"><a name="ref_guide_pc_scos_order_initialvals"></a><p class="title"><b>Example 5.12. |
| Using Initial Field Values |
| </b></p><div class="example-contents"> |
| |
| <p> |
| Though the annotations are left out for simplicity, assume <code class="literal"> |
| employeesBySal</code> and <code class="literal">departments</code> are persistent |
| fields in the class below. |
| </p> |
| <pre class="programlisting"> |
| public class Company { |
| |
| // OpenJPA will detect the custom comparator in the initial field value |
| // and use it whenever loading data from the database into this field |
| private Collection employeesBySal = new TreeSet(new SalaryComparator()); |
| private Map departments; |
| |
| public Company { |
| // or we can initialize fields in our no-args constructor; even though |
| // this field is declared type Map, OpenJPA will detect that it's |
| // actually a TreeMap and use natural ordering for loaded data |
| departments = new TreeMap(); |
| } |
| |
| // rest of class definition... |
| } |
| </pre> |
| </div></div><br class="example-break"> |
| </div> |
| <div class="section" title="6.3. Calendar Fields and TimeZones"><div class="titlepage"><div><div><h3 class="title" id="ref_guide_pc_calendar_timezone">6.3. |
| Calendar Fields and TimeZones |
| </h3></div></div></div> |
| |
| <a class="indexterm" name="d5e12402"></a> |
| <p> |
| OpenJPA's support for the <code class="classname">java.util.Calendar</code> type will |
| store only the <code class="classname">Date</code> part of the field, not the |
| <code class="classname">TimeZone</code> associated with the field. When loading the date |
| into the <code class="classname">Calendar</code> field, OpenJPA will use the <code class="classname"> |
| TimeZone</code> that was used to initialize the field. |
| </p> |
| </div> |
| <div class="section" title="6.4. Proxies"><div class="titlepage"><div><div><h3 class="title" id="ref_guide_pc_scos_proxy">6.4. |
| Proxies |
| </h3></div></div></div><div class="toc"><dl><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_scos_proxy_smart">6.4.1. |
| Smart Proxies |
| </a></span></dt><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_scos_proxy_lrs">6.4.2. |
| Large Result Set Proxies |
| </a></span></dt><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_scos_proxy_custom">6.4.3. |
| Custom Proxies |
| </a></span></dt><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_scos_proxy_serial">6.4.4. |
| Serialization |
| </a></span></dt></dl></div> |
| |
| <a class="indexterm" name="d5e12413"></a> |
| <a class="indexterm" name="d5e12415"></a> |
| <p> |
| At runtime, the values of all mutable second class object fields in persistent |
| and transactional objects are replaced with implementation-specific proxies. On |
| modification, these proxies notify their owning instance that they have been |
| changed, so that the appropriate updates can be made on the datastore. |
| </p> |
| <div class="section" title="6.4.1. Smart Proxies"><div class="titlepage"><div><div><h4 class="title" id="ref_guide_pc_scos_proxy_smart">6.4.1. |
| Smart Proxies |
| </h4></div></div></div> |
| |
| <a class="indexterm" name="d5e12422"></a> |
| <p> |
| Most proxies only track whether or not they have been modified. Smart proxies |
| for collection and map fields, however, keep a record of which elements have |
| been added, removed, and changed. This record enables the OpenJPA runtime to |
| make more efficient database updates on these fields. |
| </p> |
| <p> |
| When designing your persistent classes, keep in mind that you can optimize for |
| OpenJPA smart proxies by using fields of type <code class="classname">java.util.Set |
| </code>, <code class="classname">java.util.TreeSet</code>, and <code class="classname"> |
| java.util.HashSet</code> for your collections whenever possible. Smart |
| proxies for these types are more efficient than proxies for <code class="classname"> |
| List</code>s. You can also design your own smart proxies to further |
| optimize OpenJPA for your usage patterns. See the section on |
| <a class="link" href="ref_guide_pc_scos.html#ref_guide_pc_scos_proxy_custom" title="6.4.3. Custom Proxies">custom proxies</a> for |
| details. |
| </p> |
| </div> |
| <div class="section" title="6.4.2. Large Result Set Proxies"><div class="titlepage"><div><div><h4 class="title" id="ref_guide_pc_scos_proxy_lrs">6.4.2. |
| Large Result Set Proxies |
| </h4></div></div></div> |
| |
| <a class="indexterm" name="d5e12434"></a> |
| <a class="indexterm" name="d5e12437"></a> |
| <p> |
| Under standard ORM behavior, traversing a persistent collection or map field |
| brings the entire contents of that field into memory. Some persistent fields, |
| however, might represent huge amounts of data, to the point that attempting to |
| fully instantiate them can overwhelm the JVM or seriously degrade performance. |
| </p> |
| <p> |
| OpenJPA uses special proxy types to represent these "large result set" fields. |
| OpenJPA's large result set proxies do not cache any data in memory. Instead, |
| each operation on the proxy offloads the work to the database and returns the |
| proper result. For example, the <code class="methodname">contains</code> method of a |
| large result set collection will perform a <code class="literal"> SELECT COUNT(*)</code> |
| query with the proper <code class="literal">WHERE</code> conditions to find out if the |
| given element exists in the database's record of the collection. Similarly, each |
| time you obtain an iterator OpenJPA performs the proper query using the current |
| <a class="link" href="ref_guide_dbsetup_lrs.html" title="10. Large Result Sets">large result set settings</a>, as |
| discussed in the <a class="link" href="ref_guide_dbsetup.html" title="Chapter 4. JDBC">JDBC</a> chapter. As you |
| invoke <code class="methodname">Iterator.next</code>, OpenJPA instantiates the result |
| objects on-demand. |
| </p> |
| <p> |
| You can free the resources used by a large result set iterator by passing it to |
| the static <a class="link" href="ref_guide_runtime_jpa.html#ref_guide_runtime_openjpapersistence" title="2.9. OpenJPAPersistence"><code class="methodname"> |
| OpenJPAPersistence.close</code></a> method. |
| </p> |
| <div class="example"><a name="ref_guide_pc_scos_proxy_lrs_itr"></a><p class="title"><b>Example 5.13. |
| Using a Large Result Set Iterator |
| </b></p><div class="example-contents"> |
| |
| <pre class="programlisting"> |
| import org.apache.openjpa.persistence.*; |
| |
| ... |
| |
| Collection employees = company.getEmployees(); // employees is a lrs collection |
| Iterator itr = employees.iterator(); |
| while (itr.hasNext()) |
| process((Employee) itr.next()); |
| OpenJPAPersistence.close(itr); |
| </pre> |
| </div></div><br class="example-break"> |
| <p> |
| You can also add and remove from large result set proxies, just as with standard |
| fields. OpenJPA keeps a record of all changes to the elements of the proxy, |
| which it uses to make sure the proper results are always returned from |
| collection and map methods, and to update the field's database record on commit. |
| </p> |
| <p> |
| In order to use large result set proxies in JPA, add the |
| <a class="ulink" href="../javadoc/org/apache/openjpa/persistence/LRS.html" target="_top"><code class="classname"> |
| org.apache.openjpa.persistence.LRS</code></a> annotation to the |
| persistent field. |
| </p> |
| <p> |
| The following restrictions apply to large result set fields: |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> |
| <p> |
| The field must be declared as either a <code class="classname">java.util.Collection |
| </code> or <code class="classname">java.util.Map</code>. It cannot be declared as |
| any other type, including any sub-interface of collection or map, or any |
| concrete collection or map class. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| The field cannot have an externalizer (see |
| <a class="xref" href="ref_guide_pc_scos.html#ref_guide_pc_extern" title="6.5. Externalization">Section 6.5, “ |
| Externalization |
| ”</a>). |
| </p> |
| </li><li class="listitem"> |
| <p> |
| Because they rely on their owning object for context, large result set proxies |
| cannot be transferred from one persistent field to another. The following code |
| would result in an error on commit: |
| </p> |
| <pre class="programlisting"> |
| Collection employees = company.getEmployees() // employees is a lrs collection |
| company.setEmployees(null); |
| anotherCompany.setEmployees(employees); |
| </pre> |
| </li></ul></div> |
| <div class="example"><a name="ref_guide_pc_scos_proxy_lrs_extension"></a><p class="title"><b>Example 5.14. |
| Marking a Large Result Set Field |
| </b></p><div class="example-contents"> |
| |
| <pre class="programlisting"> |
| import org.apache.openjpa.persistence.*; |
| |
| @Entity |
| public class Company { |
| |
| @ManyToMany |
| @LRS private Collection<Employee> employees; |
| |
| ... |
| } |
| </pre> |
| </div></div><br class="example-break"> |
| </div> |
| <div class="section" title="6.4.3. Custom Proxies"><div class="titlepage"><div><div><h4 class="title" id="ref_guide_pc_scos_proxy_custom">6.4.3. |
| Custom Proxies |
| </h4></div></div></div> |
| |
| <a class="indexterm" name="d5e12475"></a> |
| <a class="indexterm" name="d5e12478"></a> |
| <p> |
| OpenJPA manages proxies through the |
| <a class="ulink" href="../javadoc/org/apache/openjpa/util/ProxyManager.html" target="_top"><code class="classname"> |
| org.apache.openjpa.util.ProxyManager</code></a> interface. OpenJPA |
| includes a default proxy manager, the <code class="classname"> |
| org.apache.openjpa.util.ProxyManagerImpl</code> (with a plugin alias name |
| of <code class="literal">default</code>), that will meet the needs of most users. The |
| default proxy manager understands the following configuration properties: |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> |
| <p> |
| <code class="literal">TrackChanges</code>: Whether to use |
| <a class="link" href="ref_guide_pc_scos.html#ref_guide_pc_scos_proxy_smart" title="6.4.1. Smart Proxies">smart proxies</a>. Defaults to |
| <code class="literal">true</code>. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| <code class="literal">AssertAllowedType</code>: Whether to immediately throw an exception |
| if you attempt to add an element to a collection or map that is not assignable |
| to the element type declared in metadata. Defaults to <code class="literal">false</code>. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| <code class="literal">DelayCollectionLoading</code>: Whether to delay loading elements of a |
| lazily loaded collection. Delay loading allows non-indexed add and remove |
| operations to occur without prior loading of the collection from the data store. This can |
| improve performance of some applications by allowing them to perform simple add or remove |
| operations on collections without requiring them to be loaded. Delayed proxies are |
| loaded when an operation is performed that requires loading, such |
| as iteration, size, serialization, and indexOf. They can also be loaded by casting the |
| proxy to a <a class="ulink" href="../javadoc/org/apache/openjpa/util/DelayedProxy.html" target="_top"><code class="classname"> |
| org.apache.openjpa.util.DelayedProxy</code></a> and invoking the |
| <code class="methodname">load</code> method. If a broker factory is available after detaching the owning |
| entity, a collection may be available for delayed loading after the persistence context has been |
| cleared. In post-detachment, entities that are loaded are not associated with a persistence context. |
| Defaults to <code class="literal">false</code>. |
| </p> |
| </li></ul></div> |
| <p> |
| The default proxy manager can proxy the standard methods of any |
| <code class="classname">Collection</code>, <code class="classname">List</code>, |
| <code class="classname">Map</code>, <code class="classname">Queue</code>, |
| <code class="classname">Date</code>, or <code class="classname">Calendar</code> class, |
| including custom implementations. It can also proxy custom classes whose |
| accessor and mutator methods follow JavaBean naming conventions. Your custom |
| types must, however, meet the following criteria: |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> |
| <p> |
| Custom container types must have a public no-arg constructor or a public |
| constructor that takes a single <code class="classname">Comparator</code> parameter. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| Custom date types must have a public no-arg constructor or a public |
| constructor that takes a single <code class="classname">long</code> parameter |
| representing the current time. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| Other custom types must have a public no-arg constructor or a public copy |
| constructor. If a custom types does not have a copy constructor, it must be |
| possible to fully copy an instance A by creating a new instance B and calling |
| each of B's setters with the value from the corresponding getter on A. |
| </p> |
| </li></ul></div> |
| <p> |
| If you have custom classes that must be proxied and do not meet these |
| requirements, OpenJPA allows you to define your own proxy classes and |
| your own proxy manager. See the <code class="literal">openjpa.util</code> package |
| <a class="ulink" href="../javadoc/" target="_top">Javadoc</a> for details on the interfaces involved, |
| and the utility classes OpenJPA provides to assist you. |
| </p> |
| <p> |
| You can plug your custom proxy manager into the OpenJPA runtime through the |
| <a class="link" href="ref_guide_conf_openjpa.html#openjpa.ProxyManager" title="5.56. openjpa.ProxyManager"><code class="literal"> openjpa.ProxyManager</code> |
| </a> configuration property. |
| </p> |
| <div class="example"><a name="ref_guide_pc_scos_proxy_custom_ex"></a><p class="title"><b>Example 5.15. |
| Configuring the Proxy Manager |
| </b></p><div class="example-contents"> |
| |
| <pre class="programlisting"> |
| <property name="openjpa.ProxyManager" value="TrackChanges=false"/> |
| </pre> |
| </div></div><br class="example-break"> |
| </div> |
| <div class="section" title="6.4.4. Serialization"><div class="titlepage"><div><div><h4 class="title" id="ref_guide_pc_scos_proxy_serial">6.4.4. |
| Serialization |
| </h4></div></div></div> |
| |
| <a class="indexterm" name="d5e12530"></a> |
| <a class="indexterm" name="d5e12533"></a> |
| <p> |
| When objects are serialized, the <code class="literal">DetachedStateField</code> in |
| section <a class="xref" href="ref_guide_remote.html#ref_guide_detach_state" title="1.3.1. Detached State">Section 1.3.1, “ |
| Detached State |
| ”</a> |
| will be used to help determine when build time proxies will be removed. |
| If runtime created proxies are being used (proxies not supplied by OpenJPA) |
| or if an entity has already been detached, then any found proxies will be |
| removed during serialization. |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"> |
| <p> |
| <code class="literal">transient</code>: 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 or the OpenJPA runtime. |
| All proxies will be removed during serialization. This is the default. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| <code class="literal">true</code>: 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 runtime. |
| No OpenJPA provided proxies will be removed during serialization. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| <code class="literal">false</code>: Do not use a detached state field. |
| All proxies will be removed during serialization. |
| </p> |
| </li></ul></div> |
| </div> |
| </div> |
| <div class="section" title="6.5. Externalization"><div class="titlepage"><div><div><h3 class="title" id="ref_guide_pc_extern">6.5. |
| Externalization |
| </h3></div></div></div><div class="toc"><dl><dt><span class="section"><a href="ref_guide_pc_scos.html#ref_guide_pc_extern_values">6.5.1. |
| External Values |
| </a></span></dt></dl></div> |
| |
| <a class="indexterm" name="d5e12551"></a> |
| <a class="indexterm" name="d5e12553"></a> |
| <p> |
| OpenJPA offers the ability to write |
| <a class="link" href="ref_guide_mapping_custom.html#ref_guide_mapping_custom_field" title="10.3. Custom Field Mapping">custom field mappings</a> in |
| order to have complete control over the mechanism with which fields are stored, |
| queried, and loaded from the datastore. Often, however, a custom mapping is |
| overkill. There is often a simple transformation from a Java field value to its |
| database representation. Thus, OpenJPA provides the externalization service. |
| Externalization allows you to specify methods that will externalize a field |
| value to its database equivalent on store and then rebuild the value from its |
| externalized form on load. |
| </p> |
| <div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3> |
| <p> |
| Fields of embeddable classes used for <code class="literal">@EmbeddedId</code> values in |
| JPA cannot have externalizers. |
| </p> |
| </div> |
| <p> |
| The OpenJPA |
| <a class="ulink" href="../javadoc/org/apache/openjpa/persistence/Externalizer.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.Externalizer</code></a> |
| annotation sets the name of a method that will be invoked to convert |
| the field into its external form for database storage. You can specify either |
| the name of a non-static method, which will be invoked on the field value, or a |
| static method, which will be invoked with the field value as a parameter. Each |
| method can also take an optional |
| <a class="ulink" href="../javadoc/org/apache/openjpa/kernel/StoreContext.html" target="_top"><code class="classname"> |
| StoreContext</code></a> parameter for access to a persistence context. |
| The return value of the method is the field's external form. By default, OpenJPA |
| assumes that all named methods belong to the field value's class (or its |
| superclasses). You can, however, specify static methods of other classes using |
| the format <code class="literal"><class-name>.<method-name></code>. |
| </p> |
| <p> |
| Given a field of type <code class="classname">CustomType</code> that externalizes to a |
| string, the table below demonstrates several possible externalizer methods and |
| their corresponding metadata extensions. |
| </p> |
| <div class="table"><a name="d5e12570"></a><p class="title"><b>Table 5.1. |
| Externalizer Options |
| </b></p><div class="table-contents"> |
| |
| <table summary="
 Externalizer Options
 " border="1"><colgroup><col align="left" class="method"><col align="left" class="extension"></colgroup><thead><tr><th align="left"> |
| Method |
| </th><th align="left"> |
| Extension |
| </th></tr></thead><tbody><tr><td align="left"> |
| <code class="literal"> |
| public String CustomType.toString() |
| </code> |
| </td><td align="left"> |
| <code class="literal"> |
| @Externalizer("toString") |
| </code> |
| </td></tr><tr><td align="left"> |
| <code class="literal"> |
| public String CustomType.toString(StoreContext ctx) |
| </code> |
| </td><td align="left"> |
| <code class="literal"> |
| @Externalizer("toString") |
| </code> |
| </td></tr><tr><td align="left"> |
| <code class="literal"> |
| public static String AnyClass.toString(CustomType ct) |
| </code> |
| </td><td align="left"> |
| <code class="literal"> |
| @Externalizer("AnyClass.toString") |
| </code> |
| </td></tr><tr><td align="left"> |
| <code class="literal"> |
| public static String AnyClass.toString(CustomType ct, StoreContext ctx) |
| </code> |
| </td><td align="left"> |
| <code class="literal"> |
| @Externalizer("AnyClass.toString") |
| </code> |
| </td></tr></tbody></table> |
| </div></div><br class="table-break"> |
| <p> |
| The OpenJPA |
| <a class="ulink" href="../javadoc/org/apache/openjpa/persistence/Factory.html" target="_top"><code class="classname"> |
| org.apache.openjpa.persistence.Factory</code></a> annotation |
| contains the name of a method that will be invoked to instantiate the field from |
| the external form stored in the database. Specify a static method name. The |
| method will be invoked with the externalized value and must return an |
| instance of the field type. The method can also take an optional |
| <a class="ulink" href="../javadoc/org/apache/openjpa/kernel/StoreContext.html" target="_top"><code class="classname"> |
| StoreContext</code></a> parameter for access to a persistence context. |
| If a factory is not specified, OpenJPA will use the constructor of the field |
| type that takes a single argument of the external type, or will throw an |
| exception if no constructor with that signature exists. |
| </p> |
| <p> |
| Given a field of type <code class="classname">CustomType</code> that externalizes to a |
| string, the table below demonstrates several possible factory methods and their |
| corresponding metadata extensions. |
| </p> |
| <div class="table"><a name="d5e12607"></a><p class="title"><b>Table 5.2. |
| Factory Options |
| </b></p><div class="table-contents"> |
| |
| <table summary="
 Factory Options
 " border="1"><colgroup><col align="left" class="method"><col align="left" class="extension"></colgroup><thead><tr><th align="left"> |
| Method |
| </th><th align="left"> |
| Extension |
| </th></tr></thead><tbody><tr><td align="left"> |
| <code class="literal"> |
| public CustomType(String str) |
| </code> |
| </td><td align="left"> |
| none |
| </td></tr><tr><td align="left"> |
| <code class="literal"> |
| public static CustomType CustomType.fromString(String str) |
| </code> |
| </td><td align="left"> |
| <code class="literal"> |
| @Factory("fromString") |
| </code> |
| </td></tr><tr><td align="left"> |
| <code class="literal"> |
| public static CustomType CustomType.fromString(String str, StoreContext ctx) |
| </code> |
| </td><td align="left"> |
| <code class="literal"> |
| @Factory("fromString") |
| </code> |
| </td></tr><tr><td align="left"> |
| <code class="literal"> |
| public static CustomType AnyClass.fromString(String str) |
| </code> |
| </td><td align="left"> |
| <code class="literal"> |
| @Factory("AnyClass.fromString") |
| </code> |
| </td></tr><tr><td align="left"> |
| <code class="literal"> |
| public static CustomType AnyClass.fromString(String str, StoreContext ctx) |
| </code> |
| </td><td align="left"> |
| <code class="literal"> |
| @Factory("AnyClass.fromString") |
| </code> |
| </td></tr></tbody></table> |
| </div></div><br class="table-break"> |
| <p> |
| If your externalized field is not a standard persistent type, you must |
| explicitly mark it persistent. In OpenJPA, you can force a persistent field |
| by annotating it with <a class="link" href="ref_guide_meta_jpa.html#ref_guide_meta_jpa_persistent" title="3.3. Persistent Field Values"><code class="classname"> |
| org.apache.openjpa.persistence.Persistent</code></a> annotation. |
| </p> |
| <div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3> |
| <p> |
| If your custom field type is mutable and is not a standard collection, map, or |
| date class, OpenJPA will not be able to detect changes to the field. You must |
| mark the field dirty manually, or create a custom field proxy. |
| See |
| <a class="ulink" href="../javadoc/org/apache/openjpa/persistence/OpenJPAEntityManager.html" target="_top"> |
| <code class="methodname">OpenJPAEntityManager.dirty</code></a> for how to mark a |
| field dirty manually in JPA. |
| See <a class="xref" href="ref_guide_pc_scos.html#ref_guide_pc_scos_proxy" title="6.4. Proxies">Section 6.4, “ |
| Proxies |
| ”</a> for a discussion of proxies. |
| </p> |
| </div> |
| <p> |
| You can externalize a field to virtually any value that is supported by |
| OpenJPA's field mappings (embedded relations are the exception; you must declare |
| your field to be a persistence-capable type in order to embed it). This means |
| that a field can externalize to something as simple as a primitive, something as |
| complex as a collection or map of entities, or anything in |
| between. If you do choose to externalize to a collection or map, OpenJPA |
| recognizes a family of metadata extensions for specifying type information for the |
| externalized form of your fields - see <a class="xref" href="ref_guide_meta_ext.html#type" title="4.2.6. Type">Section 4.2.6, “ |
| Type |
| ”</a>. If the |
| external form of your field is an entity object or contains entities, OpenJPA |
| will correctly include the objects in its persistence-by-reachability |
| algorithms and its delete-dependent algorithms. |
| </p> |
| <p> |
| The example below demonstrates a few forms of externalization. |
| </p> |
| <div class="example"><a name="ref_guide_pc_externex"></a><p class="title"><b>Example 5.16. |
| Using Externalization |
| </b></p><div class="example-contents"> |
| |
| <pre class="programlisting"> |
| import org.apache.openjpa.persistence.*; |
| |
| @Entity |
| public class Magazine { |
| |
| // use Class.getName and Class.forName to go to/from strings |
| @Persistent |
| @Externalizer("getName") |
| @Factory("forName") |
| private Class cls; |
| |
| // use URL.getExternalForm for externalization. no factory; |
| // we can rely on the URL string constructor |
| @Persistent |
| @Externalizer("toExternalForm") |
| private URL url; |
| |
| // use our custom methods |
| @Persistent |
| @Externalizer("Magazine.authorsFromCustomType") |
| @Factory("Magazine.authorsToCustomType") |
| @ElementType(Author.class) |
| private CustomType customType; |
| |
| public static Collection authorsFromCustomType(CustomType customType) { |
| ... logic to pack custom type into a list of authors ... |
| } |
| |
| public static CustomType authorsToCustomType(Collection authors) { |
| ... logic to create custom type from a collection of authors ... |
| } |
| |
| ... |
| } |
| </pre> |
| </div></div><br class="example-break"> |
| <p> |
| <a class="indexterm" name="d5e12656"></a> |
| You can query externalized fields using parameters. Pass in a value of the field |
| type when executing the query. OpenJPA will externalize the parameter using the |
| externalizer method named in your metadata, and compare the externalized |
| parameter with the value stored in the database. As a shortcut, OpenJPA also |
| allows you to use parameters or literals of the field's externalized type in |
| queries, as demonstrated in the example below. |
| </p> |
| <div class="note" title="Note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3> |
| <p> |
| Currently, queries are limited to fields that externalize to a primitive, |
| primitive wrapper, string, or date types, due to constraints on query syntax. |
| </p> |
| </div> |
| <div class="example"><a name="ref_guide_pc_extern_queryex"></a><p class="title"><b>Example 5.17. |
| Querying Externalization Fields |
| </b></p><div class="example-contents"> |
| |
| <p> |
| Assume the <code class="classname">Magazine</code> class has the same fields as in the |
| previous example. |
| </p> |
| <pre class="programlisting"> |
| // you can query using parameters |
| Query q = em.createQuery("select m from Magazine m where m.url = :u"); |
| q.setParameter("u", new URL("http://www.solarmetric.com")); |
| List results = q.getResultList(); |
| |
| // or as a shortcut, you can use the externalized form directly |
| q = em.createQuery("select m from Magazine m where m.url = 'http://www.solarmetric.com'"); |
| results = q.getResultList(); |
| </pre> |
| </div></div><br class="example-break"> |
| <div class="section" title="6.5.1. External Values"><div class="titlepage"><div><div><h4 class="title" id="ref_guide_pc_extern_values">6.5.1. |
| External Values |
| </h4></div></div></div> |
| |
| <a class="indexterm" name="d5e12668"></a> |
| <p> |
| Externalization often takes simple constant values and transforms them to |
| constant values of a different type. An example would be storing a <code class="classname"> |
| boolean</code> field as a <code class="classname">char</code>, where <code class="literal">true |
| </code> and <code class="literal">false</code> would be stored in the database as |
| <code class="literal">'T'</code> and <code class="literal">'F'</code> respectively. |
| </p> |
| <p> |
| OpenJPA allows you to define these simple translations in metadata, so that the |
| field behaves as in <a class="link" href="ref_guide_pc_scos.html#ref_guide_pc_extern" title="6.5. Externalization">full-fledged |
| externalization</a> without requiring externalizer and factory methods. |
| External values supports translation of pre-defined simple types (primitives, |
| primitive wrappers, and Strings), to other pre-defined simple values. |
| </p> |
| <p> |
| Use the OpenJPA |
| <a class="ulink" href="../javadoc/org/apache/openjpa/persistence/ExternalValues.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.ExternalValues</code></a> |
| annotation to define external value translations. The values are |
| defined in a format similar to that of <a class="link" href="ref_guide_conf_plugins.html" title="4. Plugin Configuration"> |
| configuration plugins</a>, except that the value pairs represent Java and |
| datastore values. To convert the Java boolean values of <code class="literal">true</code> |
| and <code class="literal">false</code> to the character values <code class="literal">T</code> and |
| <code class="literal">F</code>, for example, you would use the extension value: <code class="literal"> |
| true=T,false=F</code>. |
| </p> |
| <p> |
| If the type of the datastore value is different from the field's type, use the |
| <a class="ulink" href="../javadoc/org/apache/openjpa/persistence/Type.html" target="_top"> |
| <code class="classname">org.apache.openjpa.persistence.Type</code></a> annotation |
| to define the datastore type. |
| </p> |
| <div class="example"><a name="externvalues_ex"></a><p class="title"><b>Example 5.18. |
| Using External Values |
| </b></p><div class="example-contents"> |
| |
| <p> |
| This example uses external value translation to transform a string field to an |
| integer in the database. |
| </p> |
| <pre class="programlisting"> |
| public class Magazine { |
| |
| @ExternalValues({"SMALL=5", "MEDIUM=8", "LARGE=10"}) |
| @Type(int.class) |
| private String sizeWidth; |
| |
| ... |
| } |
| </pre> |
| </div></div><br class="example-break"> |
| </div> |
| </div> |
| </div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ref_guide_inverses.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ref_guide_pc.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ref_guide_fetch.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5. |
| Managed Inverses |
| </td><td width="20%" align="center"><a accesskey="h" href="manual.html">Home</a></td><td width="40%" align="right" valign="top"> 7. |
| Fetch Groups |
| </td></tr></table></div></body></html> |