You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2010/08/04 00:09:23 UTC
svn commit: r982048 - in /openjpa/trunk/openjpa-kernel/src/main:
java/org/apache/openjpa/kernel/ java/org/apache/openjpa/util/
resources/org/apache/openjpa/kernel/
Author: ppoddar
Date: Tue Aug 3 22:09:22 2010
New Revision: 982048
URL: http://svn.apache.org/viewvc?rev=982048&view=rev
Log:
OPENJPA-1567: Allow reference to sibling managed instances
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AttachManager.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/SingleFieldManager.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java
openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AttachManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AttachManager.java?rev=982048&r1=982047&r2=982048&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AttachManager.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AttachManager.java Tue Aug 3 22:09:22 2010
@@ -62,8 +62,8 @@ public class AttachManager {
private final Collection _visitedNodes = new ArrayList();
// reusable strategies
- private AttachStrategy _version = null;
- private AttachStrategy _detach = null;
+ private AttachStrategy _version;
+ private AttachStrategy _detach;
/**
* Constructor. Supply broker attaching to.
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=982048&r1=982047&r2=982048&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 Tue Aug 3 22:09:22 2010
@@ -238,7 +238,8 @@ public class BrokerImpl
private boolean _cachePreparedQuery = true;
private boolean _cacheFinderQuery = true;
private boolean _suppressBatchOLELogging = false;
-
+ private boolean _allowReferenceToSiblingContext = false;
+
// status
private int _flags = 0;
@@ -4042,7 +4043,7 @@ public class BrokerImpl
* @param status one of our STATUS constants describing why we're
* setting the state manager
*/
- void setStateManager(Object id, StateManagerImpl sm, int status) {
+ protected void setStateManager(Object id, StateManagerImpl sm, int status) {
lock();
try {
switch (status) {
@@ -4490,6 +4491,8 @@ public class BrokerImpl
return false;
PersistenceCapable pc = ImplHelper.toPersistenceCapable(obj, _conf);
+ if (pc.pcGetStateManager() instanceof DetachedStateManager)
+ return true;
Boolean detached = pc.pcIsDetached();
if (detached != null)
return detached.booleanValue();
@@ -5090,4 +5093,12 @@ public class BrokerImpl
}
return _store.isCached(oids, loaded);
};
+
+ public boolean getAllowReferenceToSiblingContext() {
+ return _allowReferenceToSiblingContext;
+ }
+
+ public void setAllowReferenceToSiblingContext(boolean allow) {
+ _allowReferenceToSiblingContext = allow;
+ }
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java?rev=982048&r1=982047&r2=982048&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java Tue Aug 3 22:09:22 2010
@@ -1468,4 +1468,13 @@ public class DelegatingBroker
public boolean isCached(List<Object> oid) {
return _broker.isCached(oid);
}
+
+ public boolean getAllowReferenceToSiblingContext() {
+ return _broker.getAllowReferenceToSiblingContext();
+ }
+
+ public void setAllowReferenceToSiblingContext(boolean allow) {
+ _broker.setAllowReferenceToSiblingContext(allow);
+ }
+
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java?rev=982048&r1=982047&r2=982048&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DetachedValueStateManager.java Tue Aug 3 22:09:22 2010
@@ -281,6 +281,9 @@ public class DetachedValueStateManager
if (sm != null) {
if (sm instanceof DetachedStateManager)
return fetchFromDetachedSM((DetachedStateManager) sm, field);
+ if (_ctx.getAllowReferenceToSiblingContext() && sm instanceof StateManagerImpl) {
+ return ((StateManagerImpl) sm).fetch(field);
+ }
throw new UnsupportedException(_loc.get("detach-val-badsm", _pc));
}
provideField(field);
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/SingleFieldManager.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/SingleFieldManager.java?rev=982048&r1=982047&r2=982048&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/SingleFieldManager.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/SingleFieldManager.java Tue Aug 3 22:09:22 2010
@@ -29,12 +29,14 @@ import java.util.Date;
import java.util.Iterator;
import java.util.Map;
+import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.meta.ValueMetaData;
import org.apache.openjpa.util.ChangeTracker;
import org.apache.openjpa.util.Exceptions;
+import org.apache.openjpa.util.ImplHelper;
import org.apache.openjpa.util.InvalidStateException;
import org.apache.openjpa.util.MapChangeTracker;
import org.apache.openjpa.util.ObjectId;
@@ -763,10 +765,18 @@ class SingleFieldManager
return; // allow but ignore
sm = _broker.getStateManager(obj);
- if (sm == null || !sm.isPersistent())
- throw new InvalidStateException(
- _loc.get("cant-cascade-persist", vmd))
+ if (sm == null || !sm.isPersistent()) {
+ if (((StoreContext)_broker).getAllowReferenceToSiblingContext()
+ && ImplHelper.isManageable(obj)
+ && ((PersistenceCapable)obj).pcGetStateManager() != null) {
+ return;
+ } else {
+ throw new InvalidStateException(_loc.get("cant-cascade-persist",
+ vmd.toString(), Exceptions.toString(obj),
+ sm == null ? " unmanaged" : sm.getPCState().getClass().getSimpleName()))
.setFailedObject(obj);
+ }
+ }
} else {
if (vmd.getCascadePersist() == ValueMetaData.CASCADE_IMMEDIATE) {
if (!_broker.isDetachedNew() && _broker.isDetached(obj))
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java?rev=982048&r1=982047&r2=982048&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java Tue Aug 3 22:09:22 2010
@@ -500,4 +500,26 @@ public interface StoreContext {
* @since 2.0.0.
*/
public boolean isCached(List<Object> oid);
+
+ /**
+ * Affirms if this context will allow its managed instances to refer instances
+ * that are managed by other contexts.
+ * <B>Note</B>: Some specification (such as JPA) does not warranty predictable
+ * behavior when strict group-like property of a persistent context (where managed
+ * instances can only refer to instances managed by the <em>same</em> context).
+ * Please be aware of consequences when the flag is set to true.
+ *
+ * @since 2.1
+ */
+ public void setAllowReferenceToSiblingContext(boolean flag);
+
+ /**
+ * Affirms if this context will allow its managed instances to refer instances
+ * that are managed by other contexts.
+ *
+ * @return false by default.
+ *
+ * @since 2.1
+ */
+ public boolean getAllowReferenceToSiblingContext();
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java?rev=982048&r1=982047&r2=982048&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/util/ApplicationIds.java Tue Aug 3 22:09:22 2010
@@ -486,9 +486,9 @@ public class ApplicationIds {
// If a value already exists on this field, throw exception.
// This is considered an application coding error.
if (!sm.isDefaultValue(pks[i].getIndex()))
- throw new InvalidStateException(_loc2.get(
- "existing-value-override-excep", pks[i]
- .getFullName(false)));
+ throw new InvalidStateException(_loc2.get("existing-value-override-excep",
+ pks[i].getFullName(false), Exceptions.toString(sm.getPersistenceCapable()),
+ sm.getPCState().getClass().getSimpleName()));
// Assign the generated value
if (store.assignField(sm, pks[i].getIndex(), preFlush))
pks[i].setValueGenerated(true);
Modified: openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties?rev=982048&r1=982047&r2=982048&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties (original)
+++ openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties Tue Aug 3 22:09:22 2010
@@ -214,14 +214,18 @@ nontrans-proxied: You cannot make a prop
nontransactional.
no-field: Field "{0}" is not declared in "{1}", or is not managed.
no-field-index: "{0}" is not the index of any managed field in "{1}".
-cant-cascade-persist: Encountered unmanaged object in persistent field \
- "{0}" during flush. However, this field does not \
- allow cascade persist. Set the cascade attribute for this field to \
- CascadeType.PERSIST or CascadeType.ALL (JPA annotations) or \
- "persist" or "all" (JPA orm.xml), or enable cascade-persist globally, \
- or manually persist the related field value prior to flushing. \
- You cannot flush unmanaged objects or graphs that have persistent \
- associations to unmanaged objects.
+cant-cascade-persist: Encountered unmanaged object "{1}" in life cycle state \
+ {2} while cascading persistence via field "{0}" during flush. However, \
+ this field does not allow cascade persist. You cannot flush unmanaged objects \
+ or graphs that have persistent associations to unmanaged objects.\r\n \
+ Suggested actions: a) Set the cascade attribute for this field to \
+ CascadeType.PERSIST or CascadeType.ALL (JPA annotations) or \
+ "persist" or "all" (JPA orm.xml), \r\n \
+ b) enable cascade-persist globally, \r\n \
+ c) manually persist the related field value prior to flushing. \r\n \
+ d) if the reference belongs to another context, allow reference to it \
+ by setting StoreContext.setAllowReferenceToSiblingContext().
+
cant-cascade-attach: Encountered new object in persistent field \
"{0}" during attach. However, this field does not \
allow cascade attach. Set the cascade attribute for this field to \
@@ -384,11 +388,10 @@ null-fg: Attempt to add null/empty fetch
null-field: Attempt to add null/empty field name to fetch configuration.
container-projection: Query projections cannot include array, collection, or \
map fields. Invalid query: "{0}"
-existing-value-override-excep: The generated value processing detected an \
-existing value assigned to this field: {0}. This existing value was either \
-provided via an initializer or by calling the setter method. You either need \
-to remove the @GeneratedValue annotation or modify the code to remove the \
-initializer processing.
+existing-value-override-excep: Primary key field {0} of {1} has non-default value. \
+ The instance life cycle is in {2} state and hence an existing non-default value \
+ for the identity field is not permitted. You either need to remove the @GeneratedValue \
+ annotation or modify the code to remove the initializer processing.
invalid-tran-status: The transaction was not in a valid state ({0}) to \
accept the "{1}" method invocation. Processing will continue.
multi-threaded-access: Multiple concurrent threads attempted to access a \