You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by aw...@apache.org on 2007/04/11 18:21:17 UTC
svn commit: r527565 - in /incubator/openjpa/trunk:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/
openjpa-kernel/src/main/java/org/apache/openjpa/kernel/
openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/
openj...
Author: awhite
Date: Wed Apr 11 09:21:13 2007
New Revision: 527565
URL: http://svn.apache.org/viewvc?view=rev&rev=527565
Log:
OPENJPA-134 : When we're performing eager fetches and we can detect that we're
already fetching the owning side of a bidi relation, cut off eager selecting
and loading when we come across the back-ptr to the owner again.
Added:
incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BidiChild.java (with props)
incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BidiParent.java (with props)
incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestEagerBidiSQL.java (with props)
Modified:
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/DelegatingJDBCFetchConfiguration.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCFetchConfiguration.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCFetchConfigurationImpl.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PagingResultObjectProvider.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java
incubator/openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/ObjectData.java
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/DelegatingJDBCFetchConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/DelegatingJDBCFetchConfiguration.java?view=diff&rev=527565&r1=527564&r2=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/DelegatingJDBCFetchConfiguration.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/DelegatingJDBCFetchConfiguration.java Wed Apr 11 09:21:13 2007
@@ -233,26 +233,26 @@
}
}
- public JDBCFetchConfiguration traverseJDBC(FieldMetaData fm) {
+ public int getIsolation() {
try {
- return getJDBCDelegate().traverseJDBC(fm);
+ return getJDBCDelegate().getIsolation();
} catch (RuntimeException re) {
throw translate(re);
}
}
- public int getIsolation() {
+ public JDBCFetchConfiguration setIsolation(int level) {
try {
- return getJDBCDelegate().getIsolation();
+ getJDBCDelegate().setIsolation(level);
+ return this;
} catch (RuntimeException re) {
throw translate(re);
}
}
- public JDBCFetchConfiguration setIsolation(int level) {
+ public JDBCFetchConfiguration traverseJDBC(FieldMetaData fm) {
try {
- getJDBCDelegate().setIsolation(level);
- return this;
+ return getJDBCDelegate().traverseJDBC(fm);
} catch (RuntimeException re) {
throw translate(re);
}
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCFetchConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCFetchConfiguration.java?view=diff&rev=527565&r1=527564&r2=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCFetchConfiguration.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCFetchConfiguration.java Wed Apr 11 09:21:13 2007
@@ -167,11 +167,6 @@
public JDBCFetchConfiguration clearJoins();
/**
- * Convenience method to cast traversal to store-specific type.
- */
- public JDBCFetchConfiguration traverseJDBC(FieldMetaData fm);
-
- /**
* <p>The isolation level for queries issued to the database. This overrides
* the persistence-unit-wide <code>openjpa.jdbc.TransactionIsolation</code>
* value.</p>
@@ -204,4 +199,9 @@
* @since 0.9.7
*/
public JDBCFetchConfiguration setIsolation(int level);
+
+ /**
+ * Convenience method to cast traversal to store-specific type.
+ */
+ public JDBCFetchConfiguration traverseJDBC(FieldMetaData fm);
}
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCFetchConfigurationImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCFetchConfigurationImpl.java?view=diff&rev=527565&r1=527564&r2=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCFetchConfigurationImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCFetchConfigurationImpl.java Wed Apr 11 09:21:13 2007
@@ -303,25 +303,6 @@
return this;
}
- public JDBCFetchConfiguration traverseJDBC(FieldMetaData fm) {
- return (JDBCFetchConfiguration) traverse(fm);
- }
-
- /**
- * Access JDBC configuration information. May return null if not a
- * JDBC back-end (possible to get a JDBCFetchConfiguration on non-JDBC
- * back end in remote client).
- */
- private JDBCConfiguration getJDBCConfiguration() {
- StoreContext ctx = getContext();
- if (ctx == null)
- return null;
- OpenJPAConfiguration conf = ctx.getConfiguration();
- if (!(conf instanceof JDBCConfiguration))
- return null;
- return (JDBCConfiguration) conf;
- }
-
public int getIsolation() {
return _state.isolationLevel;
}
@@ -341,5 +322,24 @@
else
_state.isolationLevel = level;
return this;
+ }
+
+ public JDBCFetchConfiguration traverseJDBC(FieldMetaData fm) {
+ return (JDBCFetchConfiguration) traverse(fm);
+ }
+
+ /**
+ * Access JDBC configuration information. May return null if not a
+ * JDBC back-end (possible to get a JDBCFetchConfiguration on non-JDBC
+ * back end in remote client).
+ */
+ private JDBCConfiguration getJDBCConfiguration() {
+ StoreContext ctx = getContext();
+ if (ctx == null)
+ return null;
+ OpenJPAConfiguration conf = ctx.getConfiguration();
+ if (!(conf instanceof JDBCConfiguration))
+ return null;
+ return (JDBCConfiguration) conf;
}
}
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java?view=diff&rev=527565&r1=527564&r2=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java Wed Apr 11 09:21:13 2007
@@ -756,8 +756,8 @@
public Object load(ClassMapping mapping, JDBCFetchConfiguration fetch,
BitSet exclude, Result result) throws SQLException {
if (!mapping.isMapped())
- throw new InvalidStateException(_loc
- .get("virtual-mapping", mapping));
+ throw new InvalidStateException(_loc.get("virtual-mapping",
+ mapping));
// get the object id for the row; base class selects pk columns
ClassMapping base = mapping;
@@ -972,7 +972,7 @@
if (sm != null && sm.getPCState() != PCState.TRANSIENT
&& sm.getLoaded().get(fm.getIndex()))
return false;
- return fetch.requiresFetch(fm);
+ return fetch.requiresFetch(fm) == FetchConfiguration.FETCH_LOAD;
}
/**
@@ -1127,7 +1127,7 @@
fms = subMappings[i].getDefinedFieldMappings();
for (int j = 0; j < fms.length; j++) {
// make sure in one of configured fetch groups
- if (!fetch.requiresFetch(fms[j])
+ if (fetch.requiresFetch(fms[j]) != FetchConfiguration.FETCH_LOAD
&& ((!fms[j].isInDefaultFetchGroup()
&& fms[j].isDefaultFetchGroupExplicit())
|| fms[j].supportsSelect(sel, sel.TYPE_TWO_PART, sm, this,
Modified: incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PagingResultObjectProvider.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PagingResultObjectProvider.java?view=diff&rev=527565&r1=527564&r2=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PagingResultObjectProvider.java (original)
+++ incubator/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PagingResultObjectProvider.java Wed Apr 11 09:21:13 2007
@@ -27,6 +27,7 @@
import org.apache.openjpa.jdbc.sql.SQLBuffer;
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.jdbc.sql.SelectExecutor;
+import org.apache.openjpa.kernel.FetchConfiguration;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.kernel.StoreContext;
import org.apache.openjpa.lib.util.Closeable;
@@ -90,7 +91,7 @@
FieldMapping[] fms = mapping.getDefinedFieldMappings();
BitSet paged = null;
for (int i = 0; i < fms.length; i++) {
- if (!fetch.requiresFetch(fms[i]))
+ if (fetch.requiresFetch(fms[i]) != FetchConfiguration.FETCH_LOAD)
continue;
if (fms[i].supportsSelect(sel, sel.EAGER_PARALLEL, null, store,
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?view=diff&rev=527565&r1=527564&r2=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java Wed Apr 11 09:21:13 2007
@@ -777,7 +777,7 @@
StateManagerImpl sm = getStateManagerImplById(oid,
(flags & OID_ALLOW_NEW) != 0 || (_flags & FLAG_FLUSHED) != 0);
if (sm != null) {
- if (!requiresLoad(sm, true, edata, flags))
+ if (!requiresLoad(sm, true, fetch, edata, flags))
return call.processReturn(oid, sm);
if (!sm.isLoading()) {
@@ -827,7 +827,7 @@
// initialize a new state manager for the datastore instance
sm = newStateManagerImpl(oid, (flags & OID_COPY) != 0);
- boolean load = requiresLoad(sm, false, edata, flags);
+ boolean load = requiresLoad(sm, false, fetch, edata, flags);
sm = initialize(sm, load, fetch, edata);
if (sm == null) {
if ((flags & OID_NOVALIDATE) != 0)
@@ -939,7 +939,7 @@
sm = newStateManagerImpl(oid, (flags & OID_COPY) != 0);
_loading.put(obj, sm);
- if (requiresLoad(sm, initialized, edata, flags)) {
+ if (requiresLoad(sm, initialized, fetch, edata, flags)) {
transState = transState || useTransactionalState(fetch);
if (initialized && !sm.isTransactional() && transState)
sm.transactional();
@@ -977,7 +977,7 @@
for (Iterator itr = oids.iterator(); itr.hasNext(); idx++) {
oid = itr.next();
sm = (StateManagerImpl) _loading.get(oid);
- if (sm != null && requiresLoad(sm, true, edata, flags)) {
+ if (sm != null && requiresLoad(sm, true, fetch, edata, flags)) {
try {
sm.load(fetch, StateManagerImpl.LOAD_FGS,
exclude, edata, false);
@@ -1011,7 +1011,9 @@
* to the user.
*/
private boolean requiresLoad(OpenJPAStateManager sm, boolean initialized,
- Object edata, int flags) {
+ FetchConfiguration fetch, Object edata, int flags) {
+ if (!fetch.requiresLoad())
+ return false;
if ((flags & OID_NOVALIDATE) == 0)
return true;
if (edata != null) // take advantage of existing result
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java?view=diff&rev=527565&r1=527564&r2=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingFetchConfiguration.java Wed Apr 11 09:21:13 2007
@@ -436,9 +436,17 @@
}
}
- public boolean requiresFetch(FieldMetaData fmd) {
+ public int requiresFetch(FieldMetaData fmd) {
try {
return _fetch.requiresFetch(fmd);
+ } catch (RuntimeException re) {
+ throw translate(re);
+ }
+ }
+
+ public boolean requiresLoad() {
+ try {
+ return _fetch.requiresLoad();
} catch (RuntimeException re) {
throw translate(re);
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java?view=diff&rev=527565&r1=527564&r2=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachManager.java Wed Apr 11 09:21:13 2007
@@ -231,9 +231,11 @@
StateManagerImpl sm, BitSet idxs) {
FetchConfiguration fetch = broker.getFetchConfiguration();
FieldMetaData[] fmds = sm.getMetaData().getFields();
- for (int i = 0; i < fmds.length; i++)
- if (fmds[i].isPrimaryKey() || fetch.requiresFetch(fmds[i]))
+ for (int i = 0; i < fmds.length; i++) {
+ if (fmds[i].isPrimaryKey() || fetch.requiresFetch(fmds[i])
+ != FetchConfiguration.FETCH_NONE)
idxs.set(i);
+ }
}
/**
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java?view=diff&rev=527565&r1=527564&r2=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfiguration.java Wed Apr 11 09:21:13 2007
@@ -40,6 +40,32 @@
public static final int DEFAULT = -99;
/**
+ * Constant indicating that a field does not require fetching.
+ *
+ * @see #requiresFetch
+ */
+ public static final int FETCH_NONE = 0;
+
+ /**
+ * Constant indicating that a field requires a fetch and load of fetched
+ * data.
+ *
+ * @see #requiresFetch
+ */
+ public static final int FETCH_LOAD = 1;
+
+ /**
+ * Constant indicating that a reference to the field's value must be
+ * fetched, but loading data is not necessary. Used when we know the
+ * data will be loaded anyway, such as when traversing the back-ptr of
+ * a bidirectional relation where the other side is also being fetched.
+ *
+ * @see #requiresFetch
+ */
+ public static final int FETCH_REF = 2;
+
+
+ /**
* Return the context assiciated with this configuration;
* may be null if it has not been set or this object has been serialized.
*/
@@ -309,11 +335,19 @@
/**
* Affirms if the given field requires to be fetched in the context
- * of current fetch operation.
+ * of current fetch operation. Returns one of {@link #FETCH_NONE},
+ * {@link #FETCH_LOAD}, {@link FETCH_REF}.
*
* @since 0.4.1
*/
- public boolean requiresFetch(FieldMetaData fm);
+ public int requiresFetch(FieldMetaData fm);
+
+ /**
+ * Return false if we know that the object being fetched with this
+ * configuration does not require a load, because this configuration came
+ * from a traversal of a {@link #FETCH_REF} field.
+ */
+ public boolean requiresLoad();
/**
* Traverse the given field to generate (possibly) a new configuration
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java?view=diff&rev=527565&r1=527564&r2=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/FetchConfigurationImpl.java Wed Apr 11 09:21:13 2007
@@ -39,6 +39,7 @@
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FetchGroup;
import org.apache.openjpa.meta.FieldMetaData;
+import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.util.ImplHelper;
import org.apache.openjpa.util.InternalException;
import org.apache.openjpa.util.NoTransactionException;
@@ -84,6 +85,8 @@
private FetchConfigurationImpl _parent;
private String _fromField;
private Class _fromType;
+ private String _directRelationOwner;
+ private boolean _load = true;
private int _availableRecursion;
private int _availableDepth;
@@ -126,6 +129,8 @@
clone._parent = _parent;
clone._fromField = _fromField;
clone._fromType = _fromType;
+ clone._directRelationOwner = _directRelationOwner;
+ clone._load = _load;
clone._availableRecursion = _availableRecursion;
clone._availableDepth = _availableDepth;
clone.copy(this);
@@ -498,23 +503,32 @@
// Traversal
/////////////
- public boolean requiresFetch(FieldMetaData fm) {
+ public int requiresFetch(FieldMetaData fm) {
if (!includes(fm))
- return false;
+ return FETCH_NONE;
Class type = getRelationType(fm);
if (type == null)
- return true;
+ return FETCH_LOAD;
if (_availableDepth == 0)
- return false;
+ return FETCH_NONE;
// we can skip calculating recursion depth if this is a top-level conf:
// the field is in our fetch groups, so can't possibly not select
if (_parent == null)
- return true;
+ return FETCH_LOAD;
int rdepth = getAvailableRecursionDepth(fm, type, false);
- return rdepth == FetchGroup.DEPTH_INFINITE || rdepth > 0;
+ if (rdepth != FetchGroup.DEPTH_INFINITE && rdepth <= 0)
+ return FETCH_NONE;
+
+ if (StringUtils.equals(_directRelationOwner, fm.getFullName()))
+ return FETCH_REF;
+ return FETCH_LOAD;
+ }
+
+ public boolean requiresLoad() {
+ return _load;
}
public FetchConfiguration traverse(FieldMetaData fm) {
@@ -528,6 +542,15 @@
clone._fromField = fm.getFullName(false);
clone._fromType = type;
clone._availableRecursion = getAvailableRecursionDepth(fm, type, true);
+ if (StringUtils.equals(_directRelationOwner, fm.getFullName()))
+ clone._load = false;
+ else
+ clone._load = _load;
+
+ FieldMetaData owner = fm.getMappedByMetaData();
+ if (owner != null && owner.getTypeCode() == JavaTypes.PC)
+ clone._directRelationOwner = owner.getFullName();
+
return clone;
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java?view=diff&rev=527565&r1=527564&r2=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCDataImpl.java Wed Apr 11 09:21:13 2007
@@ -138,7 +138,8 @@
// fields in configured fetch groups
if (!isLoaded(i))
loadIntermediate(sm, fmds[i]);
- else if (!sm.getLoaded().get(i) && fetch.requiresFetch(fmds[i]))
+ else if (!sm.getLoaded().get(i) && fetch.requiresFetch(fmds[i])
+ != FetchConfiguration.FETCH_NONE)
loadField(sm, fmds[i], fetch, context);
}
}
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?view=diff&rev=527565&r1=527564&r2=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java Wed Apr 11 09:21:13 2007
@@ -407,7 +407,8 @@
load = !fmds[i].isTransient();
break;
case LOAD_FGS:
- load = fetch == null || fetch.requiresFetch(fmds[i]);
+ load = fetch == null || fetch.requiresFetch(fmds[i])
+ != FetchConfiguration.FETCH_NONE;
break;
default: // LOAD_ALL
load = true;
Modified: incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java?view=diff&rev=527565&r1=527564&r2=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java (original)
+++ incubator/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/VersionAttachStrategy.java Wed Apr 11 09:21:13 2007
@@ -131,7 +131,8 @@
attachField(manager, toAttach, sm, fmds[i], true);
break;
case DETACH_FGS:
- if (fetch.requiresFetch(fmds[i]))
+ if (fetch.requiresFetch(fmds[i])
+ != FetchConfiguration.FETCH_NONE)
attachField(manager, toAttach, sm, fmds[i], true);
break;
case DETACH_LOADED:
Added: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BidiChild.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BidiChild.java?view=auto&rev=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BidiChild.java (added)
+++ incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BidiChild.java Wed Apr 11 09:21:13 2007
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed 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.relations;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+
+@Entity
+public class BidiChild {
+
+ @Id
+ @GeneratedValue
+ private long id;
+
+ private String name;
+
+ @ManyToOne(fetch=FetchType.LAZY)
+ private BidiParent oneToManyParent;
+
+ @OneToOne(fetch=FetchType.LAZY)
+ private BidiParent oneToOneParent;
+
+ public long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public BidiParent getOneToOneParent() {
+ return oneToOneParent;
+ }
+
+ public void setOneToOneParent(BidiParent parent) {
+ oneToOneParent = parent;
+ }
+
+ public BidiParent getOneToManyParent() {
+ return oneToManyParent;
+ }
+
+ public void setOneToManyParent(BidiParent parent) {
+ oneToManyParent = parent;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BidiChild.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BidiChild.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BidiParent.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BidiParent.java?view=auto&rev=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BidiParent.java (added)
+++ incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BidiParent.java Wed Apr 11 09:21:13 2007
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed 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.relations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.OrderBy;
+
+@Entity
+public class BidiParent {
+
+ @Id
+ @GeneratedValue
+ private long id;
+
+ private String name;
+
+ @OneToMany(mappedBy="oneToManyParent")
+ @OrderBy("name ASC")
+ private List<BidiChild> oneToManyChildren = new ArrayList<BidiChild>();
+
+ @OneToOne(fetch=FetchType.LAZY, mappedBy="oneToOneParent")
+ private BidiChild oneToOneChild;
+
+ public long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public BidiChild getOneToOneChild() {
+ return oneToOneChild;
+ }
+
+ public void setOneToOneChild(BidiChild child) {
+ oneToOneChild = child;
+ }
+
+ public List<BidiChild> getOneToManyChildren() {
+ return oneToManyChildren;
+ }
+}
Propchange: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BidiParent.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/BidiParent.java
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestEagerBidiSQL.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestEagerBidiSQL.java?view=auto&rev=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestEagerBidiSQL.java (added)
+++ incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestEagerBidiSQL.java Wed Apr 11 09:21:13 2007
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed 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.relations;
+
+import java.util.List;
+import javax.persistence.EntityManager;
+
+import junit.textui.TestRunner;
+import org.apache.openjpa.persistence.OpenJPAEntityManager;
+import org.apache.openjpa.persistence.OpenJPAQuery;
+import org.apache.openjpa.persistence.test.SQLListenerTestCase;
+
+/**
+ * Test that when both sides of a mapped-by relation are eager fetched,
+ * traversing from the mapped-by side to the mapping side cuts off -- that
+ * we don't traverse in a loop back to the mapped-by side in the generated
+ * SQL.
+ *
+ * @author Abe White
+ */
+public class TestEagerBidiSQL
+ extends SQLListenerTestCase {
+
+ private long id1;
+ private long id2;
+
+ public void setUp() {
+ setUp(BidiParent.class, BidiChild.class);
+
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+
+ for (int i = 1; i <= 2; i++) {
+ BidiParent parent = new BidiParent();
+ parent.setName("parent" + i);
+ em.persist(parent);
+
+ BidiChild oneOneChild = new BidiChild();
+ oneOneChild.setName("oneToOneChild" + i);
+ oneOneChild.setOneToOneParent(parent);
+ parent.setOneToOneChild(oneOneChild);
+ em.persist(oneOneChild);
+
+ for (int j = 1; j <= 3; j++) {
+ BidiChild oneManyChild = new BidiChild();
+ oneManyChild.setName("oneToManyChild" + i + "::" + j);
+ oneManyChild.setOneToManyParent(parent);
+ parent.getOneToManyChildren().add(oneManyChild);
+ em.persist(oneManyChild);
+ }
+
+ if (i == 1)
+ id1 = parent.getId();
+ else
+ id2 = parent.getId();
+ }
+
+ em.getTransaction().commit();
+ em.close();
+ }
+
+ public void testEagerOwnerOneToManyFind() {
+ sql.clear();
+
+ OpenJPAEntityManager em = emf.createEntityManager();
+ em.getFetchPlan().addField(BidiParent.class, "oneToManyChildren");
+ em.getFetchPlan().addField(BidiChild.class, "oneToManyParent");
+ BidiParent parent = em.find(BidiParent.class, id1);
+ assertEquals(1, sql.size());
+ assertNotSQL(".* LEFT OUTER JOIN BidiParent .*");
+ assertEquals("parent1", parent.getName());
+ assertEquals(3, parent.getOneToManyChildren().size());
+ for (int i = 0; i < 3; i++) {
+ assertEquals("oneToManyChild1::" + (i + 1),
+ parent.getOneToManyChildren().get(i).getName());
+ assertEquals(parent,
+ parent.getOneToManyChildren().get(i).getOneToManyParent());
+ }
+ assertEquals(1, sql.size());
+ em.close();
+ }
+
+ public void testEagerOwnerOneToOneFind() {
+ sql.clear();
+
+ OpenJPAEntityManager em = emf.createEntityManager();
+ em.getFetchPlan().addField(BidiParent.class, "oneToOneChild");
+ em.getFetchPlan().addField(BidiChild.class, "oneToOneParent");
+ BidiParent parent = em.find(BidiParent.class, id1);
+ assertEquals(1, sql.size());
+ assertNotSQL(".* LEFT OUTER JOIN BidiParent .*");
+ assertEquals("parent1", parent.getName());
+ assertNotNull(parent.getOneToOneChild());
+ assertEquals("oneToOneChild1", parent.getOneToOneChild().getName());
+ assertEquals(parent, parent.getOneToOneChild().getOneToOneParent());
+ assertEquals(1, sql.size());
+ em.close();
+ }
+
+ public void testEagerOwnerOneToManyQuery() {
+ sql.clear();
+
+ OpenJPAEntityManager em = emf.createEntityManager();
+ OpenJPAQuery q = em.createQuery("SELECT o FROM BidiParent o "
+ + "ORDER BY o.name ASC");
+ q.getFetchPlan().addField(BidiParent.class, "oneToManyChildren");
+ q.getFetchPlan().addField(BidiChild.class, "oneToManyParent");
+ List<BidiParent> res = (List<BidiParent>) q.getResultList();
+
+ assertEquals(2, res.size());
+ assertEquals(sql.toString(), 2, sql.size());
+ assertNotSQL(".* LEFT OUTER JOIN BidiParent .*");
+
+ for (int i = 0; i < res.size(); i++) {
+ assertEquals("parent" + (i + 1), res.get(i).getName());
+ assertEquals(3, res.get(i).getOneToManyChildren().size());
+ for (int j = 0; j < 3; j++) {
+ assertEquals("oneToManyChild" + (i + 1) + "::" + (j + 1),
+ res.get(i).getOneToManyChildren().get(j).getName());
+ assertEquals(res.get(i), res.get(i).getOneToManyChildren().
+ get(j).getOneToManyParent());
+ }
+ }
+ assertEquals(2, sql.size());
+ em.close();
+ }
+
+ public void testEagerOwnerOneToOneQuery() {
+ sql.clear();
+
+ OpenJPAEntityManager em = emf.createEntityManager();
+ OpenJPAQuery q = em.createQuery("SELECT o FROM BidiParent o "
+ + "ORDER BY o.name ASC");
+ q.getFetchPlan().addField(BidiParent.class, "oneToOneChild");
+ q.getFetchPlan().addField(BidiChild.class, "oneToOneParent");
+ List<BidiParent> res = (List<BidiParent>) q.getResultList();
+
+ assertEquals(2, res.size());
+ assertEquals(1, sql.size());
+ assertNotSQL(".* LEFT OUTER JOIN BidiParent .*");
+
+ for (int i = 0; i < res.size(); i++) {
+ assertEquals("parent" + (i + 1), res.get(i).getName());
+ assertNotNull(res.get(i).getOneToOneChild());
+ assertEquals("oneToOneChild" + (i + 1),
+ res.get(i).getOneToOneChild().getName());
+ assertEquals(res.get(i),
+ res.get(i).getOneToOneChild().getOneToOneParent());
+ }
+ assertEquals(1, sql.size());
+ em.close();
+ }
+
+ public void testEagerNonOwnerOneToOneQuery() {
+ sql.clear();
+
+ OpenJPAEntityManager em = emf.createEntityManager();
+ OpenJPAQuery q = em.createQuery("SELECT o FROM BidiParent o "
+ + "ORDER BY o.name ASC");
+ q.getFetchPlan().addField(BidiParent.class, "oneToOneChild");
+ q.getFetchPlan().addField(BidiChild.class, "oneToManyParent");
+ List<BidiParent> res = (List<BidiParent>) q.getResultList();
+
+ assertEquals(2, res.size());
+ assertEquals(1, sql.size());
+ assertSQL(".* LEFT OUTER JOIN BidiParent .*");
+
+ for (int i = 0; i < res.size(); i++) {
+ assertEquals("parent" + (i + 1), res.get(i).getName());
+ assertNotNull(res.get(i).getOneToOneChild());
+ assertEquals("oneToOneChild" + (i + 1),
+ res.get(i).getOneToOneChild().getName());
+ assertNull(res.get(i).getOneToOneChild().getOneToManyParent());
+ }
+ assertEquals(1, sql.size());
+ em.close();
+ }
+
+ public static void main(String[] args) {
+ TestRunner.run(TestEagerBidiSQL.class);
+ }
+}
+
Propchange: incubator/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/relations/TestEagerBidiSQL.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/ObjectData.java
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/ObjectData.java?view=diff&rev=527565&r1=527564&r2=527565
==============================================================================
--- incubator/openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/ObjectData.java (original)
+++ incubator/openjpa/trunk/openjpa-xmlstore/src/main/java/org/apache/openjpa/xmlstore/ObjectData.java Wed Apr 11 09:21:13 2007
@@ -111,7 +111,8 @@
FieldMetaData[] fmds = _meta.getFields();
for (int i = 0; i < fmds.length; i++)
- if (!sm.getLoaded().get(i) && fetch.requiresFetch(fmds[i]))
+ if (!sm.getLoaded().get(i) && fetch.requiresFetch(fmds[i])
+ != FetchConfiguration.FETCH_NONE)
sm.store(i, toLoadable(sm, fmds[i], _data[i], fetch));
}