Author: mikedd
Date: Tue Apr 6 17:05:47 2010
New Revision: 931227
URL: http://svn.apache.org/viewvc?rev=931227&view=rev
Log:
OPENJPA-1551
Added:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/Person.java
(with props)
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestSwitchConnection.java
(with props)
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/resources/jndi.properties
(with props)
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/resources/simple-jndi/
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/resources/simple-jndi/jdbc/
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/resources/simple-jndi/jdbc/default.properties
(with props)
Modified:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerFactory.java
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBrokerFactory.java
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/pom.xml
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java
Modified:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
URL:
http://svn.apache.org/viewvc/openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java?rev=931227&r1=931226&r2=931227&view=diff
==============================================================================
---
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
(original)
+++
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java
Tue Apr 6 17:05:47 2010
@@ -32,12 +32,14 @@ import java.util.Iterator;
import java.util.Set;
import javax.sql.DataSource;
+import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.event.OrphanedKeyAction;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.meta.Discriminator;
import org.apache.openjpa.jdbc.meta.FieldMapping;
import org.apache.openjpa.jdbc.meta.ValueMapping;
+import org.apache.openjpa.jdbc.schema.DataSourceFactory;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.JoinSyntaxes;
import org.apache.openjpa.jdbc.sql.Joins;
@@ -47,6 +49,7 @@ import org.apache.openjpa.jdbc.sql.SQLFa
import org.apache.openjpa.jdbc.sql.Select;
import org.apache.openjpa.jdbc.sql.SelectExecutor;
import org.apache.openjpa.jdbc.sql.Union;
+import org.apache.openjpa.kernel.Broker;
import org.apache.openjpa.kernel.FetchConfiguration;
import org.apache.openjpa.kernel.LockManager;
import org.apache.openjpa.kernel.OpenJPAStateManager;
@@ -114,14 +117,53 @@ public class JDBCStoreManager
if (lm instanceof JDBCLockManager)
_lm = (JDBCLockManager) lm;
- if (!ctx.isManaged() && _conf.isConnectionFactoryModeManaged())
- _ds = _conf.getDataSource2(ctx);
- else
- _ds = _conf.getDataSource(ctx);
+ _ds = getDataSource(ctx);
if (_conf.getUpdateManagerInstance().orderDirty())
ctx.setOrderDirtyObjects(true);
}
+
+ private boolean useConnectionFactory2(StoreContext ctx) {
+ return !ctx.isManaged() && _conf.isConnectionFactoryModeManaged();
+ }
+
+ private final DataSource getDataSource(StoreContext ctx) {
+ if (useContextToGetDataSource(ctx)) {
+ return getDataSourceFromContext(ctx);
+ }
+ else {
+ return getDataSourceFromConfig(ctx);
+ }
+ }
+
+ private final DataSource getDataSourceFromConfig(StoreContext ctx) {
+ if (useConnectionFactory2(ctx)) {
+ return _conf.getDataSource2(ctx);
+ }
+ else {
+ return _conf.getDataSource(ctx);
+ }
+ }
+
+ private final DataSource getDataSourceFromContext(StoreContext ctx) {
+ DataSource ds;
+
+ if (useConnectionFactory2(ctx)) {
+ ds = (DataSource) ctx.getConnectionFactory2();
+ } else {
+ ds = (DataSource) ctx.getConnectionFactory();
+ }
+ return DataSourceFactory.decorateDataSource(ds, _conf, false);
+ }
+
+ private boolean useContextToGetDataSource(StoreContext ctx) {
+ // configuration check to enable goes here.
+ if (StringUtils.isBlank(ctx.getConnectionFactoryName())
+ && StringUtils.isBlank(ctx.getConnectionFactory2Name())) {
+ return false;
+ }
+ return true;
+ }
public JDBCConfiguration getConfiguration() {
return _conf;
Modified:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
URL:
http://svn.apache.org/viewvc/openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java?rev=931227&r1=931226&r2=931227&view=diff
==============================================================================
---
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
(original)
+++
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/AbstractBrokerFactory.java
Tue Apr 6 17:05:47 2010
@@ -164,8 +164,13 @@ public abstract class AbstractBrokerFact
return newBroker(user, pass, managed, connRetainMode, true);
}
+ public Broker newBroker(String user, String pass, boolean managed, int
connRetainMode, boolean findExisting) {
+ return newBroker(user, pass, managed, connRetainMode, findExisting,
"", "");
+ }
+
public Broker newBroker(String user, String pass, boolean managed,
- int connRetainMode, boolean findExisting) {
+ int connRetainMode, boolean findExisting, String cf1Name, String
cf2Name) {
+
try {
assertOpen();
makeReadOnly();
@@ -186,6 +191,9 @@ public abstract class AbstractBrokerFact
dsm = new ROPStoreManager((dsm == null) ? sm : dsm);
broker = newBrokerImpl(user, pass);
+
+ broker.setConnectionFactoryName(cf1Name);
+ broker.setConnectionFactory2Name(cf2Name);
broker.initialize(this, dsm, managed, connRetainMode);
addListeners(broker);
Modified:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerFactory.java
URL:
http://svn.apache.org/viewvc/openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerFactory.java?rev=931227&r1=931226&r2=931227&view=diff
==============================================================================
---
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerFactory.java
(original)
+++
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerFactory.java
Tue Apr 6 17:05:47 2010
@@ -65,6 +65,27 @@ public interface BrokerFactory
*/
public Broker newBroker(String user, String pass, boolean managed,
int connRetainMode, boolean findExisting);
+
+ /**
+ * Return a new broker using the supplied
+ * <ul>
+ * <li>credentials</li>
+ * <li>transaction management mode</li>
+ * <li>connectionRetainMode</li>
+ * <li>connectionFactories</li>
+ * </ul>
+ *
+ * @param user Username to use when obtaining a connection. Will be
ignored if a connection factory is obtained from JNDI.
+ * @param pass Password to use when obtaining a connection. Will be
ignored if a connection factory is obtained from JNDI.
+ * @param managed Whether managed transactions will be used by this Broker
+ * @param connRetainMode {...@link ConnectionRetainMode}
+ * @param findExisting Whether the internal pool of brokers should be
used.
+ * @param cf1Name JTA ConnectionFactory to use
+ * @param cf2Name Non-JTA ConnectionFactory to use.
+ * @return A Broker which matches the provided criteria.
+ */
+ public Broker newBroker(String user, String pass, boolean managed,
+ int connRetainMode, boolean findExisting, String cf1Name, String
cf2Name);
/**
* Register a listener for lifecycle-related events on the specified
Modified:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
URL:
http://svn.apache.org/viewvc/openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java?rev=931227&r1=931226&r2=931227&view=diff
==============================================================================
---
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
(original)
+++
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/BrokerImpl.java
Tue Apr 6 17:05:47 2010
@@ -40,6 +40,7 @@ import org.apache.commons.collections.it
import org.apache.commons.collections.map.IdentityMap;
import org.apache.commons.collections.map.LinkedMap;
import org.apache.commons.collections.set.MapBackedSet;
+import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.conf.Compatibility;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.datacache.DataCache;
@@ -52,6 +53,7 @@ import org.apache.openjpa.event.RemoteCo
import org.apache.openjpa.event.TransactionEvent;
import org.apache.openjpa.event.TransactionEventManager;
import org.apache.openjpa.kernel.exps.ExpressionParser;
+import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.util.J2DoPrivHelper;
import org.apache.openjpa.lib.util.Localizer;
@@ -221,6 +223,12 @@ public class BrokerImpl
private boolean _initializeWasInvoked = false;
private static final Object[] EMPTY_OBJECTS = new Object[0];
+
+ // TODO MDD
+ private String _connectionFactoryName = "";
+ private String _connectionFactory2Name = "";
+ private Object _connectionFactory = null;
+ private Object _connectionFactory2 = null;
/**
* Set the persistence manager's authentication. This is the first
@@ -4872,4 +4880,57 @@ public class BrokerImpl
};
}
}
+
+ /**
+ * Return the 'JTA' connectionFactoryName
+ */
+ public String getConnectionFactoryName() {
+ return _connectionFactoryName;
+ }
+
+ /**
+ * Set the 'JTA' ConnectionFactoryName. Input will be trimmed to null
before being stored.
+ */
+ public void setConnectionFactoryName(String connectionFactoryName) {
+ this._connectionFactoryName =
StringUtils.trimToNull(connectionFactoryName);
+ }
+
+ /**
+ * Return the 'NonJTA' ConnectionFactoryName.
+ */
+ public String getConnectionFactory2Name() {
+ return _connectionFactory2Name;
+ }
+
+ /**
+ * Set the 'NonJTA' ConnectionFactoryName. Input will be trimmed to null
before being stored.
+ */
+ public void setConnectionFactory2Name(String connectionFactory2Name) {
+ this._connectionFactory2Name =
StringUtils.trimToNull(connectionFactory2Name);
+ }
+
+ /**
+ * Return the 'JTA' ConnectionFactory, looking it up from JNDI if needed.
+ *
+ * @return the JTA connection factory or null if connectionFactoryName is
blank.
+ */
+ public Object getConnectionFactory() {
+ if(_connectionFactory == null &&
StringUtils.isNotBlank(_connectionFactoryName)) {
+ _connectionFactory = Configurations.lookup(_connectionFactoryName);
+ }
+ return _connectionFactory;
+ }
+
+ /**
+ * Return the 'NonJTA' ConnectionFactory, looking it up from JNDI if
needed.
+ *
+ * @return the NonJTA connection factory or null if connectionFactoryName
is blank.
+ */
+ public Object getConnectionFactory2() {
+ // TODO MDD handle empyty string in lookup.
+ if(_connectionFactory2 == null &&
StringUtils.isNotBlank(_connectionFactory2Name)) {
+ _connectionFactory2 =
Configurations.lookup(_connectionFactory2Name);
+ }
+ return _connectionFactory2;
+ }
}
Modified:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
URL:
http://svn.apache.org/viewvc/openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java?rev=931227&r1=931226&r2=931227&view=diff
==============================================================================
---
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
(original)
+++
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBroker.java
Tue Apr 6 17:05:47 2010
@@ -1368,4 +1368,28 @@ public class DelegatingBroker
throw translate(re);
}
}
+
+ public String getConnectionFactoryName() {
+ return _broker.getConnectionFactoryName();
+ }
+
+ public void setConnectionFactoryName(String connectionFactoryName) {
+ _broker.setConnectionFactoryName(connectionFactoryName);
+ }
+
+ public String getConnectionFactory2Name() {
+ return _broker.getConnectionFactory2Name();
+ }
+
+ public void setConnectionFactory2Name(String connectionFactory2Name) {
+ _broker.setConnectionFactory2Name(connectionFactory2Name);
+ }
+
+ public Object getConnectionFactory() {
+ return _broker.getConnectionFactory();
+ }
+
+ public Object getConnectionFactory2() {
+ return _broker.getConnectionFactory2();
+ }
}
Modified:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBrokerFactory.java
URL:
http://svn.apache.org/viewvc/openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBrokerFactory.java?rev=931227&r1=931226&r2=931227&view=diff
==============================================================================
---
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBrokerFactory.java
(original)
+++
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/DelegatingBrokerFactory.java
Tue Apr 6 17:05:47 2010
@@ -138,9 +138,13 @@ public class DelegatingBrokerFactory
public Broker newBroker(String user, String pass, boolean managed,
int connRetainMode, boolean findExisting) {
+ return newBroker(user, pass, managed, connRetainMode, findExisting,
"", "");
+ }
+ public Broker newBroker(String user, String pass, boolean managed,
+ int connRetainMode, boolean findExisting, String cf1Name, String
cf2Name) {
try {
return _factory.newBroker(user, pass, managed, connRetainMode,
- findExisting);
+ findExisting, cf1Name, cf2Name);
} catch (RuntimeException re) {
throw translate(re);
}
Modified:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
URL:
http://svn.apache.org/viewvc/openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java?rev=931227&r1=931226&r2=931227&view=diff
==============================================================================
---
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
(original)
+++
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
Tue Apr 6 17:05:47 2010
@@ -22,7 +22,9 @@ import java.util.BitSet;
import java.util.Collection;
import java.util.Iterator;
+import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.meta.ValueMetaData;
/**
@@ -438,4 +440,38 @@ public interface StoreContext {
* Releases the internal lock.
*/
public void unlock ();
+
+ /**
+ * Return the 'JTA' connectionFactoryName
+ */
+ public String getConnectionFactoryName();
+
+ /**
+ * Set the 'JTA' ConnectionFactoryName.
+ */
+ public void setConnectionFactoryName(String connectionFactoryName);
+
+ /**
+ * Return the 'NonJTA' ConnectionFactoryName.
+ */
+ public String getConnectionFactory2Name();
+
+ /**
+ * Set the 'NonJTA' ConnectionFactoryName.
+ */
+ public void setConnectionFactory2Name(String connectionFactory2Name);
+
+ /**
+ * Return the 'JTA' ConnectionFactory, looking it up from JNDI if needed.
+ *
+ * @return the JTA connection factory or null if connectionFactoryName is
blank.
+ */
+ public Object getConnectionFactory();
+
+ /**
+ * Return the 'NonJTA' ConnectionFactory, looking it up from JNDI if
needed.
+ *
+ * @return the NonJTA connection factory or null if connectionFactoryName
is blank.
+ */
+ public Object getConnectionFactory2();
}
Modified: openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/pom.xml
URL:
http://svn.apache.org/viewvc/openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/pom.xml?rev=931227&r1=931226&r2=931227&view=diff
==============================================================================
--- openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/pom.xml
(original)
+++ openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/pom.xml Tue
Apr 6 17:05:47 2010
@@ -404,6 +404,12 @@
<version>3.2</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>simple-jndi</groupId>
+ <artifactId>simple-jndi</artifactId>
+ <version>0.11.4</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<plugins>
Added:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/Person.java
URL:
http://svn.apache.org/viewvc/openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/Person.java?rev=931227&view=auto
==============================================================================
---
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/Person.java
(added)
+++
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/Person.java
Tue Apr 6 17:05:47 2010
@@ -0,0 +1,46 @@
+package org.apache.openjpa.persistence.conf;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+// override defaults to attempt to prevent collisions.
+...@entity(name="confPerson")
+...@table(name="CONF_PERSON")
+public class Person {
+
+ @Id
+ private int id;
+
+ @Version
+ private int version;
+
+ @Column(length=16)
+ private String name;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public void setVersion(int version) {
+ this.version = version;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Propchange:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/Person.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestSwitchConnection.java
URL:
http://svn.apache.org/viewvc/openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestSwitchConnection.java?rev=931227&view=auto
==============================================================================
---
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestSwitchConnection.java
(added)
+++
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestSwitchConnection.java
Tue Apr 6 17:05:47 2010
@@ -0,0 +1,290 @@
+package org.apache.openjpa.persistence.conf;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.persistence.EntityExistsException;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.RollbackException;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.openjpa.persistence.test.PersistenceTestCase;
+
+public class TestSwitchConnection extends PersistenceTestCase {
+ private String defaultJndiName = "jdbc/mocked";
+ private String[] jndiNames = { "jdbc/mocked1", "jdbc/mocked2" };
+ private String[] schemas = { "APP", "APP1", "APP2" };
+ private static EntityManagerFactory emf = null;
+
+ /**
+ * <p>
+ * Create EntityManagers which override the openjpa.ConnectionFactoryName
property to communicate with different
+ * database instances.
+ * </p>
+ * <p>
+ * The first 'wave' of inserts should succeed with each EntityManager. A
second 'wave' of inserts with the same
+ * Identity will fail.
+ * </p>
+ */
+ public void testOverrideConnectionFactory() {
+ Collection<EntityManager> ems = new ArrayList<EntityManager>();
+
+ ems.add(getEntityManagerCF(""));
+ for (String jndiLoc : jndiNames) {
+ ems.add(getEntityManagerCF(jndiLoc));
+ }
+ assertEquals(jndiNames.length + 1, ems.size());
+
+ for (EntityManager em : ems) {
+ deleteRows(em);
+ }
+
+ doPersists(ems, false, false); // switching the connection factory
should work the first time.
+ doPersists(ems, true, true); // inserting the same row a second time
will fail.
+
+ for (EntityManager em : ems) {
+ em.close();
+ }
+ }
+
+ /**
+ * <p>
+ * Create EntityManagers which override the openjpa.ConnectionUserName
property to try to use different credentials
+ * on the same ConnectionFactory. The ConnectionUserName property will be
ignored when using a ConnectionFactory
+ * from JNDI so the attempt will ultimately fail.
+ * </p>
+ * <p>
+ * The first insert should succeed, but subsequent inserts will use the
same credentials and will fail. A second
+ * 'wave' of inserts with the same Identity will also fail.
+ * </p>
+ */
+ public void testOverrideUserName() {
+ Collection<EntityManager> ems = new ArrayList<EntityManager>();
+
+ for (String schema : schemas) {
+ ems.add(getEntityManagerUserName(schema));
+ }
+ assertEquals(schemas.length, ems.size());
+
+ for (EntityManager em : ems) {
+ deleteRows(em);
+ }
+
+ doPersists(ems, false, true); // Username on a connectionfactory from
JNDI is not overridden.
+ doPersists(ems, true, true); // inserting the same row a second time
will fail.
+
+ for (EntityManager em : ems) {
+ em.close();
+ }
+ }
+
+ /**
+ * <p>
+ * Helper method which obtains an EntityManagerFactory and initializes the
database for this testcase. The same
+ * operation will be performed for each of the additional JNDI locations
used in this class (these
+ * EntityManagerFactories are closed and discarded at the end of the
method.
+ * </p>
+ * <p>
+ * This initialization happens only once for the class and should not be
moved to a setUp() method which would be
+ * executed once for each test.
+ * </p>
+ *
+ * @return the 'base' EntityManagerFactory which will be used in this
testcase.
+ */
+ protected EntityManagerFactory getEntityManagerFactory() {
+ if (emf == null) {
+ // specify connectionDriverName to ensure that system properties
won't cover up any problems.
+ emf =
+ createEMF("openjpa.ConnectionDriverName", "",
"openjpa.ConnectionFactoryName", defaultJndiName,
+ Person.class);
+ assertNotNull(emf);
+ initDB(emf);
+
+ for (String jndiName : jndiNames) {
+ // create the emfs for cf1 and cf2 to trigger synchronize
mappings, drop existing rows, and create
+ // schemas
+ EntityManagerFactory tempEmf =
+ createEMF("openjpa.ConnectionDriverName", "",
"openjpa.ConnectionFactoryName", jndiName,
+ Person.class);
+
+ assertNotNull(tempEmf);
+ initDB(tempEmf);
+ tempEmf.close();
+ }
+
+ }
+ return emf;
+ }
+
+ /**
+ * Delete the rows from the confPerson table.
+ *
+ * @param em The EntityManager which will be used to clean the database.
+ */
+ private void deleteRows(EntityManager em) {
+ EntityTransaction tran = em.getTransaction();
+ tran.begin();
+ em.createQuery("Delete from confPerson").executeUpdate();
+ tran.commit();
+ }
+
+ /**
+ * <p>
+ * Delete rows, create schemas and create tables for those schemas.
+ * </p>
+ *
+ * @param emf EntityManagerFactory to use for creation.
+ */
+ private void initDB(EntityManagerFactory emf) {
+ EntityManager em = emf.createEntityManager();
+ EntityTransaction tran = em.getTransaction();
+
+ deleteRows(em);
+
+ // It's 'easier' to manually create the different schema names than to
rely on SyncrhonizeMappings (the number
+ // of EMFs could grow exponentially)
+ for (String schema : schemas) {
+ try {
+ tran.begin();
+ em.createNativeQuery("CREATE SCHEMA " +
schema).executeUpdate();
+ em.createNativeQuery(
+ "CREATE TABLE " + schema
+ + ".CONF_PERSON (id INTEGER NOT NULL, name
VARCHAR(16), version INTEGER, PRIMARY KEY (id)) ")
+ .executeUpdate();
+ tran.commit();
+ } catch (Exception e) {
+ // assume the schema already exists and move on
+ tran.rollback();
+ }
+ }
+
+ if (tran.isActive()) {
+ tran.rollback();
+ }
+ em.close();
+ }
+
+ /**
+ * <p>
+ * Get an EntityManager with one configuration property changed from what
was specified on the EntityManagerFactory.
+ * </p>
+ * <p>
+ * If the EntityManager cannot be created an AssertionError will be thrown.
+ * </p>
+ *
+ * @param propName property name to override.
+ * @param propValue value for the overridden property.
+ * @return An EntityManager instance with the property overridden
+ */
+ protected EntityManager getEntityManagerOverrideProp(String propName,
String propValue) {
+
+ Map<String, Object> props = new HashMap<String, Object>();
+
+ if (StringUtils.isNotBlank(propValue)) {
+ props.put(propName, propValue);
+ }
+
+ EntityManager rval =
getEntityManagerFactory().createEntityManager(props);
+ assertNotNull("Unable to create EntityManager with " + propName + " =
" + propValue, rval);
+ return rval;
+ }
+
+ /**
+ * Convenience method to override the connectionFactoryName property when
creating an EntityManager.
+ *
+ * @param cfName
+ * @return
+ */
+ protected EntityManager getEntityManagerCF(String cfName) {
+ return getEntityManagerOverrideProp("openjpa.ConnectionFactoryName",
cfName);
+ }
+
+ /**
+ * Convenience method to override the connectionUserName property when
creating an EntityManager
+ *
+ * @param userName
+ * @return
+ */
+ protected EntityManager getEntityManagerUserName(String userName) {
+ return getEntityManagerOverrideProp("openjpa.ConnectionUserName",
userName);
+ }
+
+ /**
+ * <p>
+ * Persist the same row to a collection of EntityManagers. The
EntityManagers should represent different database
+ * schemas (either unique DB instances, schemas, or userid/passwords.
+ * </p>
+ * <p>
+ * The caller is responsible for making sure the database is clean (or
not) prior to calling this method and adjust
+ * the expectations appropriately.
+ * <p>
+ * <p>
+ * This method can expect to fail on the first insert, or on the second
insert. In either case once an insert fails
+ * all subsequent inserts are expected to fail. The latter case is useful
when we don't expect a change to take
+ * effect (ie setting the ConnectionUserName property but using a
ConnectionFactory from JNDI).
+ * </p>
+ *
+ * @param ems Collection of EntityManagers which will be used to persist
new entities
+ * @param expectFirstToFail Whether the first (and all subsequent) inserts
should fail.
+ * @param expectNextToFail Whether the second (and all subsequent) inserts
should fail.
+ */
+ protected void doPersists(Collection<EntityManager> ems, boolean
expectFirstToFail, boolean expectNextToFail) {
+ Person p;
+ EntityTransaction tran = null;
+ int iteration = 0;
+ for (EntityManager em : ems) {
+ try {
+ p = new Person();
+ p.setId(1);
+ tran = em.getTransaction();
+
+ tran.begin();
+ em.persist(p);
+ tran.commit();
+ if (shouldFail(expectFirstToFail, expectNextToFail,
iteration)) {
+ fail("Expected an EntityExistsException or a
RollbackException");
+ }
+ iteration++;
+ } catch (EntityExistsException eee) {
+ // expected but we may need to clean up.
+ if (tran != null && tran.isActive()) {
+ tran.rollback();
+ }
+ if (!shouldFail(expectFirstToFail, expectNextToFail,
iteration)) {
+ throw eee;
+ }
+ } catch (RollbackException rbe) {
+ // expected but we may need to clean up.
+ if (tran != null && tran.isActive()) {
+ tran.rollback();
+ }
+ if (!shouldFail(expectFirstToFail, expectNextToFail,
iteration)) {
+ throw rbe;
+ }
+ }
+ }
+ }
+
+ /**
+ * Convenience method to determine whether we should expect a failure.
+ *
+ * @param expectFirst
+ * @param expectNext
+ * @param iteration
+ * @return
+ */
+ private boolean shouldFail(boolean expectFirst, boolean expectNext, int
iteration) {
+ boolean rval = false;
+ if (iteration > 0 && expectNext) {
+ rval = true;
+ }
+ if (expectFirst) {
+ rval = true;
+ }
+ return rval;
+ }
+}
Propchange:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/conf/TestSwitchConnection.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/resources/jndi.properties
URL:
http://svn.apache.org/viewvc/openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/resources/jndi.properties?rev=931227&view=auto
==============================================================================
---
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/resources/jndi.properties
(added)
+++
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/resources/jndi.properties
Tue Apr 6 17:05:47 2010
@@ -0,0 +1,4 @@
+ java.naming.factory.initial=org.osjava.sj.SimpleContextFactory
+ org.osjava.sj.root=src/test/resources/simple-jndi
+ org.osjava.sj.colon.replace=--
+ org.osjava.sj.delimiter=/
Propchange:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/resources/jndi.properties
------------------------------------------------------------------------------
svn:eol-style = native
Added:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/resources/simple-jndi/jdbc/default.properties
URL:
http://svn.apache.org/viewvc/openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/resources/simple-jndi/jdbc/default.properties?rev=931227&view=auto
==============================================================================
---
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/resources/simple-jndi/jdbc/default.properties
(added)
+++
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/resources/simple-jndi/jdbc/default.properties
Tue Apr 6 17:05:47 2010
@@ -0,0 +1,17 @@
+mocked/type=javax.sql.DataSource
+mocked/driver=org.apache.derby.jdbc.EmbeddedDriver
+mocked/url=jdbc:derby:target/database/jpa-jndi-database;create=true
+mocked/user=app
+mocked/password=app
+
+mocked1/type=javax.sql.DataSource
+mocked1/driver=org.apache.derby.jdbc.EmbeddedDriver
+mocked1/url=jdbc:derby:target/database/jpa-jndi-database1;create=true
+mocked1/user=app
+mocked1/password=app
+
+mocked2/type=javax.sql.DataSource
+mocked2/driver=org.apache.derby.jdbc.EmbeddedDriver
+mocked2/url=jdbc:derby:target/database/jpa-jndi-database2;create=true
+mocked2/user=app
+mocked2/password=app
Propchange:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence-jdbc/src/test/resources/simple-jndi/jdbc/default.properties
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java
URL:
http://svn.apache.org/viewvc/openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java?rev=931227&r1=931226&r2=931227&view=diff
==============================================================================
---
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java
(original)
+++
openjpa/sandboxes/OpenJPA-1551-1.0.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/EntityManagerFactoryImpl.java
Tue Apr 6 17:05:47 2010
@@ -189,8 +189,11 @@ public class EntityManagerFactoryImpl
}
}
+ String connectionFactoryName = (String)
Configurations.removeProperty("ConnectionFactoryName", props);
+ String connectionFactory2Name = (String)
Configurations.removeProperty("ConnectionFactoryName2", props);
+
Broker broker = _factory.newBroker(user, pass, managed, retainMode,
- false);
+ false, connectionFactoryName, connectionFactory2Name);
// add autodetach for close and rollback conditions to the
configuration
broker.setAutoDetach(AutoDetach.DETACH_CLOSE, true);