> 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, <[EMAIL PROTECTED]> 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 >> + * [EMAIL PROTECTED] ReplicationPolicy#replicate(Object, java.util.List, >> Object)} >> + * method. >> + * >> + * @see ReplicationPolicy >> + * >> + * @author Pinaki Poddar >> + * >> + */ >> [EMAIL PROTECTED]({ TYPE }) >> [EMAIL PROTECTED](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 [EMAIL PROTECTED] DistributionPolicy} and [EMAIL >> PROTECTED] >> 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 >> + * [EMAIL PROTECTED] DistributionPolicy} or [EMAIL PROTECTED] >> ReplicationPolicy} >> + * depending on whether the given instance is [EMAIL PROTECTED] >> 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 [EMAIL PROTECTED] >> 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 >> + * >> + */ >> [EMAIL PROTECTED] >> [EMAIL PROTECTED] >> +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.
