Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » What is the right approach for Multi-tenancy using eclipselink
What is the right approach for Multi-tenancy using eclipselink [message #1759998] Fri, 21 April 2017 05:31 Go to next message
Nazmul Price is currently offline Nazmul PriceFriend
Messages: 2
Registered: April 2017
Junior Member
Hello I'm developing a web application using Vaadin framework, JPA EclipseLink as ORM, MYSQL as database. Currently I'm working to implement Multitenant structure for my app. Here I've to choose TABLE_PER_TENANT with different schema in a shared database strategy as I already have some tenants.

Here is an example of my tenant specific entity:

    @Entity
    @Multitenant(MultitenantType.TABLE_PER_TENANT)
    @TenantTableDiscriminator(type = TenantTableDiscriminatorType.SCHEMA, contextProperty = PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT)
    public class UserAccount implements Serializable {
    ......
    }

Here is my persistence unit for tenant in persistence.xml :
    <persistence-unit name="GroupBuilderPU" transaction-type="RESOURCE_LOCAL">
            <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
            <class>Includes all tenant table class</class>
            <properties>
                <property name="eclipselink.cache.shared.default" value="false"/>
                <!-- container isn upcloud ??-->
                 <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/?rewriteBatchedStatements=true&amp;characterEncoding=UTF-8&amp;connectionCollation=utf8_general_ci&amp;zeroDateTimeBehavior=convertToNull&amp;useUnicode=true&amp;connectionCollation=utf8_general_ci&amp;characterSetResults=utf8&amp;characterEncoding=utf8&amp;characterEncoding=UTF-8&amp;characterSetResults=UTF-8"/>
                <property name="javax.persistence.jdbc.user" value="root"/>
                <property name="javax.persistence.jdbc.password" value="root"/>
                      
                <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
                <property name="eclipselink.ddl-generation" value="create-or-extend-tables"/>
                <property name="eclipselink.jdbc.batch-writing" value="JDBC"/>
                <property name="eclipselink.jdbc.batch-writing.size" value="1000"/>
                <property name="hibernate.connection.useUnicode" value="true"/>
                <property name="hibernate.connection.characterEncoding" value="UTF-8"/>
            </properties>
        </persistence-unit>


Now I'm getting an entitymanager like this:


    public static EntityManager createTenantSpecificEntityManager(){
            EntityManager em = Persistence.createEntityManagerFactory(GroupBuilderApp.PERSISTENCE_UNIT).createEntityManager(getProperties());
            
            return em;
        }
    
    private static Map<String, Object> getProperties(){
            Map<String, Object> properties = new HashMap<>();
            properties.put("javax.persistence.jdbc.url", getDataBaseConnectionURL(COMPANY_NAME_AS_TENENT_ID));
            
            return properties;
        }
    public static String getDataBaseConnectionURL(String schemaName){
            String str = "jdbc:mysql://localhost:3306/?rewriteBatchedStatements=true&amp;characterEncoding=UTF-8&amp;connectionCollation=utf8_general_ci&amp;zeroDateTimeBehavior=convertToNull&amp;useUnicode=true&amp;connectionCollation=utf8_general_ci&amp;characterSetResults=utf8&amp;characterEncoding=utf8&amp;characterEncoding=UTF-8&amp;characterSetResults=UTF-8";//for testing purpose
            StringBuilder sb = new StringBuilder(str);
            sb.insert(sb.indexOf("?"), schemaName);
            return sb.toString();
        }


Now I'm using entitymanager like this:

    em = createTenantSpecificEntityManager();
    em.getTransaction().begin();
           em.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, GroupBuilderApp.COMPANY_NAME_AS_TENENT_ID);
    .......
    Do any operation here
    .......
    em.getTransaction().commit();
    em.close();


In the app user can log in to a specific tenant (where he has given the access). So at a time only one tenant's data can be accessed.

Is it the right approach for my app to make it Multi-tenant?
Is there any improvement I can do?
Re: What is the right approach for Multi-tenancy using eclipselink [message #1761429 is a reply to message #1759998] Thu, 11 May 2017 04:51 Go to previous messageGo to next message
Vitaly Gorbunov is currently offline Vitaly GorbunovFriend
Messages: 7
Registered: July 2012
Junior Member
We tried to use schema-per-tenant configuration in the past and I would strongly not recommend it. It's design is really error-prone, hard to maintain and can be rather dangerous.

It's based on idea of cloning mapping metadata for each tenant. Which implies careful implementation of clone methods in each complex metadata object to avoid shared objects between different tenants.
It seems to be not the case, since we faced multiple cases of violation of such rule, which was not clear how to solve.
As a result we could have mapping metadata corruption - and in some cases it leads to exception, in some - it can write data to incorrect schema.

--

Instead I would recommend to use @org.eclipse.persistence.annotations.Partitioning. It will require separate connection pool per schema, but implementation in eclipselink is pretty clear and straight-forward.
Re: What is the right approach for Multi-tenancy using eclipselink [message #1763410 is a reply to message #1761429] Mon, 15 May 2017 13:26 Go to previous message
Nazmul Price is currently offline Nazmul PriceFriend
Messages: 2
Registered: April 2017
Junior Member
Thanks for the reply.

Any good example regarding to your approach?
Previous Topic:EclipseLink: internal pool and external pool usage
Next Topic:javaagent and eclipselink.persistencexml
Goto Forum:
  


Current Time: Thu Dec 14 04:26:22 GMT 2017

Powered by FUDForum. Page generated in 0.02152 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software