Author: ppoddar
Date: Mon Dec 22 12:22:52 2008
New Revision: 728761
URL: http://svn.apache.org/viewvc?rev=728761&view=rev
Log:
OPENJPA-841: Add structure to hold Slice information. Also ensure that
replicated instances carry all replicated slice information even when they are
found in a single slice.
Added:
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceInfo.java
Modified:
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceImplHelper.java
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SlicePersistence.java
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java
openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/localizer.properties
openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/Country.java
openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java
Modified:
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java?rev=728761&r1=728760&r2=728761&view=diff
==============================================================================
---
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java
(original)
+++
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java
Mon Dec 22 12:22:52 2008
@@ -59,24 +59,21 @@
public OpenJPAStateManager persist(Object pc, Object id, boolean
explicit,
OpCallbacks call) {
OpenJPAStateManager sm = getStateManager(pc);
- String[] targets = null;
+ SliceInfo info = null;
boolean replicated = SliceImplHelper.isReplicated(sm);
- if (getOperatingSet().isEmpty()
- && (sm == null || sm.getImplData() == null)) {
- targets = SliceImplHelper.getSlicesByPolicy(pc,
getConfiguration(),
+ if (getOperatingSet().isEmpty() &&
!SliceImplHelper.isSliceAssigned(sm)) {
+ info = SliceImplHelper.getSlicesByPolicy(pc,
getConfiguration(),
this);
- if (!replicated) {
- _rootSlice = targets[0];
- }
+ _rootSlice = info.getSlices()[0];
}
sm = super.persist(pc, id, explicit, call);
- if (sm.getImplData() == null) {
- if (targets == null) {
- targets = replicated
+ if (!SliceImplHelper.isSliceAssigned(sm)) {
+ if (info == null) {
+ info = replicated
? SliceImplHelper.getSlicesByPolicy(pc,
getConfiguration(), this)
- : new String[]{_rootSlice};
+ : new SliceInfo(_rootSlice);
}
- sm.setImplData(targets, true);
+ info.setInto(sm);
}
return sm;
}
Modified:
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceImplHelper.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceImplHelper.java?rev=728761&r1=728760&r2=728761&view=diff
==============================================================================
---
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceImplHelper.java
(original)
+++
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceImplHelper.java
Mon Dec 22 12:22:52 2008
@@ -42,30 +42,45 @@
* {...@link DistributionPolicy} or {...@link ReplicationPolicy}
* depending on whether the given instance is {...@link Replicated
replicated}.
*/
- public static String[] getSlicesByPolicy(Object pc,
+ public static SliceInfo getSlicesByPolicy(Object pc,
DistributedConfiguration conf, Object ctx) {
- List<String> availables = conf.getActiveSliceNames();
+ List<String> actives = conf.getActiveSliceNames();
Object policy = null;
String[] targets = null;
- if (isReplicated(pc, conf)) {
+ boolean replicated = isReplicated(pc, conf);
+ if (replicated) {
policy = conf.getReplicationPolicyInstance();
- targets = ((ReplicationPolicy)policy).replicate
- (pc, availables, ctx);
- if (targets == null || targets.length == 0)
- targets = availables.toArray(new
String[availables.size()]);
+ targets = ((ReplicationPolicy)policy).replicate(pc,
actives, ctx);
} else {
policy = conf.getDistributionPolicyInstance();
- String slice = ((DistributionPolicy)policy).distribute
- (pc, availables, ctx);
- targets = new String[]{slice};
+ targets = new
String[]{((DistributionPolicy)policy).distribute
+ (pc, actives, ctx)};
}
- for (String target : targets)
- if (!availables.contains(target))
- throw new UserException(_loc.get("bad-policy-slice",
new Object[] {
- policy.getClass().getName(), target,
pc, availables}));
- return targets;
+ assertSlices(targets, pc, actives, policy);
+ return new SliceInfo(replicated, targets);
}
+ private static void assertSlices(String[] targets, Object pc,
+ List<String> actives, Object policy) {
+ if (targets == null || targets.length == 0)
+ throw new UserException(_loc.get("no-policy-slice", new Object[] {
+ policy.getClass().getName(), pc, actives}));
+ for (String target : targets)
+ if (!actives.contains(target))
+ throw new UserException(_loc.get("bad-policy-slice",
+ new Object[] {policy.getClass().getName(), target, pc,
+ actives}));
+ }
+
+ /**
+ * Gets the target slices for the given StateManager.
+ */
+ public static SliceInfo getSlicesByPolicy(OpenJPAStateManager sm,
+ DistributedConfiguration conf, Object ctx) {
+ return getSlicesByPolicy(sm.getPersistenceCapable(), conf, ctx);
+ }
+
+
/**
* Affirms if the given instance be replicated to multiple slices.
*/
@@ -85,4 +100,19 @@
return false;
return sm.getMetaData().isReplicated();
}
+
+ /**
+ * Affirms if the given StateManager has an assigned slice.
+ */
+ public static boolean isSliceAssigned(OpenJPAStateManager sm) {
+ return sm != null && sm.getImplData() != null
+ && sm.getImplData() instanceof SliceInfo;
+ }
+
+ /**
+ * Gets the assigned slice information, if any, from the given
StateManager.
+ */
+ public static SliceInfo getSliceInfo(OpenJPAStateManager sm) {
+ return isSliceAssigned(sm) ? (SliceInfo) sm.getImplData() : null;
+ }
}
Added:
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceInfo.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceInfo.java?rev=728761&view=auto
==============================================================================
---
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceInfo.java
(added)
+++
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceInfo.java
Mon Dec 22 12:22:52 2008
@@ -0,0 +1,117 @@
+/*
+ * 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.slice;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.apache.openjpa.kernel.OpenJPAStateManager;
+import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.util.InternalException;
+
+/**
+ * Holder of slice names where a persistent instance is stored. This structure
+ * is held in StateManagers to track the origin of a persistent instance.
+ *
+ * @author Pinaki Poddar
+ *
+ */
+...@suppresswarnings("serial")
+public class SliceInfo implements Serializable {
+ private final boolean _isReplicated;
+ private String[] _slices;
+
+ private static transient Localizer _loc =
+ Localizer.forPackage(SliceInfo.class);
+
+ /**
+ * Generic constructor given one or more slice names.
+ * The replicated flag is set independently.
+ */
+ public SliceInfo(boolean replicated, String[] slices) {
+ super();
+ if (slices == null || slices.length == 0)
+ throw new InternalException();
+ _isReplicated = replicated;
+ _slices = slices;
+ }
+
+ /**
+ * Generic constructor given one or more slice names.
+ * The replicated flag is set independently.
+ */
+ public SliceInfo(boolean replicated, List<String> slices) {
+ super();
+ if (slices == null || slices.isEmpty())
+ throw new InternalException();
+ _isReplicated = replicated;
+ _slices = slices.toArray(new String[slices.size()]);
+ }
+
+ /**
+ * Constructor for non-replicated instance that is stored in a single
slice.
+ */
+ public SliceInfo(String slice) {
+ this(false, new String[]{slice});
+ }
+
+ /**
+ * Constructor for replicated instance that is stored in one or more
slices.
+ */
+ public SliceInfo(String[] slices) {
+ this(true, slices);
+ }
+
+ public SliceInfo(List<String> slices) {
+ this(true, slices);
+ }
+
+ /**
+ * Affirms if this receiver designates replicated instances.
+ * @return
+ */
+ public boolean isReplicated() {
+ return _isReplicated;
+ }
+
+ /**
+ * Gets the name of the slice(s) held by this receiver.
+ */
+ public String[] getSlices() {
+ return _slices;
+ }
+
+ /**
+ * Sets this receiver as the given StateManager's internal
instance-level
+ * data. If the given StateManager had existing instance-level data
that is
+ * not a SliceInfo then raise an exception.
+ */
+ public SliceInfo setInto(OpenJPAStateManager sm) {
+ if (sm == null)
+ throw new NullPointerException();
+ if (SliceImplHelper.isReplicated(sm) != isReplicated())
+ throw new InternalException();
+ Object previous = sm.setImplData(this, true);
+ if (previous == null || previous instanceof SliceInfo)
+ return (SliceInfo)previous;
+ throw new InternalException(_loc.get("unknown-impl-data",
previous,
+ previous.getClass().getName(), sm.getPersistenceCapable())
+ .getMessage());
+ }
+}
Modified:
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SlicePersistence.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SlicePersistence.java?rev=728761&r1=728760&r2=728761&view=diff
==============================================================================
---
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SlicePersistence.java
(original)
+++
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SlicePersistence.java
Mon Dec 22 12:22:52 2008
@@ -21,7 +21,7 @@
import java.util.Arrays;
import org.apache.openjpa.enhance.PersistenceCapable;
-import org.apache.openjpa.kernel.StateManagerImpl;
+import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.util.ImplHelper;
/**
@@ -45,17 +45,29 @@
PersistenceCapable pc = ImplHelper.toPersistenceCapable(obj,
null);
if (pc == null)
return null;
- StateManagerImpl sm = (StateManagerImpl)pc.pcGetStateManager();
- if (sm == null)
+ OpenJPAStateManager sm =
(OpenJPAStateManager)pc.pcGetStateManager();
+ SliceInfo info = SliceImplHelper.getSliceInfo(sm);
+ if (info == null)
return null;
- Object slice = sm.getImplData();
- if (slice instanceof String[]) {
- if (((String[])slice).length == 1) {
- return ((String[])slice)[0];
- } else {
- return Arrays.toString(((String[])slice));
- }
- }
- return null;
+ String[] names = info.getSlices();
+ return info.isReplicated() ? Arrays.toString(names) : names[0];
}
+
+ /**
+ * Affirms if the given instance is replicated, provided the given
instance
+ * is managed.
+ */
+ public static boolean isReplicated(Object obj) {
+ if (obj == null)
+ return false;
+ PersistenceCapable pc = ImplHelper.toPersistenceCapable(obj, null);
+ if (pc == null)
+ return false;
+ OpenJPAStateManager sm = (OpenJPAStateManager)pc.pcGetStateManager();
+ SliceInfo info = SliceImplHelper.getSliceInfo(sm);
+ if (info == null)
+ return false;
+ return info.isReplicated();
+ }
+
}
Modified:
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java?rev=728761&r1=728760&r2=728761&view=diff
==============================================================================
---
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java
(original)
+++
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java
Mon Dec 22 12:22:52 2008
@@ -33,6 +33,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.kernel.ConnectionInfo;
import org.apache.openjpa.jdbc.kernel.JDBCStore;
@@ -56,6 +57,7 @@
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.slice.ProductDerivation;
import org.apache.openjpa.slice.SliceImplHelper;
+import org.apache.openjpa.slice.SliceInfo;
import org.apache.openjpa.util.InternalException;
import org.apache.openjpa.util.StoreException;
@@ -113,22 +115,32 @@
* targets slices by using additional connection info. If no additional
* connection info then calls back to user-defined policy.
*/
- protected String[] findSliceNames(OpenJPAStateManager sm, Object info) {
- boolean hasImplData = sm.getImplData() != null;
- if (hasImplData)
- return (String[])sm.getImplData();
- String[] targets = estimateSlice(sm, info);
- if (targets == null)
- return assignSlice(sm);
- return targets;
+ protected SliceInfo findSliceNames(OpenJPAStateManager sm, Object edata) {
+ if (SliceImplHelper.isSliceAssigned(sm))
+ return SliceImplHelper.getSliceInfo(sm);
+ SliceInfo result = null;
+ PersistenceCapable pc = sm.getPersistenceCapable();
+ Object ctx = getContext();
+ if (SliceImplHelper.isReplicated(sm)) {
+ result = SliceImplHelper.getSlicesByPolicy(pc, _conf, ctx);
+ } else {
+ String origin = estimateSlice(sm, edata);
+ if (origin == null) {
+ result = SliceImplHelper.getSlicesByPolicy(pc, _conf, ctx);
+ } else {
+ result = new SliceInfo(origin);
+ }
+ }
+ return result;
}
- private String[] assignSlice(OpenJPAStateManager sm) {
- Object pc = sm.getPersistenceCapable();
- String[] targets = SliceImplHelper.getSlicesByPolicy(pc, _conf,
- getContext());
- sm.setImplData(targets, true);
- return targets;
+ private void assignSlice(OpenJPAStateManager sm, String hint) {
+ if (SliceImplHelper.isReplicated(sm)) {
+ SliceImplHelper.getSlicesByPolicy(sm, _conf, getContext())
+ .setInto(sm);
+ return;
+ }
+ new SliceInfo(hint).setInto(sm);
}
/**
@@ -137,27 +149,19 @@
* then return null.
*
*/
- private String[] estimateSlice(OpenJPAStateManager sm, Object edata) {
+ private String estimateSlice(OpenJPAStateManager sm, Object edata) {
if (edata == null || !(edata instanceof ConnectionInfo))
return null;
- List<String> temps = null;
Result result = ((ConnectionInfo) edata).result;
if (result instanceof ResultSetResult) {
JDBCStore store = ((ResultSetResult) result).getStore();
for (SliceStoreManager slice : _slices) {
if (slice == store) {
- if (temps == null)
- temps = new ArrayList<String>();
- temps.add(slice.getName());
+ return slice.getName();
}
}
}
- if (temps != null) {
- String[] targets = temps.toArray(new String[temps.size()]);
- sm.setImplData(targets, true);
- return targets;
- }
return null;
}
@@ -165,7 +169,7 @@
* Selects child StoreManager(s) where the given instance resides.
*/
private StoreManager selectStore(OpenJPAStateManager sm, Object edata) {
- String[] targets = findSliceNames(sm, edata);
+ String[] targets = findSliceNames(sm, edata).getSlices();
for (String target : targets) {
SliceStoreManager slice = lookup(target);
if (slice == null)
@@ -221,16 +225,16 @@
}
public boolean exists(OpenJPAStateManager sm, Object edata) {
- List<String> targets = null;
+ String origin = null;
for (SliceStoreManager slice : _slices) {
if (slice.exists(sm, edata)) {
- if (targets == null)
- targets.add(slice.getName());
+ origin = slice.getName();
+ break;
}
}
- if (targets != null)
- sm.setImplData(targets.toArray(new String[targets.size()]),
true);
- return targets != null;
+ if (origin != null)
+ assignSlice(sm, origin);
+ return origin != null;
}
@@ -244,12 +248,16 @@
Map<String, List<OpenJPAStateManager>> subsets = bin(sms, null);
boolean parallel = !getConfiguration().getMultithreaded();
- for (SliceStoreManager slice : _slices) {
+ for (int i = 0; i < _slices.size(); i++) {
+ SliceStoreManager slice = _slices.get(i);
List<OpenJPAStateManager> subset = subsets.get(slice.getName());
if (subset.isEmpty())
continue;
if (containsReplicated(subset)) {
+ Map<OpenJPAStateManager, Object> versions =
cacheVersion(subset);
collectException(slice.flush(subset), exceptions);
+ if (i != _slices.size()-1)
+ rollbackVersion(subset, versions);
} else {
if (parallel) {
futures.add(threadPool.submit(new Flusher(slice,
subset)));
@@ -285,6 +293,23 @@
return false;
}
+ private Map<OpenJPAStateManager, Object> cacheVersion
+ (List<OpenJPAStateManager> sms) {
+ Map<OpenJPAStateManager, Object> result =
+ new HashMap<OpenJPAStateManager, Object>();
+ for (OpenJPAStateManager sm : sms)
+ if (sm.getMetaData().isReplicated())
+ result.put(sm, sm.getVersion());
+ return result;
+ }
+
+ private void rollbackVersion(List<OpenJPAStateManager> sms,
+ Map<OpenJPAStateManager, Object> result) {
+ for (OpenJPAStateManager sm : sms)
+ if (sm.getMetaData().isReplicated())
+ sm.setVersion(result.get(sm));
+ }
+
/**
* Separate the given list of StateManagers in separate lists for each
slice
* by the associated slice identifier of each StateManager.
@@ -297,7 +322,7 @@
subsets.put(slice.getName(), new ArrayList<OpenJPAStateManager>());
for (Object x : sms) {
OpenJPAStateManager sm = (OpenJPAStateManager) x;
- String[] targets = findSliceNames(sm, edata);
+ String[] targets = findSliceNames(sm, edata).getSlices();
for (String slice : targets) {
subsets.get(slice).add(sm);
}
@@ -328,20 +353,23 @@
public boolean initialize(OpenJPAStateManager sm, PCState state,
FetchConfiguration fetch, Object edata) {
if (edata instanceof ConnectionInfo) {
- String[] targets = findSliceNames(sm, (ConnectionInfo) edata);
- if (targets != null || targets.length > 0)
- return lookup(targets[0]).initialize(sm, state, fetch, edata);
+ String origin = estimateSlice(sm, edata);
+ if (origin != null) {
+ if (lookup(origin).initialize(sm, state, fetch, edata)) {
+ assignSlice(sm, origin);
+ return true;
+ }
+ }
}
// not a part of Query result load. Look into the slices till found
List<SliceStoreManager> targets = getTargets(fetch);
for (SliceStoreManager slice : targets) {
if (slice.initialize(sm, state, fetch, edata)) {
- sm.setImplData(new String[]{slice.getName()}, true);
+ assignSlice(sm, slice.getName());
return true;
}
}
return false;
-
}
public boolean load(OpenJPAStateManager sm, BitSet fields,
@@ -403,7 +431,7 @@
}
public boolean syncVersion(OpenJPAStateManager sm, Object edata) {
- String[] targets = findSliceNames(sm, edata);
+ String[] targets = findSliceNames(sm, edata).getSlices();
boolean sync = true;
for (String replica : targets) {
SliceStoreManager slice = lookup(replica);
Modified:
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java?rev=728761&r1=728760&r2=728761&view=diff
==============================================================================
---
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java
(original)
+++
openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java
Mon Dec 22 12:22:52 2008
@@ -132,8 +132,8 @@
boolean isReplicated = containsReplicated(ctx);
for (int i = 0; i < owner._queries.size(); i++) {
// if replicated, then execute only on single
slice
- if (i > 0 && isReplicated) {
- continue;
+ if (isReplicated && !usedExecutors.isEmpty()) {
+ break;
}
StoreManager sm =
owner.getDistributedStore().getSlice(i);
if (!targets.contains(sm))
@@ -153,7 +153,6 @@
call.range = range;
futures.add(threadPool.submit(call));
}
-
}
if (parallel) {
for (Future<ResultObjectProvider> future :
futures) {
Modified:
openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/localizer.properties
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/localizer.properties?rev=728761&r1=728760&r2=728761&view=diff
==============================================================================
---
openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/localizer.properties
(original)
+++
openjpa/trunk/openjpa-slice/src/main/resources/org/apache/openjpa/slice/localizer.properties
Mon Dec 22 12:22:52 2008
@@ -18,9 +18,13 @@
"{1}" for "{2}". The valid slices are {3}. This error may happen \
when one or more of the originally configured slices are unavailable \
and Lenient property is set to true.
+no-policy-slice:Distribution policy "{0}" has returned no slice for "{1}". \
+ The valid slices are {2}.
forced-set-config: Configuration property "{0}" is not set explicitly. Setting
\
this value to "{1}".
multithreaded-false: Configuration property "{0}" is set to "false". \
It is recommended to set "{0}" to "true", because Slice executes
database \
operations per slice in parallel in different threads, setting "{0}" to
\
- "false" may cause unpredictable behavior.
\ No newline at end of file
+ "false" may cause unpredictable behavior.
+unknown-impl-data: Encountered unrecognized internal data "{0}" of "{1}" \
+ associated with persistent instance "{2}".
\ No newline at end of file
Modified:
openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/Country.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/Country.java?rev=728761&r1=728760&r2=728761&view=diff
==============================================================================
---
openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/Country.java
(original)
+++
openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/Country.java
Mon Dec 22 12:22:52 2008
@@ -20,37 +20,46 @@
import javax.persistence.Entity;
import javax.persistence.Id;
+import javax.persistence.Version;
import org.apache.openjpa.persistence.Replicated;
/**
- * A persistence entity to be replicated across multiple databases.
- * A non-replicated entity can refer to a replicated entity.
+ * A persistence entity to be replicated across multiple databases. A
+ * non-replicated entity can refer to a replicated entity.
*
* @author Pinaki Poddar
- *
+ *
*/
@Entity
@Replicated
public class Country {
- @Id
- private String name;
-
- private long population;
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public long getPopulation() {
- return population;
- }
-
- public void setPopulation(long population) {
- this.population = population;
- }
+ @Id
+ private String name;
+
+ private long population;
+
+ @Version
+ private int version;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public long getPopulation() {
+ return population;
+ }
+
+ public void setPopulation(long population) {
+ this.population = population;
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
}
Modified:
openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java
URL:
http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java?rev=728761&r1=728760&r2=728761&view=diff
==============================================================================
---
openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java
(original)
+++
openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java
Mon Dec 22 12:22:52 2008
@@ -22,6 +22,7 @@
import java.util.List;
import javax.persistence.EntityManager;
+import javax.persistence.Query;
/**
* Tests basic create, read, update and delete operations.
@@ -55,7 +56,7 @@
PObject pc = new PObject();
pcs.add(pc);
em.persist(pc);
- pc.setValue(i);
+ pc.setValue(10+i);
}
em.getTransaction().commit();
em.clear();
@@ -117,6 +118,33 @@
assertEquals(pc.getId(), pc2.getId());
assertEquals(value, pc2.getValue());
}
+
+ /**
+ * Store and find the same object via reference.
+ */
+ public void testReference() {
+ PObject pc = createIndependentObject();
+ int value = pc.getValue();
+
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ PObject pc2 = em.getReference(PObject.class, pc.getId());
+ assertNotNull(pc2);
+ assertNotEquals(pc, pc2);
+ assertEquals(pc.getId(), pc2.getId());
+ assertEquals(value, pc2.getValue());
+ pc2.setValue(value+1);
+ em.merge(pc2);
+ em.getTransaction().commit();
+ em.clear();
+
+ em.getTransaction().begin();
+ PObject pc3 = em.getReference(PObject.class, pc.getId());
+ assertEquals(value+1, pc3.getValue());
+ em.getTransaction().commit();
+
+ }
+
public void testPersistIndependentObjects() {
int before = count(PObject.class);
@@ -209,9 +237,13 @@
em.getTransaction().commit();
assertEquals(names.length, count(Country.class));
+ em.getTransaction().begin();
Country india = em.find(Country.class, "India");
assertNotNull(india);
assertEquals("India", india.getName());
+ assertTrue(SlicePersistence.isReplicated(india));
+ assertTrue(SlicePersistence.getSlice(india).indexOf("One") != -1);
+ assertTrue(SlicePersistence.getSlice(india).indexOf("Two") != -1);
}
/**
@@ -241,6 +273,21 @@
em.getTransaction().begin();
em.merge(india);
em.getTransaction().commit();
+
+ String[] hints = new String[] {"One", "Two"};
+ String jpql = "select c from Country c where c.name=:name";
+ em.getTransaction().begin();
+ for (String hint : hints) {
+ em.clear();
+ Query query = em.createQuery(jpql).setParameter("name", "India");
+ query.setHint(ProductDerivation.HINT_TARGET, hint);
+ india = (Country)query.getSingleResult();
+ assertEquals(india.getPopulation(), 1201);
+ assertTrue(SlicePersistence.isReplicated(india));
+ assertTrue(SlicePersistence.getSlice(india).indexOf("One") != -1);
+ assertTrue(SlicePersistence.getSlice(india).indexOf("Two") != -1);
+ }
+ em.getTransaction().rollback();
}
public void testQuerySingleObject() {