-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Is there a way inside ZK to have a class run for each request from the client to the server?
For a multi tenant application I'm using a ThreadLocal to store a key to identify what data source to access. I can't think of a way of storing a thread local somewhere and have it reloaded for every request.
do you work with hibernate?
A simple Servlet filter should work fine, or alternatively thet ExecutionInit/ExecutionCleanup -mechanism if you need access to ZK-specific stuff.
I remember that i have searched a long time for a hibernate inBuild mechanism for to do that and found a simple but working idea in a blog.
I can adapt all three kinds of multi-tenancy with it.
1. All tenants data in a single table with a discriminator field.
2. All tenants data in separated tables (schemas)
3. All tenants data in separated databases.
Try this:
/** * Copyright (C) 2010 - 2013 Forsthaus IT Consulting GbR. * * This file is part of openTruuls™. http://www.opentruuls.org/ * * openTruuls™ community edition is free software: * you can redistribute it and/or modify it under the terms of the * GNU Lesser General Public License as published by the Free Software * Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses></http:>. * * If you need a commercial license please write us under [email protected] */ package org.opentruuls.backend.data.util; import javax.servlet.http.HttpSession; import org.apache.commons.lang.StringUtils; import org.hibernate.EmptyInterceptor; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; /** * EN: Hibernate Interceptor. The prepared SQL Statement will be modified for * the tenants table schemata name used by the tenant before Hibernate is * executing the query.<br> * <br> * DE: Hibernate Interceptor. Hier wird das vorbereitete SQL Statement mit dem * zum Mandanten gehoerigen Tabellen Schema Namen ergaenzt bevor Hibernate es * ausfuehrt. D.h. der default Tabellen SchemaName 'public' wird mit dem jeweils * zum Mandanten gehoerigen Namen ersetzt. Der Name 'public' ist also geschuetzt * und sollte keinesfalls weder in einem TabellenNamen oder einem FeldNamen * vorkommen<br> * <br> * Besser: '"PUBLIC"."' = '"4711"."' | SELECT * FROM "PUBLIC"."MYTABLE" <br> * <br> * TODO Es ist natuerlich sicherer den Tabellen SchemaNamen extern zu setzen als * durch eine String Manipulation im abzusetzenden SQL-Statement. Fuer * PostgreSQL hiesse dass, den 'search_path' zu setzen:<br> * // String sPath = "SET search_path TO " + schemaName; <br> * * @author Stephan Gerth */ public class FHHibernateInterceptor extends EmptyInterceptor { private static final long serialVersionUID = 1L; @Override public String onPrepareStatement(String sql) { String preparedStatement = super.onPrepareStatement(sql); String schemaName = getSchemaNameFromSessionContext(); if (StringUtils.isNotEmpty(schemaName)) { preparedStatement = preparedStatement.replaceAll("public.", schemaName + "."); } return preparedStatement; } /** * EN: Gets the tables schema name from the Users SessionContext.<br> * * DE: Gibt den Tabellen Schema Namen aus dem User Session Kontext zurueck.<br> * * @return table schema name / Tabellen Schema Name * @see de.forsthaus.policy.model.PolicyManager */ private String getSchemaNameFromSessionContext() { RequestAttributes atr = RequestContextHolder.currentRequestAttributes(); HttpSession ses = (HttpSession) atr.getSessionMutex(); String res = (String) ses.getAttribute("SchemaName"); String result = StringUtils.trim(res); // System.out.println("----------> SessionID :" + atr.getSessionId()); return result; } }
FHSessionUtil.java
Sets the table schema name after a login from the tenant user
. . . /** * EN: Sets the TableSchemaName Attribute in the user's session.<br> * DE: Setzt das TableSchemaName Attribut in der User Session.<br> * * @param schemaName * the table schema name / Der Tabellen Schema Name */ public static void setTablesSchemaName(String schemaName) { getSession().setAttribute("SchemaName", schemaName); } . . .
best
Stephan
Asked: 2012-12-19 21:15:43 +0800
Seen: 74 times
Last updated: Dec 21 '12