Sneak peak at Java EE 7 - Multitenant Examples with EclipseLink
Join the DZone community and get the full member experience.
Join For FreeThe Aquarium is a great source of inspiration and most recent
information about Java EE progress across all relevant specifications
and reference implementations. They picked up a presentation by Oracle's
Shaun Smith (blog/twitter)
about the status and future of EclipseLink as an open source project.
He covers all the new features which are going to be in EclipseLink 2.4
which will be availabke along with the June Eclipse Juno Release. In
detail these are REST, NoSQL and Multitenancy. (details refer to the complete slide-deck (PDF) from the marsjug event.)
I like to see that EclipseLink still is the center of innovation in Java
persistence and they are trying hard to adopt latest buzz timely.
Working for a more conservative industry in general the main new feature
I am looking for is multitenancy. What you can guess from the slides
is, that something in this field should already be working with latest
EclipseLink 2.3.0.
What is Multitenancy going to look like?
Let's start looking at what Oracle's Linda DeMichiel announced at last years JavaOne (compare blog-post) and also let's look at what the early draft (PDF)
of the JPA 2.1 specification has to offer. The easier part is the early
draft. Not a single line mentions "Multitenan[t|cy]" in any context.
So, this is obviously still a big to do for further iterations. A bit
more could be found in the JavaOne Strategy Keynote (Slides 41,42) and the JavaOne Technical Keynote (PDF)
(Slide 25). The general Java EE 7 approach will be to have support for
separate isolated instances of the same app for different tenants. The
mapping should be done by the container and be available to apps in some
way. This is all very vague until today and the only concrete code
examples available from the slides refer to some obvious JPA related
examples using two annotations @Multitenant and
@TenantDiscriminatorColumn. Hmm. Doesn't this look familiar to you?
What is possible today?
It does! EclipseLink (as of 2.3.0 - Indigo) supports shared multitenant
tables using tenant discriminator column(s), allowing an application to
be re-used for multiple tenants and have all their data co-located. All
tenants share the same schema without being aware of one another and can
use non-multitenant entity types as per usual. But be aware of the
fact, that this is only one possible approach to multitenancy for data.
This is commonly referred to as "dedicated database" because all
tenant's data go into one single db! The basic principles for the
following are:
- application instances handle multiple tenants
- caching has to be isolated for every tenant by JPA
You can look at all the details on a dedicated EclipseLink wiki page. Want to give it a test drive? let's start. Prerequisites as usual (NetBeans, GlassFish, MySQL, compare older posts
if you need more help.). Make sure to have the right EclipseLink
dependencies (at least 2.3.0)! Create a new entity via the wizard, setup
your datasource and persistence.xml and call it e.g. Customer.
Dedicated Persistence Unit
In this usage there is a persistence unit defined per tenant and the application/container must request the correct PersistenceContext or PersistenceUnit for its tenant. There is one single persistence unit and nothing is shared. Go with the above example and add the following property to your persistence.xml:
As you can see, you now have your companyId column. If you insert some data it will always be filled with the property value you assigned in the persistence.xml. Use either a @PersistenceContext or a @PersistenceUnit to access your entities. Using this approach you have a shared cache as usual for your application.
![]() |
@PersistenceContext with Shared Cache (Source: S.Smith) |
Persistence Context per Tenant
If you don't want to have a single tenant per application you could decide to have a single persistence unit definition in the persistence.xml and a shared persistence unit (EntityManagerFactory and cache) in you application. In this case the tenant context needs to be specified per EntityManager at runtime. In this case you have a shared cache available for regular entity types but the @Multitenant types must be protected in the cache. You do this by specifying some properties:
![]() |
Shared @PersistenceUnit per tentant (Source: S.Smith) |
Discriminator Approaches
The above examples work with a single discriminator tenant column. You can add the discriminator column to the PK by specifying a primaryKey attribute like the following:
This leads to a secondary tenants table.
Additional Goodies
As always you can do the complete configuration within your persistence.xml only, too. For a reference please look at the already mentioned wiki page. One last thing is of interest. You could also map the tenant discriminator column with your entity. You simple have to make sure it isn't updated or inserted.
INFO: Getting EntityManager INFO: Inserting Test Customer FEIN: INSERT INTO CUSTOMER (ID, TENANT_ID) VALUES (?, ?) bind => [1, 2] FEIN: INSERT INTO TENANTS (ID, TENANT_CODE) VALUES (?, ?) bind => [1, TENANT2] FEIN: SELECT t0.ID, t1.TENANT_CODE, t0.TENANT_ID, t1.ID FROM CUSTOMER t0, TENANTS t1 WHERE
(((t1.ID = t0.ID) AND (t1.TENANT_CODE = ?)) AND (t0.TENANT_ID = ?)) bind => [TENANT2, 2]
Curious for more Java EE 7 and JPA 2.1 goodies? Keep updated with the development status wiki page for the EclipseLink JPA 2.1 project.
From http://blog.eisele.net/2012/01/sneak-peak-at-java-ee-7-multitenant.html
Opinions expressed by DZone contributors are their own.
Trending
-
Auto-Scaling Kinesis Data Streams Applications on Kubernetes
-
What ChatGPT Needs Is Context
-
What Is JHipster?
-
Replacing Apache Hive, Elasticsearch, and PostgreSQL With Apache Doris
Comments