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() {


Reply via email to