openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Pinaki Poddar <ppod...@apache.org>
Subject Re: svn commit: r698284 - in /openjpa/trunk: openjpa-kernel/src/main/java/org/apache/openjpa/meta/ openjpa-persistence/src/main/java/org/apache/openjpa/persistence/ openjpa-slice/src/main/java/org/apache/openjpa/slice/ openjpa-slice/src/main/java/org
Date Tue, 23 Sep 2008 19:59:41 GMT

> I know I'm being a pain in the butt...
No you are not. You are simply thinking ahead of me. I am documenting this
new feature as we speak. And will commit them 'soon'.


Kevin Sutter wrote:
> 
> Pinaki,
> I know I'm being a pain in the butt...  But, wouldn't these changes also
> require doc updates?  ;-)
> 
> Thanks,
> Kevin
> 
> On Tue, Sep 23, 2008 at 1:58 PM, <ppoddar@apache.org> wrote:
> 
>> Author: ppoddar
>> Date: Tue Sep 23 11:58:00 2008
>> New Revision: 698284
>>
>> URL: http://svn.apache.org/viewvc?rev=698284&view=rev
>> Log:
>> Introduces notion of @Replicated entity. This feature allows to relax
>> collocation constraint for quasi-stationary master data. A replicated
>> entity
>> is stored as identical copies across multiple slices. The
>> ReplicationStrategy works similar to DistributionStrategy for replicated
>> entity. The slice association cardinality has uniformly changed to array
>> of
>> slices from a single slice name both for replicated and non-replicated
>> entity. The non-replicated entities can refer to replicated entities but
>> not
>> vice versa. The query operation (especially the ones with aggregate
>> function) is aware of replicated data and queries only one of the slices
>> to
>> avoid duplication.
>>
>> Added:
>>
>> 
>> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/Replicated.java
>>
>> 
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ReplicationPolicy.java
>>
>> 
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceImplHelper.java
>>
>> 
>> openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/Country.java
>> Modified:
>>
>> 
>> openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
>>
>> 
>> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
>>
>> 
>> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/MetaDataTag.java
>>
>> 
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedBrokerImpl.java
>>
>> 
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java
>>
>> 
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java
>>
>> 
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.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/DistributedJDBCConfigurationImpl.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/test/java/org/apache/openjpa/slice/Address.java
>>
>> 
>> openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/TestBasic.java
>>   
>> openjpa/trunk/openjpa-slice/src/test/resources/META-INF/persistence.xml
>>
>> Modified:
>> openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
>> URL:
>> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java?rev=698284&r1=698283&r2=698284&view=diff
>>
>> ==============================================================================
>> ---
>> openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
>> (original)
>> +++
>> openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java
>> Tue Sep 23 11:58:00 2008
>> @@ -164,7 +164,8 @@
>>     private int _identity = ID_UNKNOWN;
>>     private int _idStrategy = ValueStrategies.NONE;
>>     private int _accessType = ACCESS_UNKNOWN;
>> -
>> +    private boolean _replicated = false;
>> +
>>     private String _seqName = DEFAULT_STRING;
>>     private SequenceMetaData _seqMeta = null;
>>     private String _cacheName = DEFAULT_STRING;
>> @@ -2401,4 +2402,20 @@
>>        Collections.sort(result);
>>        return result.toArray(new String[result.size()]);
>>     }
>> +
>> +    /**
>> +     * Affirms the persistence instances of this receiver is replicated
>> across
>> +     * multiple databases.
>> +     */
>> +    public boolean isReplicated() {
>> +       return _replicated;
>> +    }
>> +
>> +    /**
>> +     * Sets the persistence instances of this receiver to be replicated
>> across
>> +     * multiple databases.
>> +     */
>> +    public void setReplicated(boolean flag) {
>> +       _replicated = flag;
>> +    }
>>  }
>>
>> Modified:
>> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
>> URL:
>> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java?rev=698284&r1=698283&r2=698284&view=diff
>>
>> ==============================================================================
>> ---
>> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
>> (original)
>> +++
>> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java
>> Tue Sep 23 11:58:00 2008
>> @@ -175,6 +175,7 @@
>>         _tags.put(ManagedInterface.class, MANAGED_INTERFACE);
>>         _tags.put(ReadOnly.class, READ_ONLY);
>>         _tags.put(Type.class, TYPE);
>> +        _tags.put(Replicated.class, REPLICATED);
>>     }
>>
>>     private final OpenJPAConfiguration _conf;
>> @@ -577,6 +578,9 @@
>>                     if (isMetaDataMode())
>>                         parseManagedInterface(meta, (ManagedInterface)
>> anno);
>>                     break;
>> +                case REPLICATED:
>> +                       meta.setReplicated(true);
>> +                       break;
>>                 default:
>>                     throw new
>> UnsupportedException(_loc.get("unsupported",
>> _cls,
>>                         anno.toString()));
>>
>> Modified:
>> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/MetaDataTag.java
>> URL:
>> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/MetaDataTag.java?rev=698284&r1=698283&r2=698284&view=diff
>>
>> ==============================================================================
>> ---
>> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/MetaDataTag.java
>> (original)
>> +++
>> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/MetaDataTag.java
>> Tue Sep 23 11:58:00 2008
>> @@ -80,4 +80,5 @@
>>     MANAGED_INTERFACE,
>>     READ_ONLY,
>>     TYPE,
>> +    REPLICATED
>>  }
>>
>> Added:
>> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/Replicated.java
>> URL:
>> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/Replicated.java?rev=698284&view=auto
>>
>> ==============================================================================
>> ---
>> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/Replicated.java
>> (added)
>> +++
>> openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/Replicated.java
>> Tue Sep 23 11:58:00 2008
>> @@ -0,0 +1,44 @@
>> +/*
>> + * Licensed to the Apache Software Foundation (ASF) under one
>> + * or more contributor license agreements.  See the NOTICE file
>> + * distributed with this work for additional information
>> + * regarding copyright ownership.  The ASF licenses this file
>> + * to you under the Apache License, Version 2.0 (the
>> + * "License"); you may not use this file except in compliance
>> + * with the License.  You may obtain a copy of the License at
>> + *
>> + * http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + * Unless required by applicable law or agreed to in writing,
>> + * software distributed under the License is distributed on an
>> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>> + * KIND, either express or implied.  See the License for the
>> + * specific language governing permissions and limitations
>> + * under the License.
>> + */
>> +package org.apache.openjpa.persistence;
>> +
>> +import static java.lang.annotation.ElementType.TYPE;
>> +import static java.lang.annotation.RetentionPolicy.RUNTIME;
>> +
>> +import java.lang.annotation.Retention;
>> +import java.lang.annotation.Target;
>> +
>> +/**
>> + * Annotation to specify the instance of the annotated entity be
>> + * replicated across more than one <em>slices</em>. The actual slices
>> where an
>> + * instance of the annotated entity will be replicated is determined by
>> + * the return value of user-specified
>> + * {@link ReplicationPolicy#replicate(Object, java.util.List, Object)}
>> + * method.
>> + *
>> + * @see ReplicationPolicy
>> + *
>> + * @author Pinaki Poddar
>> + *
>> + */
>> +@Target({ TYPE })
>> +@Retention(RUNTIME)
>> +public @interface Replicated {
>> +
>> +}
>>
>> 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=698284&r1=698283&r2=698284&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
>> Tue Sep 23 11:58:00 2008
>> @@ -22,7 +22,6 @@
>>  import org.apache.openjpa.kernel.OpCallbacks;
>>  import org.apache.openjpa.kernel.OpenJPAStateManager;
>>  import org.apache.openjpa.lib.util.Localizer;
>> -import org.apache.openjpa.util.UserException;
>>
>>  /**
>>  * A specialized Broker to associate slice identifiers with the
>> StateManagers as
>> @@ -36,11 +35,17 @@
>>  */
>>  @SuppressWarnings("serial")
>>  public class DistributedBrokerImpl extends FinalizingBrokerImpl {
>> -       private transient String slice;
>> -
>> +       private transient String _rootSlice;
>> +       private transient DistributedConfiguration _conf;
>>        private static final Localizer _loc =
>>                        Localizer.forPackage(DistributedBrokerImpl.class);
>>
>> +    public DistributedConfiguration getConfiguration() {
>> +       if (_conf == null) {
>> +               _conf =
>> (DistributedConfiguration)super.getConfiguration();
>> +       }
>> +        return _conf;
>> +    }
>>        /**
>>         * Assigns slice identifier to the resultant StateManager as
>> initialized by
>>         * the super class implementation. The slice identifier is decided
>> by
>> @@ -54,32 +59,28 @@
>>        public OpenJPAStateManager persist(Object pc, Object id, boolean
>> explicit,
>>                        OpCallbacks call) {
>>                OpenJPAStateManager sm = getStateManager(pc);
>> +               String[] targets = null;
>> +               boolean replicated = SliceImplHelper.isReplicated(sm);
>>                if (getOperatingSet().isEmpty()
>> -                               && (sm == null || sm.getImplData() ==
>> null)) {
>> -                       slice = getSlice(pc);
>> +                       && (sm == null || sm.getImplData() == null)) {
>> +                       targets = SliceImplHelper.getSlicesByPolicy(pc,
>> getConfiguration(),
>> +                               this);
>> +                       if (!replicated) {
>> +                               _rootSlice = targets[0];
>> +                       }
>>                }
>>                sm = super.persist(pc, id, explicit, call);
>> -               if (sm.getImplData() == null)
>> -                       sm.setImplData(slice, true);
>> -
>> +               if (sm.getImplData() == null) {
>> +                       if (targets == null) {
>> +                          targets = replicated
>> +                          ? SliceImplHelper.getSlicesByPolicy(pc,
>> getConfiguration(), this)
>> +                          : new String[]{_rootSlice};
>> +                       }
>> +                       sm.setImplData(targets, true);
>> +               }
>>                return sm;
>>        }
>>
>> -       /**
>> -        * Gets the slice by the user-defined distribution policy.
>> -        */
>> -       String getSlice(Object pc) {
>> -               DistributedConfiguration conf =
>> -                               (DistributedConfiguration)
>> getConfiguration();
>> -               String slice =
>> -
>> (conf.getDistributionPolicyInstance().distribute(pc, conf
>> -                                               .getActiveSliceNames(),
>> this));
>> -               if (!conf.getActiveSliceNames().contains(slice))
>> -                       throw new
>> UserException(_loc.get("bad-policy-slice", new Object[] {
>> -
>> conf.getDistributionPolicyInstance().getClass().getName(),
>> -                                       slice, pc,
>> conf.getActiveSliceNames() }));
>> -               return slice;
>> -       }
>>
>>        @Override
>>        public boolean endOperation() {
>>
>> Modified:
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java
>> URL:
>> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java?rev=698284&r1=698283&r2=698284&view=diff
>>
>> ==============================================================================
>> ---
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java
>> (original)
>> +++
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributedConfiguration.java
>> Tue Sep 23 11:58:00 2008
>> @@ -75,4 +75,10 @@
>>         * the available slices.
>>         */
>>        DistributionPolicy getDistributionPolicyInstance();
>> +
>> +       /**
>> +        * Gets the policy that governs how new replicated instances will
>> be
>> +        * replicated across the available slices.
>> +        */
>> +       ReplicationPolicy getReplicationPolicyInstance();
>>  }
>>
>> Modified:
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java
>> URL:
>> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java?rev=698284&r1=698283&r2=698284&view=diff
>>
>> ==============================================================================
>> ---
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java
>> (original)
>> +++
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/DistributionPolicy.java
>> Tue Sep 23 11:58:00 2008
>> @@ -19,6 +19,7 @@
>>  package org.apache.openjpa.slice;
>>
>>  import java.util.List;
>> +import java.util.Random;
>>
>>
>>  /**
>> @@ -44,4 +45,16 @@
>>         * @see DistributedConfiguration#getActiveSliceNames()
>>         */
>>        String distribute(Object pc, List<String> slices, Object context);
>> +
>> +       /**
>> +        * Implements a default distribution policy to store the given
>> +        * instance to a randomly selected available slice.
>> +        *
>> +        */
>> +       public static class Default implements DistributionPolicy {
>> +               private static Random RNG = new Random();
>> +               public String distribute(Object pc, List<String> slices,
>> Object ctx) {
>> +                       return slices.get(RNG.nextInt(slices.size()));
>> +               }
>> +       }
>>  }
>>
>> Modified:
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java
>> URL:
>> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java?rev=698284&r1=698283&r2=698284&view=diff
>>
>> ==============================================================================
>> ---
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java
>> (original)
>> +++
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ProductDerivation.java
>> Tue Sep 23 11:58:00 2008
>> @@ -22,7 +22,9 @@
>>
>>  import org.apache.openjpa.conf.OpenJPAProductDerivation;
>>  import org.apache.openjpa.lib.conf.AbstractProductDerivation;
>> +import org.apache.openjpa.lib.conf.Configuration;
>>  import org.apache.openjpa.slice.jdbc.DistributedJDBCBrokerFactory;
>> +import org.apache.openjpa.slice.jdbc.DistributedJDBCConfigurationImpl;
>>
>>  /**
>>  * Derives configuration for Slice.
>> @@ -58,6 +60,28 @@
>>        }
>>
>>        public int getType() {
>> -               return TYPE_FEATURE;
>> +               return TYPE_STORE;
>>        }
>> +
>> +       /**
>> +        * Sets the {@link DistributionPolicy} and {@link
>> ReplicationPolicy} to
>> +        * their respective defaults if not set by the user.
>> +        */
>> +    @Override
>> +    public boolean afterSpecificationSet(Configuration c) {
>> +        if (!(c instanceof DistributedJDBCConfigurationImpl))
>> +            return false;
>> +        DistributedJDBCConfigurationImpl conf =
>> +               (DistributedJDBCConfigurationImpl)c;
>> +        boolean modified = false;
>> +        if (conf.getDistributionPolicyInstance() == null) {
>> +               conf.distributionPolicyPlugin.setString("random");
>> +               modified = true;
>> +        }
>> +        if (conf.getReplicationPolicyInstance() == null) {
>> +               conf.replicationPolicyPlugin.setString("all");
>> +               modified = true;
>> +        }
>> +        return modified;
>> +    }
>>  }
>>
>> Added:
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ReplicationPolicy.java
>> URL:
>> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ReplicationPolicy.java?rev=698284&view=auto
>>
>> ==============================================================================
>> ---
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ReplicationPolicy.java
>> (added)
>> +++
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/ReplicationPolicy.java
>> Tue Sep 23 11:58:00 2008
>> @@ -0,0 +1,60 @@
>> +/*
>> + * 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.util.List;
>> +
>> +
>> +/**
>> + * Policy to select one of the physical databases referred as
>> <em>slice</em>
>> + * in which a given persistent instance will be replicated.
>> + *
>> + * @author Pinaki Poddar
>> + *
>> + */
>> +public interface ReplicationPolicy {
>> +       /**
>> +        * Gets the name of the slices where a given instance will be
>> replicated.
>> +        *
>> +        * @param pc The newly persistent or to-be-merged object.
>> +        * @param slices list of names of the active slices. The ordering
>> of
>> +        * the list is either explicit <code>openjpa.slice.Names</code>
>> property
>> +        * or implicit i.e. alphabetic order of available identifiers if
>> +        * <code>openjpa.slice.Names</code> is unspecified.
>> +        * @param context generic persistence context managing the given
>> instance.
>> +        *
>> +        * @return identifier of the slices. This names must match one of
>> the
>> +        * given slice names. Return null or empty list to imply all
>> active
>> slices.
>> +        *
>> +        * @see DistributedConfiguration#getActiveSliceNames()
>> +        */
>> +       String[] replicate(Object pc, List<String> slices, Object
>> context);
>> +
>> +       /**
>> +        * Implements a default replication policy to replicate the given
>> +        * instance across all available slices.
>> +        *
>> +        */
>> +       public static class Default implements ReplicationPolicy {
>> +               public String[] replicate(Object pc, List<String> slices,
>> +                       Object context) {
>> +                       return null;
>> +               }
>> +       }
>> +}
>>
>> Added:
>> 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=698284&view=auto
>>
>> ==============================================================================
>> ---
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceImplHelper.java
>> (added)
>> +++
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/SliceImplHelper.java
>> Tue Sep 23 11:58:00 2008
>> @@ -0,0 +1,88 @@
>> +/*
>> + * 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.util.List;
>> +
>> +import org.apache.openjpa.conf.OpenJPAConfiguration;
>> +import org.apache.openjpa.kernel.OpenJPAStateManager;
>> +import org.apache.openjpa.lib.util.Localizer;
>> +import org.apache.openjpa.meta.ClassMetaData;
>> +import org.apache.openjpa.util.UserException;
>> +
>> +/**
>> + * Utility methods to determine the target slices for a persistence
>> capable
>> + * instance by calling back to user-specified distribution policy.
>> + *
>> + * @author Pinaki Poddar
>> + *
>> + */
>> +public class SliceImplHelper {
>> +       private static final Localizer _loc =
>> +               Localizer.forPackage(SliceImplHelper.class);
>> +
>> +       /**
>> +        * Gets the target slices by calling user-specified
>> +        * {@link DistributionPolicy} or {@link ReplicationPolicy}
>> +        * depending on whether the given instance is {@link Replicated
>> replicated}.
>> +        */
>> +       public static String[] getSlicesByPolicy(Object pc,
>> +                       DistributedConfiguration conf, Object ctx) {
>> +               List<String> availables = conf.getActiveSliceNames();
>> +               Object policy = null;
>> +               String[] targets = null;
>> +               if (isReplicated(pc, conf)) {
>> +                       policy = conf.getReplicationPolicyInstance();
>> +                       targets = ((ReplicationPolicy)policy).replicate
>> +                               (pc, availables, ctx);
>> +                       if (targets == null || targets.length == 0)
>> +                               targets = availables.toArray(new
>> String[availables.size()]);
>> +               } else {
>> +                       policy = conf.getDistributionPolicyInstance();
>> +                       String slice =
>> ((DistributionPolicy)policy).distribute
>> +                               (pc, availables, ctx);
>> +                       targets = new String[]{slice};
>> +               }
>> +               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;
>> +       }
>> +
>> +       /**
>> +        * Affirms if the given instance be replicated to multiple
>> slices.
>> +        */
>> +       public static boolean isReplicated(Object pc,
>> OpenJPAConfiguration
>> conf) {
>> +               if (pc == null)
>> +                       return false;
>> +               ClassMetaData meta = conf.getMetaDataRepositoryInstance()
>> +                       .getMetaData(pc.getClass(), null, false);
>> +               return (meta == null) ? false : meta.isReplicated();
>> +       }
>> +
>> +       /**
>> +        * Affirms if the given instance be replicated to multiple
>> slices.
>> +        */
>> +       public static boolean isReplicated(OpenJPAStateManager sm) {
>> +               if (sm == null)
>> +                       return false;
>> +               return sm.getMetaData().isReplicated();
>> +       }
>> +}
>>
>> 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=698284&r1=698283&r2=698284&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
>> Tue Sep 23 11:58:00 2008
>> @@ -18,6 +18,8 @@
>>  */
>>  package org.apache.openjpa.slice;
>>
>> +import java.util.Arrays;
>> +
>>  import org.apache.openjpa.enhance.PersistenceCapable;
>>  import org.apache.openjpa.kernel.StateManagerImpl;
>>  import org.apache.openjpa.util.ImplHelper;
>> @@ -32,6 +34,8 @@
>>        /**
>>         * Get the slice identifier for the given instance if it is a
>> managed
>>         * instance and has been assigned to a slice.
>> +        * If the given instance is replicated across multiple slices
>> then
>> returns
>> +        * comma-separated list of slice names.
>>         *
>>         * @return name of the slice, if any. null otherwise.
>>         */
>> @@ -45,6 +49,13 @@
>>                if (sm == null)
>>                        return null;
>>                Object slice = sm.getImplData();
>> -               return (slice instanceof String) ? (String)slice : null;
>> +               if (slice instanceof String[]) {
>> +                       if (((String[])slice).length == 1) {
>> +                               return ((String[])slice)[0];
>> +                       } else {
>> +                               return
>> Arrays.toString(((String[])slice));
>> +                       }
>> +               }
>> +               return null;
>>        }
>>  }
>>
>> Modified:
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java
>> URL:
>> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java?rev=698284&r1=698283&r2=698284&view=diff
>>
>> ==============================================================================
>> ---
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java
>> (original)
>> +++
>> openjpa/trunk/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCConfigurationImpl.java
>> Tue Sep 23 11:58:00 2008
>> @@ -49,6 +49,7 @@
>>  import org.apache.openjpa.slice.DistributionPolicy;
>>  import org.apache.openjpa.slice.ExecutorServiceValue;
>>  import org.apache.openjpa.slice.ProductDerivation;
>> +import org.apache.openjpa.slice.ReplicationPolicy;
>>  import org.apache.openjpa.slice.Slice;
>>  import org.apache.openjpa.util.UserException;
>>
>> @@ -73,11 +74,13 @@
>>     protected StringValue masterPlugin;
>>     protected StringListValue namesPlugin;
>>     protected ExecutorServiceValue executorServicePlugin;
>> -    protected PluginValue distributionPolicyPlugin;
>> +    public PluginValue distributionPolicyPlugin;
>> +    public PluginValue replicationPolicyPlugin;
>>
>>     public static final String DOT = ".";
>>     public static final String REGEX_DOT = "\\.";
>> -    public static final String PREFIX_SLICE =
>> ProductDerivation.PREFIX_SLICE + DOT;
>> +    public static final String PREFIX_SLICE =
>> ProductDerivation.PREFIX_SLICE +
>> +       DOT;
>>     public static final String PREFIX_OPENJPA = "openjpa.";
>>     private static Localizer _loc =
>>             Localizer.forPackage(DistributedJDBCConfigurationImpl.class);
>> @@ -95,8 +98,18 @@
>>         brokerPlugin.setString(DistributedBrokerImpl.class.getName());
>>
>>         distributionPolicyPlugin = addPlugin("DistributionPolicy", true);
>> +        distributionPolicyPlugin.setAlias("random",
>> +               DistributionPolicy.Default.class.getName());
>> +        distributionPolicyPlugin.setDefault("random");
>>         distributionPolicyPlugin.setDynamic(true);
>>
>> +        replicationPolicyPlugin = addPlugin
>> +               ("ReplicatedDistributionPolicy", true);
>> +        replicationPolicyPlugin.setAlias("all",
>> +               ReplicationPolicy.Default.class.getName());
>> +        replicationPolicyPlugin.setDefault("all");
>> +        replicationPolicyPlugin.setDynamic(true);
>> +
>>         lenientPlugin = addBoolean("Lenient");
>>
>>         masterPlugin = addString("Master");
>> @@ -185,6 +198,18 @@
>>     }
>>
>>     public void setDistributionPolicyInstance(String val) {
>> +       replicationPolicyPlugin.set(val);
>> +    }
>> +
>> +    public ReplicationPolicy getReplicationPolicyInstance() {
>> +        if (replicationPolicyPlugin.get() == null) {
>> +
>> replicationPolicyPlugin.instantiate(ReplicationPolicy.class,
>> +                    this, true);
>> +        }
>> +        return (ReplicationPolicy) replicationPolicyPlugin.get();
>> +    }
>> +
>> +    public void setReplicatedDistributionPolicyInstance(String val) {
>>         distributionPolicyPlugin.set(val);
>>     }
>>
>>
>> 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=698284&r1=698283&r2=698284&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
>> Tue Sep 23 11:58:00 2008
>> @@ -18,6 +18,7 @@
>>  */
>>  package org.apache.openjpa.slice.jdbc;
>>
>> +import java.io.IOException;
>>  import java.sql.Connection;
>>  import java.sql.SQLException;
>>  import java.util.ArrayList;
>> @@ -42,6 +43,7 @@
>>  import org.apache.openjpa.kernel.FetchConfiguration;
>>  import org.apache.openjpa.kernel.OpenJPAStateManager;
>>  import org.apache.openjpa.kernel.PCState;
>> +import org.apache.openjpa.kernel.QueryContext;
>>  import org.apache.openjpa.kernel.QueryLanguages;
>>  import org.apache.openjpa.kernel.Seq;
>>  import org.apache.openjpa.kernel.StoreContext;
>> @@ -54,10 +56,15 @@
>>  import org.apache.openjpa.meta.ClassMetaData;
>>  import org.apache.openjpa.meta.FieldMetaData;
>>  import org.apache.openjpa.slice.DistributionPolicy;
>> +import org.apache.openjpa.slice.SliceImplHelper;
>>  import org.apache.openjpa.slice.ProductDerivation;
>> +import org.apache.openjpa.slice.ReplicationPolicy;
>>  import org.apache.openjpa.util.InternalException;
>>  import org.apache.openjpa.util.StoreException;
>>  import org.apache.openjpa.util.UserException;
>> +import org.apache.tools.ant.taskdefs.condition.IsReference;
>> +
>> +import sun.reflect.ReflectionFactory.GetReflectionFactoryAction;
>>
>>  /**
>>  * A Store manager for multiple physical databases referred as
>> <em>slice</em>.
>> @@ -109,71 +116,70 @@
>>
>>     /**
>>      * Decides the index of the StoreManager by first looking at the
>> -     * implementation data. If not found then {@link DistributionPolicy
>> -     * DistributionPolicy} determines the target store for new instances
>> and
>> -     * additional connection info is used to estimate for the existing
>> -     * instances.
>> +     * implementation data. If no implementation data is found, then
>> estimates
>> +     * targets slices by using additional connection info. If no
>> additional
>> +     * connection info then calls back to user-defined policy.
>>      */
>> -    protected String findSliceName(OpenJPAStateManager sm, Object info)
>> {
>> -        boolean hasIndex = hasSlice(sm);
>> -        if (hasIndex)
>> -            return sm.getImplData().toString();
>> -        String slice = estimateSlice(sm, info);
>> -        if (slice == null)
>> +    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 slice;
>> -    }
>> -
>> -    private boolean hasSlice(OpenJPAStateManager sm) {
>> -        return sm.getImplData() != null;
>> +        return targets;
>>     }
>> -
>> -    private String assignSlice(OpenJPAStateManager sm) {
>> -        Object pc = sm.getPersistenceCapable();
>> -        DistributionPolicy policy =
>> _conf.getDistributionPolicyInstance();
>> -        List<String> sliceNames = _conf.getActiveSliceNames();
>> -        String slice =policy.distribute(pc, sliceNames, getContext());
>> -        if (!sliceNames.contains(slice)) {
>> -            throw new UserException(_loc.get("bad-policy-slice", new
>> Object[] {
>> -                    policy.getClass().getName(), slice, pc, sliceNames
>> }));
>> -        }
>> -        sm.setImplData(slice, true);
>> -        return slice;
>> +
>> +    private String[] assignSlice(OpenJPAStateManager sm) {
>> +       Object pc = sm.getPersistenceCapable();
>> +       String[] targets = SliceImplHelper.getSlicesByPolicy(pc, _conf,
>> +                       getContext());
>> +        sm.setImplData(targets, true);
>> +        return targets;
>>     }
>> -
>> +
>>     /**
>>      * The additional edata is used, if possible, to find the
>> StoreManager
>>      * managing the given StateManager. If the additional data is
>> unavailable
>>      * 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) {
>> -                    String sliceId = slice.getName();
>> -                    sm.setImplData(sliceId, true);
>> -                    return sliceId;
>> +                       if (temps == null)
>> +                               temps = new ArrayList<String>();
>> +                    temps.add(slice.getName());
>>                 }
>>             }
>>         }
>> -        return null;
>> +        if (temps != null) {
>> +               String[] targets = temps.toArray(new
>> String[temps.size()]);
>> +               sm.setImplData(targets, true);
>> +               return targets;
>> +        }
>> +        return null;
>>     }
>>
>>     /**
>> -     * Selects a child StoreManager where the given instance resides.
>> +     * Selects child StoreManager(s) where the given instance resides.
>>      */
>>     private StoreManager selectStore(OpenJPAStateManager sm, Object
>> edata)
>> {
>> -        String name = findSliceName(sm, edata);
>> -        SliceStoreManager slice = lookup(name);
>> -        if (slice == null)
>> -            throw new InternalException(_loc.get("wrong-slice", name,
>> sm));
>> -        return slice;
>> +        String[] targets = findSliceNames(sm, edata);
>> +        for (String target : targets) {
>> +               SliceStoreManager slice = lookup(target);
>> +               if (slice == null)
>> +                       throw new
>> InternalException(_loc.get("wrong-slice",
>> target, sm));
>> +               return slice;
>> +        }
>> +        return null;
>>     }
>>
>>     public boolean assignField(OpenJPAStateManager sm, int field,
>> @@ -222,13 +228,16 @@
>>     }
>>
>>     public boolean exists(OpenJPAStateManager sm, Object edata) {
>> +       List<String> targets = null;
>>         for (SliceStoreManager slice : _slices) {
>>             if (slice.exists(sm, edata)) {
>> -                sm.setImplData(slice.getName(), true);
>> -                return true;
>> +               if (targets == null)
>> +                       targets.add(slice.getName());
>>             }
>>         }
>> -        return false;
>> +        if (targets != null)
>> +               sm.setImplData(targets.toArray(new
>> String[targets.size()]),
>> true);
>> +        return targets != null;
>>     }
>>
>>
>> @@ -244,7 +253,11 @@
>>             List<OpenJPAStateManager> subset =
>> subsets.get(slice.getName());
>>             if (subset.isEmpty())
>>                 continue;
>> -            futures.add(threadPool.submit(new Flusher(slice, subset)));
>> +            if (containsReplicated(subset)) {
>> +               slice.flush(subset);
>> +            } else {
>> +               futures.add(threadPool.submit(new Flusher(slice,
>> subset)));
>> +            }
>>         }
>>         for (Future<Collection> future : futures) {
>>             Collection error;
>> @@ -262,12 +275,16 @@
>>         return exceptions;
>>     }
>>
>> +    boolean containsReplicated(List<OpenJPAStateManager> sms) {
>> +       for (OpenJPAStateManager sm : sms)
>> +               if (sm.getMetaData().isReplicated())
>> +                       return true;
>> +       return false;
>> +    }
>> +
>>     /**
>>      * Separate the given list of StateManagers in separate lists for
>> each
>> slice
>>      * by the associated slice identifier of each StateManager.
>> -     * @param sms
>> -     * @param edata
>> -     * @return
>>      */
>>     private Map<String, List<OpenJPAStateManager>> bin(
>>             Collection/*<StateManage>*/ sms, Object edata) {
>> @@ -277,8 +294,10 @@
>>             subsets.put(slice.getName(), new
>> ArrayList<OpenJPAStateManager>());
>>         for (Object x : sms) {
>>             OpenJPAStateManager sm = (OpenJPAStateManager) x;
>> -            String slice = findSliceName(sm, edata);
>> -            subsets.get(slice).add(sm);
>> +            String[] targets = findSliceNames(sm, edata);
>> +               for (String slice : targets) {
>> +               subsets.get(slice).add(sm);
>> +            }
>>         }
>>         return subsets;
>>     }
>> @@ -306,15 +325,15 @@
>>     public boolean initialize(OpenJPAStateManager sm, PCState state,
>>             FetchConfiguration fetch, Object edata) {
>>         if (edata instanceof ConnectionInfo) {
>> -            String slice = findSliceName(sm, (ConnectionInfo) edata);
>> -            if (slice != null)
>> -                return lookup(slice).initialize(sm, state, fetch,
>> edata);
>> +            String[] targets = findSliceNames(sm, (ConnectionInfo)
>> edata);
>> +            if (targets != null || targets.length > 0)
>> +                return lookup(targets[0]).initialize(sm, state, fetch,
>> edata);
>>         }
>>         // 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(slice.getName(), true);
>> +                sm.setImplData(new String[]{slice.getName()}, true);
>>                 return true;
>>             }
>>         }
>> @@ -381,7 +400,13 @@
>>     }
>>
>>     public boolean syncVersion(OpenJPAStateManager sm, Object edata) {
>> -        return selectStore(sm, edata).syncVersion(sm, edata);
>> +       String[] targets = findSliceNames(sm, edata);
>> +       boolean sync = true;
>> +       for (String replica : targets) {
>> +               SliceStoreManager slice = lookup(replica);
>> +               sync &= slice.syncVersion(sm, edata);
>> +       }
>> +       return sync;
>>     }
>>
>>     @Override
>>
>> 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=698284&r1=698283&r2=698284&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
>> Tue Sep 23 11:58:00 2008
>> @@ -77,7 +77,7 @@
>>
>>     public void setContext(QueryContext ctx) {
>>        super.setContext(ctx);
>> -       for (StoreQuery q:_queries)
>> +       for (StoreQuery q : _queries)
>>                q.setContext(ctx);
>>     }
>>
>> @@ -124,6 +124,9 @@
>>                        StoreManager sm  =
>> owner.getDistributedStore().getSlice(i);
>>                        if (!targets.contains(sm))
>>                                continue;
>> +                       // if replicated, then execute only on single
>> slice
>> +                       if (i > 0 &&
>> containsReplicated(query.getContext()))
>> +                               continue;
>>                        QueryExecutor call = new QueryExecutor();
>>                        call.executor = executors.get(i);
>>                        call.query    = query;
>> @@ -164,6 +167,27 @@
>>                return result;
>>         }
>>
>> +        /**
>> +                * Scans metadata to find out if a replicated class is
>> the
>> candidate.
>> +        **/
>> +        boolean containsReplicated(QueryContext query) {
>> +               Class candidate = query.getCandidateType();
>> +               if (candidate != null) {
>> +                       ClassMetaData meta =
>> query.getStoreContext().getConfiguration()
>> +                               .getMetaDataRepositoryInstance()
>> +                               .getMetaData(candidate, null, true);
>> +                       if (meta != null && meta.isReplicated())
>> +                               return true;
>> +               }
>> +               ClassMetaData[] metas = query.getAccessPathMetaDatas();
>> +               if (metas == null || metas.length < 1)
>> +                       return false;
>> +               for (ClassMetaData type : metas)
>> +                       if (type.isReplicated())
>> +                               return true;
>> +               return false;
>> +        }
>> +
>>         public Number executeDelete(StoreQuery q, Object[] params) {
>>                Iterator<StoreQuery> qs = owner._queries.iterator();
>>                final List<Future<Number>> futures = new
>> ArrayList<Future<Number>>();
>>
>> Modified:
>> openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/Address.java
>> URL:
>> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/Address.java?rev=698284&r1=698283&r2=698284&view=diff
>>
>> ==============================================================================
>> ---
>> openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/Address.java
>> (original)
>> +++
>> openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/Address.java
>> Tue Sep 23 11:58:00 2008
>> @@ -28,6 +28,9 @@
>>
>>     private String city;
>>     private int zip;
>> +
>> +    @OneToOne
>> +    private Country country;
>>
>>     @OneToOne(mappedBy = "address")
>>     Person owner;
>> @@ -79,4 +82,12 @@
>>     public String toString() {
>>         return city;
>>     }
>> +
>> +       public Country getCountry() {
>> +               return country;
>> +       }
>> +
>> +       public void setCountry(Country country) {
>> +               this.country = country;
>> +       }
>>  }
>>
>> Added:
>> 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=698284&view=auto
>>
>> ==============================================================================
>> ---
>> openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/Country.java
>> (added)
>> +++
>> openjpa/trunk/openjpa-slice/src/test/java/org/apache/openjpa/slice/Country.java
>> Tue Sep 23 11:58:00 2008
>> @@ -0,0 +1,56 @@
>> +/*
>> + * 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 javax.persistence.Entity;
>> +import javax.persistence.Id;
>> +
>> +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.
>> + *
>> + * @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;
>> +       }
>> +}
>>
>> 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=698284&r1=698283&r2=698284&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
>> Tue Sep 23 11:58:00 2008
>> @@ -30,18 +30,22 @@
>>  *
>>  */
>>  public class TestBasic extends SliceTestCase {
>> -
>> +    /**
>> +     * Specify persistence unit name as System property
>> <code>-Dunit</code> or
>> +     * use the default value as <code>"slice"</code>.
>> +     */
>>     protected String getPersistenceUnitName() {
>> -        return "slice";
>> +        return System.getProperty("unit","slice");
>>     }
>>
>>
>>     public void setUp() throws Exception {
>> -        super.setUp(PObject.class, Person.class, Address.class,
>> CLEAR_TABLES);
>> +        super.setUp(PObject.class, Person.class, Address.class,
>> Country.class,
>> +               CLEAR_TABLES);
>>     }
>>
>>     /**
>> -     * Persist N objects.
>> +     * Persist N independent objects.
>>      */
>>     List<PObject> create(int N) {
>>         List<PObject> pcs = new ArrayList<PObject>();
>> @@ -128,18 +132,25 @@
>>     }
>>
>>     public void testPersistConnectedObjectGraph() {
>> +        EntityManager em = emf.createEntityManager();
>> +        em.getTransaction().begin();
>>         Person p1 = new Person("A");
>>         Person p2 = new Person("B");
>>         Person p3 = new Person("C");
>>         Address a1 = new Address("Rome", 12345);
>>         Address a2 = new Address("San Francisco", 23456);
>>         Address a3 = new Address("New York", 34567);
>> +        Country c1 = em.find(Country.class, "Italy");
>> +        if (c1 == null) {
>> +               c1 = new Country();
>> +               c1.setName("Italy");
>> +               em.persist(c1);
>> +        }
>> +       a1.setCountry(c1);
>>         p1.setAddress(a1);
>>         p2.setAddress(a2);
>>         p3.setAddress(a3);
>>
>> -        EntityManager em = emf.createEntityManager();
>> -        em.getTransaction().begin();
>>         em.persist(p1);
>>         em.persist(p2);
>>         em.persist(p3);
>> @@ -185,5 +196,46 @@
>>         assertEquals(pc.getId(), pc2.getId());
>>         assertEquals(value + 1, pc2.getValue());
>>     }
>> +
>> +    public void testPersistReplicatedObjects() {
>> +        EntityManager em = emf.createEntityManager();
>> +        em.getTransaction().begin();
>> +        String[] names = {"USA", "India", "China"};
>> +        for (String name : names) {
>> +               Country country = new Country();
>> +               country.setName(name);
>> +               em.persist(country);
>> +        }
>> +        em.getTransaction().commit();
>> +        assertEquals(names.length, count(Country.class));
>> +
>> +        Country india = em.find(Country.class, "India");
>> +        assertNotNull(india);
>> +        assertEquals("India", india.getName());
>> +    }
>> +
>> +    public void testUpdateReplicatedObjects() {
>> +        EntityManager em = emf.createEntityManager();
>> +        em.getTransaction().begin();
>> +        String[] names = {"USA", "India", "China"};
>> +        long[] population = {300,1200,1400};
>> +        for (int i = 0; i < names.length; i++) {
>> +               Country country = new Country();
>> +               country.setName(names[i]);
>> +               country.setPopulation(population[i]);
>> +               em.persist(country);
>> +        }
>> +        em.getTransaction().commit();
>> +
>> +        assertEquals(names.length, count(Country.class));
>> +        Country india = em.find(Country.class, "India");
>> +
>> +        assertNotNull(india);
>> +        assertEquals("India", india.getName());
>> +        india.setPopulation(1201);
>> +        em.getTransaction().begin();
>> +        em.merge(india);
>> +        em.getTransaction().commit();
>> +    }
>>
>>  }
>>
>> Modified:
>> openjpa/trunk/openjpa-slice/src/test/resources/META-INF/persistence.xml
>> URL:
>> http://svn.apache.org/viewvc/openjpa/trunk/openjpa-slice/src/test/resources/META-INF/persistence.xml?rev=698284&r1=698283&r2=698284&view=diff
>>
>> ==============================================================================
>> ---
>> openjpa/trunk/openjpa-slice/src/test/resources/META-INF/persistence.xml
>> (original)
>> +++
>> openjpa/trunk/openjpa-slice/src/test/resources/META-INF/persistence.xml
>> Tue Sep 23 11:58:00 2008
>> @@ -22,6 +22,7 @@
>>         <class>org.apache.openjpa.slice.PObject</class>
>>         <class>org.apache.openjpa.slice.Person</class>
>>         <class>org.apache.openjpa.slice.Address</class>
>> +        <class>org.apache.openjpa.slice.Country</class>
>>         <properties>
>>          <property name="openjpa.Log" value="DefaultLevel=WARN,
>> Enhance=TRACE"/>
>>         </properties>
>> @@ -83,6 +84,7 @@
>>         <class>org.apache.openjpa.slice.PObject</class>
>>         <class>org.apache.openjpa.slice.Person</class>
>>         <class>org.apache.openjpa.slice.Address</class>
>> +        <class>org.apache.openjpa.slice.Country</class>
>>                <properties>
>>             <property name="openjpa.BrokerFactory" value="slice"/>
>>             <property name="openjpa.ConnectionDriverName"
>> value="org.apache.derby.jdbc.EmbeddedDriver"/>
>> @@ -122,4 +124,28 @@
>>             <property name="openjpa.jdbc.MappingDefaults"
>> value="DefaultMissingInfo=true"/>
>>         </properties>
>>    </persistence-unit>
>> +
>> +   <persistence-unit name="mysql">
>> +      <properties>
>> +         <property name="openjpa.BrokerFactory" value="slice"/>
>> +         <property name="openjpa.ConnectionDriverName"
>> value="com.mysql.jdbc.Driver"/>
>> +
>> +         <property name="openjpa.slice.Names" value="One,Two"/>
>> +         <property name="openjpa.slice.DistributionPolicy"
>> value="org.apache.openjpa.slice.policy.UserDistributionPolicy"/>
>> +
>> +         <property name="openjpa.ConnectionUserName"       
>> value="root"/>
>> +         <property name="openjpa.ConnectionPassword"        value=""/>
>> +         <property name="openjpa.slice.One.ConnectionDriverName"
>> value="com.mysql.jdbc.Driver"/>
>> +         <property name="openjpa.slice.One.ConnectionURL"
>> value="jdbc:mysql://localhost/slice1"/>
>> +         <property name="openjpa.slice.Two.ConnectionDriverName"
>> value="com.mysql.jdbc.Driver"/>
>> +         <property name="openjpa.slice.Two.ConnectionURL"
>> value="jdbc:mysql://localhost/slice2"/>
>> +
>> +         <property name="openjpa.Multithreaded" value="false"/>
>> +         <property name="openjpa.Log" value="DefaultLevel=INFO,
>> Enhance=TRACE, SQL=TRACE"/>
>> +         <property name="openjpa.jdbc.SynchronizeMappings"
>> value="refresh"/>
>> +         <property name="openjpa.jdbc.MappingDefaults"
>> value="DefaultMissingInfo=true"/>
>> +         <property name="openjpa.RuntimeUnenhancedClasses"
>> value="supported"/>
>> +      </properties>
>> +   </persistence-unit>
>> +
>>  </persistence>
>>
>>
>>
> 
> 

-- 
View this message in context: http://n2.nabble.com/Re%3A-svn-commit%3A-r698284---in--openjpa-trunk%3A-openjpa-kernel-src-main-java-org-apache-openjpa-meta--openjpa-persistence-src-main-java-org-apache-openjpa-persistence--openjpa-slice-src-main-java-o-tp1113445p1113504.html
Sent from the OpenJPA Developers mailing list archive at Nabble.com.


Mime
View raw message