|
|
|
|
Re: Multi tenancy with schema per tenant [message #1489636 is a reply to message #1482313] |
Thu, 27 November 2014 14:48 |
Martin Frano Messages: 6 Registered: November 2014 |
Junior Member |
|
|
UPDATE 26.6.2015: This isn't completelly right solution. Read also comments below or go to my article at http://www.mafospace.com/articles/multi-tenancy-with-eclipselink-and-inherited-entities
I've solved it finally. Maybe it will be helpful for someone. I've done that in similar way as described in article I linked in first post. Through custom transaction manager.
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.internal.jpa.EntityManagerImpl;
import org.eclipse.persistence.sessions.coordination.MetadataRefreshListener;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.springframework.orm.jpa.JpaTransactionManager;
import sk.bantip.hotel.server.security.SecurityHelper;
import javax.persistence.EntityManager;
import java.util.HashMap;
import java.util.Map;
public class MultiTenantJpaTransactionManager extends JpaTransactionManager {
/**
* NOTE:
* Maybe it would be also possible to replace existing entityManager in transaction with new but it
* isn't a good idea because of rollback and other problems.
* So when new tenant is required always start new transaction for it.
*/
@Override
protected javax.persistence.EntityManager createEntityManagerForTransaction() {
EntityManager em = super.createEntityManagerForTransaction();
boolean refreshed = false;
String actualTenant = null;
ServerSession ss = ((EntityManagerImpl) em.getDelegate()).getServerSession();
Map sessionProp = ss.getProperties();
actualTenant = (String) sessionProp.get(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT);
// don't run it if tenant didn't change
// it should be quite faster then
if ((actualTenant == null && SecurityHelper.getActiveTenantSchema() != null) ||
(actualTenant != null && !actualTenant.equals(SecurityHelper.getActiveTenantSchema()))) {
// set new tenant as property for actual session
// while refreshing metadata it will be used from actual session for new session
sessionProp.put(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, SecurityHelper.getActiveTenantSchema());
MetadataRefreshListener mrl = ((EntityManagerImpl) em.getDelegate()).getServerSession().getRefreshMetadataListener();
// metadata refresh listener is empty if it was already run for actual transaction (same entity manager)
// because it is placed in createEntityManagerForTransaction now this shouldn't happen but to be sure...
if (mrl != null) {
Map<String, Object> prop = new HashMap<String, Object>();
// metadata will be refreshed for next created entity manager
mrl.triggerMetadataRefresh(prop);
refreshed = true;
}
}
// if metadata for "old" entity manager wasn't refreshed we don't need to create a new one
return refreshed ? super.createEntityManagerForTransaction() : em;
}
}
Everything seems to work except inheritance with strategy type JOINED now. To fix that use customizer.
import org.eclipse.persistence.annotations.TenantTableDiscriminatorType;
import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.TablePerMultitenantPolicy;
/**
* For some reason when using table per tenant with schema discriminator isn't set good for child
* entities with inheritance JOINED strategy. It stay as SUFFIX and therefore it doesn't work.
*/
public class InheritanceJoinedMTFixCustomizer implements DescriptorCustomizer {
@Override
public void customize(ClassDescriptor descriptor) throws Exception {
// set discriminator to SCHEMA
((TablePerMultitenantPolicy) descriptor.getMultitenantPolicy())
.setTenantTableDiscriminatorType(TenantTableDiscriminatorType.SCHEMA);
}
}
And in child entities use it like this:
...
@Customizer(InheritanceJoinedMTFixCustomizer.class)
public class Person extends Contact {
...
[Updated on: Fri, 26 June 2015 11:15] Report message to a moderator
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03574 seconds