Author: curtisr7
Date: Wed Mar 3 19:20:57 2010
New Revision: 918643
URL: http://svn.apache.org/viewvc?rev=918643&view=rev
Log:
OPENJPA-1545: Adding new faster way to auto detach the entire persistence
context. Committing code changes, test, and doc.
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachLite.java
(with props)
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/DetachOptions.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetach.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomer.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomerInventory.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMItem.java
openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_remote.xml
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/DetachOptions.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/DetachOptions.java?rev=918643&r1=918642&r2=918643&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/DetachOptions.java
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/DetachOptions.java
Wed Mar 3 19:20:57 2010
@@ -33,6 +33,8 @@
private boolean _transient = true;
private boolean _manager = true;
private boolean _access = true;
+
+ private boolean _liteAutoDetach = false;
/**
* The {...@link DetachState} constant.
@@ -124,6 +126,22 @@
public void setAccessUnloaded(boolean val) {
_access = val;
}
+
+ /**
+ * Whether to use lite detachment when auto detaching. This setting only
applies when
+ * DetachState is set to loaded.
+ */
+ public void setLiteAutoDetach(boolean b) {
+ _liteAutoDetach = b;
+ }
+
+ /**
+ * Whether to use lite detachment when auto detaching. This setting only
applies when
+ * DetachState is set to loaded.
+ */
+ public boolean getLiteAutoDetach() {
+ return (getDetachState() & DETACH_LOADED) == 1 && _liteAutoDetach;
+ }
/**
* Detach loaded state.
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?rev=918643&r1=918642&r2=918643&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
Wed Mar 3 19:20:57 2010
@@ -3305,6 +3305,10 @@
}
private void detachAllInternal(OpCallbacks call) {
+ if(_conf.getDetachStateInstance().getLiteAutoDetach() == true){
+ detachAllInternalLite();
+ return;
+ }
Collection<StateManagerImpl> states = getManagedStates();
StateManagerImpl sm;
for (Iterator<StateManagerImpl> itr = states.iterator();
itr.hasNext();) {
@@ -3334,6 +3338,35 @@
}
}
+ private void detachAllInternalLite() {
+ Collection<StateManagerImpl> states = getManagedStates();
+ // TODO : should I call clear on old cache first? perhaps a memory
leak?
+ // Clear out all persistence context caches.
+ _cache = new ManagedCache(this);
+ if (_transCache != null) {
+ _transCache.clear();
+ }
+ if (_transAdditions != null) {
+ _transAdditions.clear();
+ }
+
+ // Detach all.
+ TransferFieldManager fm = new TransferFieldManager();
+ for (StateManagerImpl s : states) {
+ ClassMetaData cmd = s.getMetaData();
+ if (s.isPersistent() && cmd.isDetachable()) {
+ //Clean up an fields that are LargeResultSets.
+ for (FieldMetaData fmd : cmd.getLrsFields()) {
+ int index = fmd.getIndex();
+ fm.storeObjectField(index, null);
+ s.replaceField(s.getPersistenceCapable(), fm, index);
+ fm.clear();
+ }
+ s.unproxyFields();
+ s.getPersistenceCapable().pcReplaceStateManager(null);
+ }
+ }
+ }
public Object attach(Object obj, boolean copyNew, OpCallbacks call) {
if (obj == null)
return null;
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java?rev=918643&r1=918642&r2=918643&view=diff
==============================================================================
---
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
(original)
+++
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
Wed Mar 3 19:20:57 2010
@@ -212,6 +212,7 @@
private FieldMetaData[] _listingFields = null;
private FieldMetaData[] _allListingFields = null;
private FieldMetaData[] _allProxyFields = null;
+ private FieldMetaData[] _allLrsFields = null;
private FetchGroup[] _fgs = null;
private FetchGroup[] _customFGs = null;
private boolean _intercepting = false;
@@ -1015,6 +1016,26 @@
}
/**
+ * Return all large result set fields. Will never return null.
+ */
+ public FieldMetaData[] getLrsFields() {
+ if (_allLrsFields == null) {
+ // Make sure _allFields has been initialized
+ if (_allFields == null) {
+ getFields();
+ }
+ List<FieldMetaData> res = new ArrayList<FieldMetaData>();
+ for (FieldMetaData fmd : _allFields) {
+ if(fmd.isLRS()==true){
+ res.add(fmd);
+ }
+ }
+ _allLrsFields = res.toArray(new FieldMetaData[res.size()]);
+ }
+ return _allLrsFields;
+ }
+
+ /**
* Return all field metadata, including superclass fields.
*/
public FieldMetaData[] getFields() {
@@ -1262,6 +1283,7 @@
FieldMetaData fmd = _repos.newFieldMetaData(name, type, this);
clearFieldCache();
_fieldMap.put(name, fmd);
+
return fmd;
}
@@ -1642,6 +1664,7 @@
_allDFGFields = null;
_allPKFields = null;
_allProxyFields = null;
+ _allLrsFields = null;
_definedFields = null;
_listingFields = null;
_allListingFields = null;
Modified:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetach.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetach.java?rev=918643&r1=918642&r2=918643&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetach.java
(original)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetach.java
Wed Mar 3 19:20:57 2010
@@ -51,8 +51,8 @@
*
*/
public class TestDetach extends SingleEMFTestCase {
- private OpenJPAEntityManager em;
- private DMCustomer root;
+ OpenJPAEntityManager em;
+ DMCustomer root;
public void setUp() {
super.setUp(DMCustomer.class, DMCustomerInventory.class, DMItem.class,
Added:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachLite.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachLite.java?rev=918643&view=auto
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachLite.java
(added)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachLite.java
Wed Mar 3 19:20:57 2010
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.persistence.detachment;
+
+import org.apache.openjpa.conf.Compatibility;
+import org.apache.openjpa.enhance.PersistenceCapable;
+import org.apache.openjpa.persistence.detachment.model.DMCustomer;
+import org.apache.openjpa.persistence.detachment.model.DMCustomerInventory;
+import org.apache.openjpa.persistence.detachment.model.DMItem;
+
+public class TestDetachLite extends TestDetach {
+ public void setUp() {
+ super.setUp(
+ "openjpa.DetachState", "loaded(LiteAutoDetach=true)",
+ DMCustomer.class, DMCustomerInventory.class, DMItem.class,
+ CLEAR_TABLES
+ );
+
+ Compatibility compat =
emf.getConfiguration().getCompatibilityInstance();
+ compat.setCopyOnDetach(false);
+ compat.setFlushBeforeDetach(false);
+ em = emf.createEntityManager();
+ root = createData();
+ }
+
+ public void testCloseDetach() {
+ root = em.merge(root);
+ PersistenceCapable pc = (PersistenceCapable) root;
+ assertFalse(pc.pcIsDetached());
+ em.close();
+ assertTrue(pc.pcIsDetached());
+ // Make sure everything is detached and we can still use the Entity
+ for (DMCustomerInventory c : root.getCustomerInventories()) {
+ pc = (PersistenceCapable) c;
+ assertTrue(pc.pcIsDetached());
+ pc = (PersistenceCapable) c.getItem();
+ assertTrue(pc.pcIsDetached());
+
+ }
+ }
+}
Propchange:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/TestDetachLite.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomer.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomer.java?rev=918643&r1=918642&r2=918643&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomer.java
(original)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomer.java
Wed Mar 3 19:20:57 2010
@@ -26,6 +26,7 @@
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
+import javax.persistence.Version;
@Entity
public class DMCustomer {
@@ -35,6 +36,8 @@
private String firstName;
private String lastName;
+ @Version int version;
+
@OneToMany(mappedBy="customer",
fetch=FetchType.EAGER,
cascade=CascadeType.ALL)
Modified:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomerInventory.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomerInventory.java?rev=918643&r1=918642&r2=918643&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomerInventory.java
(original)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMCustomerInventory.java
Wed Mar 3 19:20:57 2010
@@ -23,6 +23,7 @@
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
+import javax.persistence.Version;
@Entity
public class DMCustomerInventory {
@@ -37,6 +38,8 @@
@ManyToOne(cascade=MERGE)
@JoinColumn(name="CI_CUSTOMERID")
private DMCustomer customer;
+
+ @Version int version;
public DMCustomerInventory() {
}
Modified:
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMItem.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMItem.java?rev=918643&r1=918642&r2=918643&view=diff
==============================================================================
---
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMItem.java
(original)
+++
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/detachment/model/DMItem.java
Wed Mar 3 19:20:57 2010
@@ -20,12 +20,15 @@
import javax.persistence.Entity;
import javax.persistence.Id;
+import javax.persistence.Version;
@Entity
public class DMItem {
private static long idCounter = System.currentTimeMillis();
@Id private long id = idCounter++;
+ @Version int version;
+
private String name;
private double price;
Modified: openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_remote.xml
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_remote.xml?rev=918643&r1=918642&r2=918643&view=diff
==============================================================================
--- openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_remote.xml (original)
+++ openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_remote.xml Wed Mar
3 19:20:57 2010
@@ -327,6 +327,31 @@
use detached state managers, as determined by the settings above.
</para>
</listitem>
+ <listitem>
+ <para>
+<literal>LiteAutoDetach</literal>: <emphasis role="bold">This option is ONLY
valid for the <literal>loaded</literal>
+DetachState setting.</emphasis> Detach all fields and relations as described
by the loaded
+property when an explicit detach is requested or when a
+single Entity is being detached as part of serialization. When the entire
+persistence context is being auto-detached(@See openjpa.AutoDetach),
+the minimal amount of work will be completed to disassociate all Entities from
+the persistence context. <emphasis role="bold">It is highly recommended that
all Entities have a
+...@version field when using this property</emphasis>. In addition, care needs
to be taken
+when this value is set to true as the following caveats apply:
+ <itemizedlist>
+ <listitem>
+ <para>
+A relationship from a managed Entity to an unmanaged Entity which was detached
by the lite detach setting will not be persisted.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+When merging a detached Entity back into the persistence context any lazily
loaded fields that were marked to null when detached will not be persisted.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
</itemizedlist>
<example id="ref_guide_detach_graph_confex">
<title>