- Added custom JPA provider to address Tenant per EMF - Added project to build agent jar for custom JPA provider - Upgraded to latest EclipseLink 2.4 nightly - all JSON binding tests now pass - Fixed KFL (Table isolation) hard coded schema gen
diff --git a/.gitignore b/.gitignore index d9726bb..3c7262c 100644 --- a/.gitignore +++ b/.gitignore
@@ -2,4 +2,5 @@ /MySports App/build/classes /MySports Tests/classes -/MySports Tests/src/example/mysports/tests/admin/CreateDatasourceUsingREST.java \ No newline at end of file +/MySports Tests/src/example/mysports/tests/admin/CreateDatasourceUsingREST.java +/Multitenant JPA Provider/bin \ No newline at end of file
diff --git a/Multitenant JPA Provider/.classpath b/Multitenant JPA Provider/.classpath new file mode 100644 index 0000000..e0cfb85 --- /dev/null +++ b/Multitenant JPA Provider/.classpath
@@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry combineaccessrules="false" kind="src" path="/MySports"/> + <classpathentry kind="output" path="bin"/> +</classpath>
diff --git a/Multitenant JPA Provider/.project b/Multitenant JPA Provider/.project new file mode 100644 index 0000000..30ad994 --- /dev/null +++ b/Multitenant JPA Provider/.project
@@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>Multitenant JPA Provider</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription>
diff --git a/Multitenant JPA Provider/.settings/org.eclipse.jdt.core.prefs b/Multitenant JPA Provider/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..8000cd6 --- /dev/null +++ b/Multitenant JPA Provider/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6
diff --git a/Multitenant JPA Provider/eclipselink_mtjpa.jar b/Multitenant JPA Provider/eclipselink_mtjpa.jar new file mode 100644 index 0000000..3323c08 --- /dev/null +++ b/Multitenant JPA Provider/eclipselink_mtjpa.jar Binary files differ
diff --git a/Multitenant JPA Provider/src/META-INF/MANIFEST.MF b/Multitenant JPA Provider/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..daa8b26 --- /dev/null +++ b/Multitenant JPA Provider/src/META-INF/MANIFEST.MF
@@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Specification-Title: EclipseLink MT Provider +Specification-Vendor: Eclipse.org - EclipseLink Project +Specification-Version: 2.4 +Implementation-Title: org.eclipse.persistence +Implementation-Vendor: Eclipse.org - EclipseLink Project +Implementation-Version: 2.4 +Release-Designation: EclipseLink 2.4 +Premain-Class: example.mysports.persistence.JavaSECMPInitializerAgent + +
diff --git a/MySports Admin/WebContent/WEB-INF/beans.xml b/MySports Admin/WebContent/WEB-INF/beans.xml deleted file mode 100644 index 3867c08..0000000 --- a/MySports Admin/WebContent/WEB-INF/beans.xml +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> -</beans> \ No newline at end of file
diff --git a/MySports App/WebContent/WEB-INF/lib/org.eclipse.persistence.jpars_2.4.0.v20120523-r11458.jar b/MySports Admin/WebContent/WEB-INF/lib/org.eclipse.persistence.jpars_2.4.0.v20120525-r11490.jar similarity index 75% copy from MySports App/WebContent/WEB-INF/lib/org.eclipse.persistence.jpars_2.4.0.v20120523-r11458.jar copy to MySports Admin/WebContent/WEB-INF/lib/org.eclipse.persistence.jpars_2.4.0.v20120525-r11490.jar index c8be0a4..697f90a 100644 --- a/MySports App/WebContent/WEB-INF/lib/org.eclipse.persistence.jpars_2.4.0.v20120523-r11458.jar +++ b/MySports Admin/WebContent/WEB-INF/lib/org.eclipse.persistence.jpars_2.4.0.v20120525-r11490.jar Binary files differ
diff --git a/MySports Admin/src/META-INF/persistence.xml b/MySports Admin/src/META-INF/persistence.xml index 4a69b11..1718929 100644 --- a/MySports Admin/src/META-INF/persistence.xml +++ b/MySports Admin/src/META-INF/persistence.xml
@@ -2,7 +2,8 @@ <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> - <persistence-unit name="mysports-admin"> + <persistence-unit name="MySportsAdmin"> + <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <jta-data-source>jdbc/MySportsAdmin</jta-data-source> <class>example.mysports.admin.model.Style</class> <class>example.mysports.admin.model.HostedLeague</class>
diff --git a/MySports Admin/src/example/mysports/admin/services/HostEnvironmentRepositoryBean.java b/MySports Admin/src/example/mysports/admin/services/HostEnvironmentRepositoryBean.java index 7bcc48e..db5d3dd 100644 --- a/MySports Admin/src/example/mysports/admin/services/HostEnvironmentRepositoryBean.java +++ b/MySports Admin/src/example/mysports/admin/services/HostEnvironmentRepositoryBean.java
@@ -18,7 +18,7 @@ @Stateless public class HostEnvironmentRepositoryBean implements HostEnvironmentRepository { - @PersistenceContext(unitName = "mysports-admin") + @PersistenceContext(unitName = "MySportsAdmin") private EntityManager entityManager; public EntityManager getEntityManager() {
diff --git a/MySports Admin/src/example/mysports/admin/services/HostedLeagueRepositoryBean.java b/MySports Admin/src/example/mysports/admin/services/HostedLeagueRepositoryBean.java index dbc6614..6938b78 100644 --- a/MySports Admin/src/example/mysports/admin/services/HostedLeagueRepositoryBean.java +++ b/MySports Admin/src/example/mysports/admin/services/HostedLeagueRepositoryBean.java
@@ -37,7 +37,7 @@ @Stateless public class HostedLeagueRepositoryBean implements HostedLeagueRepository { - @PersistenceContext(unitName = "mysports-admin") + @PersistenceContext(unitName = "MySportsAdmin") private EntityManager entityManager; public EntityManager getEntityManager() {
diff --git a/MySports App/WebContent/WEB-INF/lib/org.eclipse.persistence.jpars_2.4.0.v20120523-r11458.jar b/MySports App/WebContent/WEB-INF/lib/org.eclipse.persistence.jpars_2.4.0.v20120525-r11490.jar similarity index 76% rename from MySports App/WebContent/WEB-INF/lib/org.eclipse.persistence.jpars_2.4.0.v20120523-r11458.jar rename to MySports App/WebContent/WEB-INF/lib/org.eclipse.persistence.jpars_2.4.0.v20120525-r11490.jar index c8be0a4..697f90a 100644 --- a/MySports App/WebContent/WEB-INF/lib/org.eclipse.persistence.jpars_2.4.0.v20120523-r11458.jar +++ b/MySports App/WebContent/WEB-INF/lib/org.eclipse.persistence.jpars_2.4.0.v20120525-r11490.jar Binary files differ
diff --git a/MySports App/src/META-INF/persistence.xml b/MySports App/src/META-INF/persistence.xml index e728483..be2543a 100644 --- a/MySports App/src/META-INF/persistence.xml +++ b/MySports App/src/META-INF/persistence.xml
@@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="mysports" transaction-type="RESOURCE_LOCAL"> + <provider>example.mysports.persistence.MultitenantPersistenceProvider</provider> <non-jta-data-source>jdbc/MySports</non-jta-data-source> <mapping-file>META-INF/local-eclipselink-orm.xml</mapping-file> @@ -25,8 +26,7 @@ <property name="eclipselink.metadata-source" value="example.mysports.admin.AdminMetadataSource"/> <!-- EMF per tenant configuration --> - <property name="eclipselink.multitenant.tenants-share-emf" value="false" /> - <property name="eclipselink.session-name" value="MySports_%mysports.league%" /> + <property name="eclipselink.template-unit-name" value="mysports"/> </properties> </persistence-unit> </persistence>
diff --git a/MySports App/src/META-INF/services/javax.persistence.spi.PersistenceProvider b/MySports App/src/META-INF/services/javax.persistence.spi.PersistenceProvider new file mode 100644 index 0000000..359cc4a --- /dev/null +++ b/MySports App/src/META-INF/services/javax.persistence.spi.PersistenceProvider
@@ -0,0 +1 @@ +example.mysports.persistence.MultitenantPersistenceProvider \ No newline at end of file
diff --git a/MySports App/src/example/mysports/ejb/LeagueRepository.java b/MySports App/src/example/mysports/ejb/LeagueRepository.java index f8fa5bf..55b4099 100644 --- a/MySports App/src/example/mysports/ejb/LeagueRepository.java +++ b/MySports App/src/example/mysports/ejb/LeagueRepository.java
@@ -14,7 +14,7 @@ import static example.mysports.MySportsConfig.LEAGUE_CONTEXT; import static example.mysports.MySportsConfig.PU_NAME; -import static org.eclipse.persistence.config.PersistenceUnitProperties.SESSION_NAME; +import static org.eclipse.persistence.config.PersistenceUnitProperties.*; import java.io.Serializable; import java.util.ArrayList; @@ -432,13 +432,10 @@ emfProps.putAll(properties); } - // TODO: Commented out fow now assuming AdminMetadataSource configures it - emfProps.put(SESSION_NAME, getConfig().getSessionName(leagueId)); - emfProps.put(LEAGUE_CONTEXT, leagueId); emfProps.put(MySportsConfig.class.getName(), getConfig()); - - this.emf = Persistence.createEntityManagerFactory(PU_NAME, emfProps); + + this.emf = Persistence.createEntityManagerFactory(getConfig().getSessionName(leagueId), emfProps); this.leagueId = leagueId; // Clear cached state
diff --git a/MySports App/src/example/mysports/ejb/PersistenceWeavingBean.java b/MySports App/src/example/mysports/ejb/PersistenceWeavingBean.java index fd3b681..5d99510 100644 --- a/MySports App/src/example/mysports/ejb/PersistenceWeavingBean.java +++ b/MySports App/src/example/mysports/ejb/PersistenceWeavingBean.java
@@ -15,6 +15,7 @@ import javax.ejb.Singleton; import javax.ejb.Startup; import javax.persistence.EntityManagerFactory; +import javax.persistence.PersistenceProperty; import javax.persistence.PersistenceUnit;
diff --git a/MySports App/src/example/mysports/persistence/JavaSECMPInitializerAgent.java b/MySports App/src/example/mysports/persistence/JavaSECMPInitializerAgent.java new file mode 100644 index 0000000..e91a7eb --- /dev/null +++ b/MySports App/src/example/mysports/persistence/JavaSECMPInitializerAgent.java
@@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2010-2012 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 + * which accompanies this distribution. + * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * dclarke - EclipseLink 2.4 - MySports Demo Bug 344608 + ******************************************************************************/ +package example.mysports.persistence; + +import java.lang.instrument.Instrumentation; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + + +/** + * This agent is intended to be run prior to start up on a CMP3 JavaSE application. + * It gets the globalInstrumentation and makes it available to EclipseLink's initialization code. + * There are two kinds of initialization. Normally, initialization occurs through reflective + * creation and invocation of EclipseLink JavaSECMPInitializer. + * It is possible to run it with the "main" argument to the agent in which case it will simply + * try to set the globalInstrumentation field on the JavaSECMPInitializer. This type of initialization + * is useful when debugging, but imposes some restrictions on the user. One such restriction is + * that no domain classes that use lazy loading may be references in any way other than reflective in the application + */ +public class JavaSECMPInitializerAgent { + public static void premain(String agentArgs, Instrumentation instr) throws Throwable { + // Reflection allows: + // JavaSECMPInitializerAgent to be the *ONLY* class is the jar file specified in -javaagent; + // Loading JavaSECMPInitializer class using SystemClassLoader. + if ((agentArgs != null) && agentArgs.equals("main")) { + initializeFromMain(instr); + } else { + initializeFromAgent(instr); + } + } + + public static void initializeFromAgent(Instrumentation instr) throws Throwable { + Class cls = Class.forName("example.mysports.persistence.MultitenantJavaSECMPInitializer"); + Method method = cls.getDeclaredMethod("initializeFromAgent", new Class[] { Instrumentation.class }); + try { + method.invoke(null, new Object[] { instr }); + } catch (InvocationTargetException exception) { + throw exception.getCause(); + } + } + + public static void initializeFromMain(Instrumentation instr) throws Exception { + Class cls = Class.forName("example.mysports.persistence.MultitenantJavaSECMPInitializer"); + Field field = cls.getField("globalInstrumentation"); + field.set(null, instr); + } +}
diff --git a/MySports App/src/example/mysports/persistence/MultitenantJavaSECMPInitializer.java b/MySports App/src/example/mysports/persistence/MultitenantJavaSECMPInitializer.java new file mode 100644 index 0000000..cebe9cb --- /dev/null +++ b/MySports App/src/example/mysports/persistence/MultitenantJavaSECMPInitializer.java
@@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2010-2012 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 + * which accompanies this distribution. + * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * dclarke - EclipseLink 2.4 - MySports Demo Bug 344608 + ******************************************************************************/ +package example.mysports.persistence; + +import java.lang.instrument.Instrumentation; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.persistence.internal.jpa.deployment.JavaSECMPInitializer; +import org.eclipse.persistence.logging.AbstractSessionLog; +import org.eclipse.persistence.logging.SessionLog; + +@SuppressWarnings("rawtypes") +public class MultitenantJavaSECMPInitializer extends JavaSECMPInitializer { + + // Indicates whether has been initialized - that could be done only once. + protected static boolean isInitialized; + // Singleton corresponding to the main class loader. Created only if agent + // is used. + protected static JavaSECMPInitializer initializer; + + public static boolean isInContainer() { + return isInContainer; + } + + public static void setIsInContainer(boolean isInContainer) { + JavaSECMPInitializer.isInContainer = isInContainer; + } + + /** + * Get the singleton entityContainer. + */ + public static JavaSECMPInitializer getJavaSECMPInitializer() { + return getJavaSECMPInitializer(Thread.currentThread().getContextClassLoader(), null, false); + } + + public static JavaSECMPInitializer getJavaSECMPInitializer(ClassLoader classLoader) { + return getJavaSECMPInitializer(classLoader, null, false); + } + + public static JavaSECMPInitializer getJavaSECMPInitializerFromAgent() { + return getJavaSECMPInitializer(Thread.currentThread().getContextClassLoader(), null, true); + } + + public static JavaSECMPInitializer getJavaSECMPInitializerFromMain(Map m) { + return getJavaSECMPInitializer(Thread.currentThread().getContextClassLoader(), m, false); + } + + public static JavaSECMPInitializer getJavaSECMPInitializer(ClassLoader classLoader, Map m, boolean fromAgent) { + if (!isInitialized) { + if (globalInstrumentation != null) { + synchronized (initializationLock) { + if (!isInitialized) { + initializeTopLinkLoggingFile(); + if (fromAgent) { + AbstractSessionLog.getLog().log(SessionLog.FINER, SessionLog.WEAVER, "cmp_init_initialize_from_agent", (Object[]) null); + } + usesAgent = true; + initializer = new MultitenantJavaSECMPInitializer(classLoader); + initializer.initialize(m != null ? m : new HashMap(0)); + // all the transformers have been added to + // instrumentation, don't need it any more. + globalInstrumentation = null; + } + } + } + isInitialized = true; + } + if (initializer != null && initializer.getInitializationClassLoader() == classLoader) { + return initializer; + } else { + // when agent is not used initializer does not need to be + // initialized. + return new MultitenantJavaSECMPInitializer(classLoader); + } + } + + /** + * INTERNAL: Should be called only by the agent. (when weaving classes) If + * succeeded return true, false otherwise. + */ + protected static void initializeFromAgent(Instrumentation instrumentation) throws Exception { + // Squirrel away the instrumentation for later + globalInstrumentation = instrumentation; + getJavaSECMPInitializerFromAgent(); + } + + protected MultitenantJavaSECMPInitializer(ClassLoader loader) { + super(loader); + } + + @Override + public boolean isPersistenceProviderSupported(String providerClassName) { + return providerClassName != null && providerClassName.equals(MultitenantPersistenceProvider.class.getName()); + } +}
diff --git a/MySports App/src/example/mysports/persistence/MultitenantPersistenceProvider.java b/MySports App/src/example/mysports/persistence/MultitenantPersistenceProvider.java new file mode 100644 index 0000000..1119c16 --- /dev/null +++ b/MySports App/src/example/mysports/persistence/MultitenantPersistenceProvider.java
@@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2010-2012 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 + * which accompanies this distribution. + * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * dclarke - EclipseLink 2.4 - MySports Demo Bug 344608 + ******************************************************************************/ +package example.mysports.persistence; + +import java.util.Map; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.spi.PersistenceUnitInfo; + +import org.eclipse.persistence.config.PersistenceUnitProperties; +import org.eclipse.persistence.internal.jpa.deployment.JPAInitializer; +import org.eclipse.persistence.jpa.PersistenceProvider; + +/** + * {@link EntityManagerFactory} per tenant provider. + * + * @author dclarke + * + */ +public class MultitenantPersistenceProvider extends PersistenceProvider { + + /** + * TODO + */ + public static final String TEMPLATE_PU_NAME = "eclipselink.template-unit-name"; + + @SuppressWarnings("rawtypes") + @Override + public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties) { + return super.createContainerEntityManagerFactory(info, properties); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public EntityManagerFactory createEntityManagerFactory(String name, Map properties) { + String puName = name; + + if (properties != null && properties.containsKey(TEMPLATE_PU_NAME)) { + puName = (String) properties.get(TEMPLATE_PU_NAME); + properties.put(PersistenceUnitProperties.SESSION_NAME, name); + properties.put(PersistenceUnitProperties.MULTITENANT_SHARED_EMF, Boolean.FALSE.toString()); + } + + EntityManagerFactory emf = super.createEntityManagerFactory(puName, properties); + + if (emf == null && name.contains("-")) { + properties.put(TEMPLATE_PU_NAME, name.substring(0, name.indexOf("-"))); + return createEntityManagerFactory(name, properties); + } + + return emf; + } + + @SuppressWarnings("rawtypes") + @Override + public JPAInitializer getInitializer(String emName, Map m) { + ClassLoader classLoader = getClassLoader(emName, m); + return MultitenantJavaSECMPInitializer.getJavaSECMPInitializer(classLoader); + } + +}
diff --git a/MySports Tests/.classpath b/MySports Tests/.classpath index e7dbe2a..59c1568 100644 --- a/MySports Tests/.classpath +++ b/MySports Tests/.classpath
@@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> + <classpathentry combineaccessrules="false" kind="src" path="/javax.persistence 2.0.0"/> <classpathentry excluding="**/.svn/**" kind="src" path="src"/> <classpathentry combineaccessrules="false" kind="src" path="/MySports"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
diff --git a/MySports Tests/eclipselink_mtjpa.jar b/MySports Tests/eclipselink_mtjpa.jar new file mode 100644 index 0000000..3323c08 --- /dev/null +++ b/MySports Tests/eclipselink_mtjpa.jar Binary files differ
diff --git a/MySports Tests/run-configs/CreateDatabase.launch b/MySports Tests/run-configs/CreateDatabase.launch new file mode 100644 index 0000000..32e4df4 --- /dev/null +++ b/MySports Tests/run-configs/CreateDatabase.launch
@@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.jdt.junit.launchconfig"> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> +<listEntry value="/MySports Tests/src/example/mysports/tests/model/CreateDatabase.java"/> +</listAttribute> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> +<listEntry value="1"/> +</listAttribute> +<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/> +<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/> +<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/> +<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> +<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="example.mysports.tests.model.CreateDatabase"/> +<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="MySports Tests"/> +<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-javaagent:"${project_loc:/MySports Tests}\eclipselink_mtjpa.jar""/> +</launchConfiguration>
diff --git a/MySports Tests/run-configs/CreateTenantEMF.launch b/MySports Tests/run-configs/CreateTenantEMF.launch new file mode 100644 index 0000000..8352f02 --- /dev/null +++ b/MySports Tests/run-configs/CreateTenantEMF.launch
@@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.jdt.junit.launchconfig"> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> +<listEntry value="/MySports Tests/src/example/mysports/tests/persistence/CreateTenantEMF.java"/> +</listAttribute> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> +<listEntry value="1"/> +</listAttribute> +<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/> +<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/> +<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/> +<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> +<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="example.mysports.tests.persistence.CreateTenantEMF"/> +<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="MySports Tests"/> +<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-javaagent:"C:\eclipse\EclipseLink\git\mysports.git\Multitenant JPA Provider\eclipselink_mtjpa.jar""/> +</launchConfiguration>
diff --git a/MySports Tests/run-configs/MySports AllTests.launch b/MySports Tests/run-configs/MySports AllTests.launch index c13c8f1..36dc1aa 100644 --- a/MySports Tests/run-configs/MySports AllTests.launch +++ b/MySports Tests/run-configs/MySports AllTests.launch
@@ -16,5 +16,5 @@ <stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="example.mysports.tests.AllTests"/> <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="MySports Tests"/> -<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-javaagent:${eclipselink_2.4}\eclipselink\jlib\eclipselink.jar"/> +<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-javaagent:"${project_loc:/MySports Tests}\eclipselink_mtjpa.jar""/> </launchConfiguration>
diff --git a/MySports Tests/src/example/mysports/tests/admin/AdminServerConnectorTests.java b/MySports Tests/src/example/mysports/tests/admin/AdminServerConnectorTests.java index 6cad2bc..b565189 100644 --- a/MySports Tests/src/example/mysports/tests/admin/AdminServerConnectorTests.java +++ b/MySports Tests/src/example/mysports/tests/admin/AdminServerConnectorTests.java
@@ -60,7 +60,7 @@ @BeforeClass public static void setup() { config = new MySportsConfig(); - EntityManagerFactory emf = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + EntityManagerFactory emf = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); ((MockAdminServerConnector) config.getAdminConnector()).setEMF(emf); }
diff --git a/MySports Tests/src/example/mysports/tests/admin/CreateDatabase.java b/MySports Tests/src/example/mysports/tests/admin/CreateDatabase.java index 992b669..38cc33c 100644 --- a/MySports Tests/src/example/mysports/tests/admin/CreateDatabase.java +++ b/MySports Tests/src/example/mysports/tests/admin/CreateDatabase.java
@@ -49,7 +49,7 @@ EntityManagerFactory emf = null; try { - emf = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + emf = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); Server session = JpaHelper.getServerSession(emf); SchemaManager sm = new SchemaManager(session); @@ -69,7 +69,7 @@ public void verifyEmpty() throws Exception { EntityManagerFactory emf = null; try { - emf = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + emf = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); EntityManager em = emf.createEntityManager(); @@ -98,7 +98,7 @@ EntityManagerFactory emf = null; try { - emf = Persistence.createEntityManagerFactory("mysports-admin", properties); + emf = Persistence.createEntityManagerFactory("MySportsAdmin", properties); Server session = JpaHelper.getServerSession(emf); IntegrityChecker ic = session.getIntegrityChecker();
diff --git a/MySports Tests/src/example/mysports/tests/admin/CreateHostEnvironments.java b/MySports Tests/src/example/mysports/tests/admin/CreateHostEnvironments.java index 3fd98f9..7345d64 100644 --- a/MySports Tests/src/example/mysports/tests/admin/CreateHostEnvironments.java +++ b/MySports Tests/src/example/mysports/tests/admin/CreateHostEnvironments.java
@@ -78,7 +78,7 @@ @BeforeClass public static void createReposirory() { - emf = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + emf = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); EntityManager em = emf.createEntityManager(); try {
diff --git a/MySports Tests/src/example/mysports/tests/admin/CreateLeagues.java b/MySports Tests/src/example/mysports/tests/admin/CreateLeagues.java index 8a36dba..995783b 100644 --- a/MySports Tests/src/example/mysports/tests/admin/CreateLeagues.java +++ b/MySports Tests/src/example/mysports/tests/admin/CreateLeagues.java
@@ -72,7 +72,8 @@ HostedLeague kfl = new HostedLeague("KFL", "Kid's Football League", "green"); kfl.setLogoUrl("/logos/kfl.png"); kfl.setDatasourceName("jdbc/MySports"); - + kfl.setDataIsolation(DataIsolation.TABLE); + kfl.addPlayerExtension("position", "java.lang.String", "flex_1", "penalty-minutes/text()"); em.persist(kfl); @@ -93,7 +94,7 @@ @BeforeClass public static void createEMF() { - emf = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + emf = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); EntityManager em = emf.createEntityManager(); try {
diff --git a/MySports Tests/src/example/mysports/tests/admin/MockAdminMetadataSource.java b/MySports Tests/src/example/mysports/tests/admin/MockAdminMetadataSource.java index dc3959d..8187fb4 100644 --- a/MySports Tests/src/example/mysports/tests/admin/MockAdminMetadataSource.java +++ b/MySports Tests/src/example/mysports/tests/admin/MockAdminMetadataSource.java
@@ -65,7 +65,7 @@ private EntityManagerFactory getAdminEMF() { if (this.adminEMF == null) { - this.adminEMF = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + this.adminEMF = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); } return this.adminEMF; }
diff --git a/MySports Tests/src/example/mysports/tests/admin/MockAdminServerConnector.java b/MySports Tests/src/example/mysports/tests/admin/MockAdminServerConnector.java index 5e4a452..cd8e0ba 100644 --- a/MySports Tests/src/example/mysports/tests/admin/MockAdminServerConnector.java +++ b/MySports Tests/src/example/mysports/tests/admin/MockAdminServerConnector.java
@@ -83,6 +83,7 @@ l.setId(hl.getId()); l.setName(hl.getName()); l.setVersion(hl.getVersion()); + hl.getPlayerExtensions().size(); } return l; }
diff --git a/MySports Tests/src/example/mysports/tests/admin/VerifyModelAndMappings.java b/MySports Tests/src/example/mysports/tests/admin/VerifyModelAndMappings.java index 5f3ba2d..e5d4f69 100644 --- a/MySports Tests/src/example/mysports/tests/admin/VerifyModelAndMappings.java +++ b/MySports Tests/src/example/mysports/tests/admin/VerifyModelAndMappings.java
@@ -76,7 +76,7 @@ @BeforeClass public static void createEMF() { - emf = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + emf = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); } @AfterClass
diff --git a/MySports Tests/src/example/mysports/tests/admin/extensions/CreateOrmXML.java b/MySports Tests/src/example/mysports/tests/admin/extensions/CreateOrmXML.java index 3d7d7fb..ba924e4 100644 --- a/MySports Tests/src/example/mysports/tests/admin/extensions/CreateOrmXML.java +++ b/MySports Tests/src/example/mysports/tests/admin/extensions/CreateOrmXML.java
@@ -23,7 +23,7 @@ @Test public void createFromDB() { - EntityManagerFactory emf = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + EntityManagerFactory emf = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); EntityManager em = emf.createEntityManager(); try {
diff --git a/MySports Tests/src/example/mysports/tests/admin/league/LeagueJAXBTests.java b/MySports Tests/src/example/mysports/tests/admin/league/LeagueJAXBTests.java index ee7bf09..eaff3cb 100644 --- a/MySports Tests/src/example/mysports/tests/admin/league/LeagueJAXBTests.java +++ b/MySports Tests/src/example/mysports/tests/admin/league/LeagueJAXBTests.java
@@ -73,7 +73,7 @@ @BeforeClass public static void createEMF() { - emf = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + emf = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); } @AfterClass
diff --git a/MySports Tests/src/example/mysports/tests/admin/style/CreateStyles.java b/MySports Tests/src/example/mysports/tests/admin/style/CreateStyles.java index eb05d40..8880502 100644 --- a/MySports Tests/src/example/mysports/tests/admin/style/CreateStyles.java +++ b/MySports Tests/src/example/mysports/tests/admin/style/CreateStyles.java
@@ -70,7 +70,7 @@ @BeforeClass public static void createEMF() { - emf = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + emf = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); EntityManager em = emf.createEntityManager(); try {
diff --git a/MySports Tests/src/example/mysports/tests/model/CreateDatabase.java b/MySports Tests/src/example/mysports/tests/model/CreateDatabase.java index 365a0e5..884e7d6 100644 --- a/MySports Tests/src/example/mysports/tests/model/CreateDatabase.java +++ b/MySports Tests/src/example/mysports/tests/model/CreateDatabase.java
@@ -24,6 +24,7 @@ import org.eclipse.persistence.config.PersistenceUnitProperties; import org.eclipse.persistence.config.SessionCustomizer; import org.eclipse.persistence.descriptors.ClassDescriptor; +import org.eclipse.persistence.exceptions.DatabaseException; import org.eclipse.persistence.exceptions.IntegrityChecker; import org.eclipse.persistence.internal.sessions.ArrayRecord; import org.eclipse.persistence.jpa.JpaHelper; @@ -36,6 +37,7 @@ import example.mysports.MySportsConfig; import example.mysports.admin.model.HostedLeague; import example.mysports.ejb.LeagueRepository; +import example.mysports.model.Extensible; import example.mysports.tests.TestingLeagueRepository; import example.mysports.tests.admin.MockAdminServerConnector; @@ -72,10 +74,23 @@ @SuppressWarnings("unchecked") ArrayRecord record = (ArrayRecord) ((Vector<Object>) result).get(0); Assert.assertEquals(0, ((Number) record.getValues().get(0)).intValue()); + + if (Extensible.class.isAssignableFrom(desc.getJavaClass())) { + Assert.assertNotNull(desc.getMappingForAttributeName("flex1")); + session.executeSQL("SELECT flex_1 FROM " + desc.getTableName()); + Assert.assertNotNull(desc.getMappingForAttributeName("flex2")); + session.executeSQL("SELECT flex_2 FROM " + desc.getTableName()); + Assert.assertNotNull(desc.getMappingForAttributeName("flex3")); + session.executeSQL("SELECT flex_3 FROM " + desc.getTableName()); + Assert.assertNotNull(desc.getMappingForAttributeName("flex4")); + session.executeSQL("SELECT flex_4 FROM " + desc.getTableName()); + Assert.assertNotNull(desc.getMappingForAttributeName("flex5")); + session.executeSQL("SELECT flex_5 FROM " + desc.getTableName()); + } } } - @Test + //@Test public void createMHLMySportsSchema() throws Exception { Map<String, Object> properties = TestingLeagueRepository.get("MHL"); @@ -96,6 +111,40 @@ } } + @Test + public void createKFLMySportsSchema() throws Exception { + Map<String, Object> properties = TestingLeagueRepository.get("KFL"); + properties.put(PersistenceUnitProperties.ALLOW_NATIVE_SQL_QUERIES, "true"); + repository.setLeagueId("KFL", properties); + + Server session = repository.unwrap(Server.class); + + try { + session.executeNonSelectingSQL("DROP TABLE mys_player_kfl"); + } catch (DatabaseException dbe) { + } + try { + session.executeNonSelectingSQL("DROP TABLE mys_team_kfl"); + } catch (DatabaseException dbe) { + } + try { + session.executeNonSelectingSQL("DROP TABLE mys_div_kfl"); + } catch (DatabaseException dbe) { + } + + session.executeNonSelectingSQL("CREATE TABLE mys_div_kfl (ID INTEGER NOT NULL, DEF_DIV TINYINT(1) default 0, NAME VARCHAR(255), flex_1 VARCHAR(255), flex_2 VARCHAR(255), flex_3 VARCHAR(255), flex_4 VARCHAR(255), flex_5 VARCHAR(255), VERSION BIGINT, PRIMARY KEY (ID))"); + session.executeNonSelectingSQL("CREATE TABLE mys_player_kfl (ID INTEGER NOT NULL, EMAIL VARCHAR(255), F_NAME VARCHAR(255), L_NAME VARCHAR(255), NUM INTEGER, flex_1 VARCHAR(255), flex_2 VARCHAR(255), flex_3 VARCHAR(255), flex_4 VARCHAR(255), flex_5 VARCHAR(255), USER_ID VARCHAR(255), VERSION BIGINT, TEAM_ID INTEGER, PRIMARY KEY (ID))"); + session.executeNonSelectingSQL("CREATE TABLE mys_team_kfl (ID INTEGER NOT NULL, NAME VARCHAR(255), flex_1 VARCHAR(255), flex_2 VARCHAR(255), flex_3 VARCHAR(255), flex_4 VARCHAR(255), flex_5 VARCHAR(255), VERSION BIGINT, DIVISION_ID INTEGER, PRIMARY KEY (ID))"); + + for (ClassDescriptor desc : session.getDescriptors().values()) { + Object result = session.executeSQL("SELECT COUNT(*) FROM " + desc.getTableName()); + Assert.assertNotNull(result); + @SuppressWarnings("unchecked") + ArrayRecord record = (ArrayRecord) ((Vector<Object>) result).get(0); + Assert.assertEquals(0, ((Number) record.getValues().get(0)).intValue()); + } + } + /** * Verify the schema using the integrity checker to compare database * structure to that expected in the mappings. @@ -124,7 +173,7 @@ @BeforeClass public static void createLeagueRepository() { - EntityManagerFactory adminEMF = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + EntityManagerFactory adminEMF = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); EntityManager em = adminEMF.createEntityManager(); em.getTransaction().begin();
diff --git a/MySports Tests/src/example/mysports/tests/model/HighTechHockeyTests.java b/MySports Tests/src/example/mysports/tests/model/HighTechHockeyTests.java index 10b12fb..842f515 100644 --- a/MySports Tests/src/example/mysports/tests/model/HighTechHockeyTests.java +++ b/MySports Tests/src/example/mysports/tests/model/HighTechHockeyTests.java
@@ -78,7 +78,7 @@ @BeforeClass public static void createEMF() { - EntityManagerFactory adminEMF = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + EntityManagerFactory adminEMF = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); config = new MySportsConfig(); ((MockAdminServerConnector) config.getAdminConnector()).setEMF(adminEMF);
diff --git a/MySports Tests/src/example/mysports/tests/model/KidsFootballLeagueTests.java b/MySports Tests/src/example/mysports/tests/model/KidsFootballLeagueTests.java index 08edb73..de32ad9 100644 --- a/MySports Tests/src/example/mysports/tests/model/KidsFootballLeagueTests.java +++ b/MySports Tests/src/example/mysports/tests/model/KidsFootballLeagueTests.java
@@ -103,7 +103,7 @@ @BeforeClass public static void createEMF() { - EntityManagerFactory adminEMF = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + EntityManagerFactory adminEMF = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); config = new MySportsConfig(); ((MockAdminServerConnector) config.getAdminConnector()).setEMF(adminEMF);
diff --git a/MySports Tests/src/example/mysports/tests/model/MinorHockeyLeagueTests.java b/MySports Tests/src/example/mysports/tests/model/MinorHockeyLeagueTests.java index d017b09..6fce381 100644 --- a/MySports Tests/src/example/mysports/tests/model/MinorHockeyLeagueTests.java +++ b/MySports Tests/src/example/mysports/tests/model/MinorHockeyLeagueTests.java
@@ -79,7 +79,7 @@ @BeforeClass public static void createEMF() { - EntityManagerFactory adminEMF = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + EntityManagerFactory adminEMF = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); config = new MySportsConfig(); ((MockAdminServerConnector) config.getAdminConnector()).setEMF(adminEMF);
diff --git a/MySports Tests/src/example/mysports/tests/model/OttawaSoccerLeagueTests.java b/MySports Tests/src/example/mysports/tests/model/OttawaSoccerLeagueTests.java index 2d75791..3d7575e 100644 --- a/MySports Tests/src/example/mysports/tests/model/OttawaSoccerLeagueTests.java +++ b/MySports Tests/src/example/mysports/tests/model/OttawaSoccerLeagueTests.java
@@ -96,7 +96,7 @@ @BeforeClass public static void createEMF() { - EntityManagerFactory adminEMF = Persistence.createEntityManagerFactory("mysports-admin", TestingLeagueRepository.get()); + EntityManagerFactory adminEMF = Persistence.createEntityManagerFactory("MySportsAdmin", TestingLeagueRepository.get()); config = new MySportsConfig(); ((MockAdminServerConnector) config.getAdminConnector()).setEMF(adminEMF);
diff --git a/MySports Tests/src/example/mysports/tests/persistence/CreateTenantEMF.java b/MySports Tests/src/example/mysports/tests/persistence/CreateTenantEMF.java new file mode 100644 index 0000000..4011d6b --- /dev/null +++ b/MySports Tests/src/example/mysports/tests/persistence/CreateTenantEMF.java
@@ -0,0 +1,27 @@ +package example.mysports.tests.persistence; + +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.junit.Test; + +import example.mysports.MySportsConfig; +import example.mysports.persistence.MultitenantPersistenceProvider; + +public class CreateTenantEMF { + + @Test + public void createKFL() throws Exception { + Map<String, Object> properties = new HashMap<String, Object>(); + properties.put(MultitenantPersistenceProvider.TEMPLATE_PU_NAME, MySportsConfig.PU_NAME); + + EntityManagerFactory emf = Persistence.createEntityManagerFactory(MySportsConfig.PU_NAME + "-KFL", properties); + + Assert.assertNotNull(emf); + } +}