Jump to: navigation, search

Difference between revisions of "EclipseLink/Examples/MySports/EMFperTenant"

(persistence.xml)
(Usage)
 
(9 intermediate revisions by the same user not shown)
Line 1: Line 1:
 +
<div style="float:right;width:300px"><div style="background:#ffffff;width:275px" align="center">__TOC__</div></div>
 +
 
The EclipseLink [[EclipseLink/Examples/MySports|MySports Example]] implements a SaaS based solution where a single instance of the MySports application to handle requests for multiple leagues (tenants). Each league has its own custom look and feel as well as custom extension attributes for entities. Having different extension attributes requires different mappings for each tenant and thus you must have a separate EntityManagerFactory (EMF). To implement the EMF per tenant in a common application the EclipseLink persistence framework needs to be extended with a custom JPA persistence provider.
 
The EclipseLink [[EclipseLink/Examples/MySports|MySports Example]] implements a SaaS based solution where a single instance of the MySports application to handle requests for multiple leagues (tenants). Each league has its own custom look and feel as well as custom extension attributes for entities. Having different extension attributes requires different mappings for each tenant and thus you must have a separate EntityManagerFactory (EMF). To implement the EMF per tenant in a common application the EclipseLink persistence framework needs to be extended with a custom JPA persistence provider.
  
 
== Provider ==
 
== Provider ==
  
=== persistence.xml ===
+
While EclipseLink 2.4.0 does not offer explicit support for EntityManagerFactory (EMF) per tenant it is possible to construct an extended JPA provider that handles this usage scenario. In order to introduce an extended PersistenceProvider two classes needed to be added to the MySports example:
 +
* example.mysports.persistence.MySportsProvider ([http://git.eclipse.org/c/eclipselink/examples/mysports.git/tree/MySports%20App/jpa-provider/example/mysports/persistence/MySportsProvider.java src])
 +
** Handles the use of 'mysports-{league}' persistence unit names where the prefix is used as the template persistence unit name.
 +
* example.mysports.persistence.MySportsProviderInitializer ([http://git.eclipse.org/c/eclipselink/examples/mysports.git/tree/MySports%20App/jpa-provider/example/mysports/persistence/MySportsProviderInitializer.java src])
 +
** Handles the initialization from both the container and agent weaving
 +
* /META-INF/services/javax.persistence.spi.PersistenceProvider
 +
** Makes the provider discoverable
  
 +
=== Configuration: persistence.xml ===
  
 +
Here is what the template persistence unit is defined as. It is this persistence unit that is used and customized to create the tenant specific persistence unit.
  
 
<source lang="xml">
 
<source lang="xml">
<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 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">
 
<persistence-unit name="mysports" transaction-type="RESOURCE_LOCAL">
 
<provider>example.mysports.persistence.MySportsProvider</provider>
 
<provider>example.mysports.persistence.MySportsProvider</provider>
Line 19: Line 33:
 
<class>example.mysports.model.Division</class>
 
<class>example.mysports.model.Division</class>
 
<validation-mode>NONE</validation-mode>
 
<validation-mode>NONE</validation-mode>
 +
               
 +
                <properties>
 +
                <!-- ... -->
 +
                </properties>
 +
 +
</persistence-unit>
 +
</persistence>
 
</source>
 
</source>
 +
 +
== Java SE Testing ==
 +
 +
In order to test outside of a container using the custom PersistenceProvider a new agent is required.
 +
* example.mysports.persistence.MySportsWeavingAgent ([http://git.eclipse.org/c/eclipselink/examples/mysports.git/tree/MySports%20Tests/agent-src/example/mysports/persistence/MySportsWeavingAgent.java src])
 +
** Implements agent's premain and initialize methods for both weaving options.
 +
* META-INF/MANIFEST.MF ([http://git.eclipse.org/c/eclipselink/examples/mysports.git/tree/MySports%20Tests/agent-src/META-INF/MANIFEST.MF src])
 +
** Required for the agent to be invoked at bootstrap
 +
<pre>Premain-Class: example.mysports.persistence.MySportsWeavingAgent</pre>
 +
 +
The mysports-agent.jar provided in the test project is then used instead of EclipseLink's. This agent is pre-configured in the provided run configurations.
 +
 +
== Usage ==
 +
 +
In order to use access a league (tenant)'s persistence unit it can simply be looked up using the name: 'mysports-???' where '???' is the league identifier.
 +
 +
=== JPS-RS Usage ===
 +
 +
Since the MySports application also exposes its persistence unit(s) over REST using [[EclipseLink/Release/2.4.0/JPA-RS|JPA-RS]] the tenant specific persistence units must be exposed as well.
 +
 +
EXAMPLE:
 +
<pre>
 +
GET: http://localhost:8080/MySports/persistence/mysports-OSL/metadata
 +
</pre>

Latest revision as of 14:34, 21 June 2012

The EclipseLink MySports Example implements a SaaS based solution where a single instance of the MySports application to handle requests for multiple leagues (tenants). Each league has its own custom look and feel as well as custom extension attributes for entities. Having different extension attributes requires different mappings for each tenant and thus you must have a separate EntityManagerFactory (EMF). To implement the EMF per tenant in a common application the EclipseLink persistence framework needs to be extended with a custom JPA persistence provider.

Provider

While EclipseLink 2.4.0 does not offer explicit support for EntityManagerFactory (EMF) per tenant it is possible to construct an extended JPA provider that handles this usage scenario. In order to introduce an extended PersistenceProvider two classes needed to be added to the MySports example:

  • example.mysports.persistence.MySportsProvider (src)
    • Handles the use of 'mysports-{league}' persistence unit names where the prefix is used as the template persistence unit name.
  • example.mysports.persistence.MySportsProviderInitializer (src)
    • Handles the initialization from both the container and agent weaving
  • /META-INF/services/javax.persistence.spi.PersistenceProvider
    • Makes the provider discoverable

Configuration: persistence.xml

Here is what the template persistence unit is defined as. It is this persistence unit that is used and customized to create the tenant specific persistence unit.

<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.MySportsProvider</provider>
		<non-jta-data-source>jdbc/MySports</non-jta-data-source>
		<mapping-file>META-INF/local-eclipselink-orm.xml</mapping-file>
 
		<class>example.mysports.model.User</class>
		<class>example.mysports.model.Team</class>
		<class>example.mysports.model.Player</class>
		<class>example.mysports.model.Division</class>
		<validation-mode>NONE</validation-mode>
 
                <properties>
                <!-- ... -->
                </properties>
 
	</persistence-unit>
</persistence>

Java SE Testing

In order to test outside of a container using the custom PersistenceProvider a new agent is required.

  • example.mysports.persistence.MySportsWeavingAgent (src)
    • Implements agent's premain and initialize methods for both weaving options.
  • META-INF/MANIFEST.MF (src)
    • Required for the agent to be invoked at bootstrap
Premain-Class: example.mysports.persistence.MySportsWeavingAgent

The mysports-agent.jar provided in the test project is then used instead of EclipseLink's. This agent is pre-configured in the provided run configurations.

Usage

In order to use access a league (tenant)'s persistence unit it can simply be looked up using the name: 'mysports-???' where '???' is the league identifier.

JPS-RS Usage

Since the MySports application also exposes its persistence unit(s) over REST using JPA-RS the tenant specific persistence units must be exposed as well.

EXAMPLE:

GET: http://localhost:8080/MySports/persistence/mysports-OSL/metadata