here I have a problem that I want to find a solution here, I work on a project using spring mvc and hibernate in my project I have several databases with same architecture (database by company) and a database for authentication, when the user login i have to generates a SessionFactory that corresponds to database of the user company, can you help me by offering me an architecture and give me some examples please, sorry for my English.
1 Answers
Depending on which hibernate version you use you can just utilize the built in multi tenant features of hibernate. For that you need to implement the CurrentaTenantIdentifierResolver
and MultiTenantConnectionProvider
following this documentationthis documentation
the following hibernateProperties have to be set additionaly to use them:
hibernate.multiTenancy=DATABASE
hibernate.tenant_identifier_resolver=xxx.xxx.CurrentTenantIdentifierResolverImpl
hibernate.multi_tenant_connection_provider=xxx.xxx.MultiTenantConnectionProviderImpl
Sample Implementation: CurrentTenantIdentifier:
import javax.faces.context.FacesContext;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
public class CurrentTenantIdentifierResolverImpl implements CurrentTenantIdentifierResolver {
@Override
public String resolveCurrentTenantIdentifier() {
if (SecurityContextHolder.getContext().getAuthentication().getPrincipal().yourOwnRoutineToDetermineCompanyxxx=="companyxxx"){
return "companyxxx";
} else if ... furhter companies{
...
}
}
@Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
MultiTenantConnectionProvider:
public class MultiTenantConnectionProviderImpl extends AbstractMultiTenantConnectionProvider {
@Autowired
private DataSoruce DScompany02;
@Autowired
private DataSource DScompany01;
@Autowired
private DataSource default;
@Override
protected ConnectionProvider getAnyConnectionProvider() {
return new DatasourceConnectionProvider(default);
}
@Override
protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
if (tenantidentifer == "company01"){
return new DatasourceConnectionProvider(DScompany01);
} repeat....
}
}
now just define a datasource per company DB so it can be swapped by the multitenantconnectionprovider.
A call to the sessionFactory in the DAO can be made by using SessionFactory.getCurrentSession()
or in special cases by using sessionFactory.withOptions().tenantIdentifier("company01").openSession()
This should cover the basics but might need some tayloring to your application.

- 1,511
- 2
- 13
- 24
-
Hi Carsten, thank you for reply, i use spring 3.2.2-RELEASE with hibernate 4.2, for exemple the user from companyxxx is authenticated, and now i have to create au session factory who connect to url "localahost:3306/dbcompanyxxx", how to do that, in my DAO i have to do somthing like public List
getModel(){SessionFactory sesseionFactory = SessionManager.getSessionFactory(user.getIdCompany(); .....} can you developpe your answer please – user820688 May 27 '13 at 09:06 -
Elaborated the answer a bit. – Carsten May 27 '13 at 09:35
-
ok thanks, when i use openSession it work, but i willnot have a probleme with read or write in the databases ? – user820688 May 27 '13 at 09:45
-
No, the session you get is opened with the (for that instance) relevant DB connection. On this sesion you can do everything you can with a "standard" hibernate implementation. – Carsten May 27 '13 at 10:36
-
Thanks for solution, i will use this :-) – user820688 May 27 '13 at 12:08