J'ai essayé de multi-locataire avec Hibernate 3.
Chaque table a une colonne SystemId pour distinguer les locataires.
J'ai ajouté un filtre Hibernate à une entité JPA qui ajoute la colonne SystemId aux critères de recherche.
J'ai ajouté les annotations suivantes à la configuration pour utiliser ma propre fabrique de référentiels.
@EnableJpaRepositories(basePackages = "com.example.dataaccess.repositories",
        repositoryFactoryBeanClass = PrimaryRepositoryFactoryBean.class)
PrimaryRepositoryFactoryBean.class
public class PrimaryRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends JpaRepositoryFactoryBean<T, S, ID> {
    @Autowired //Cet enfant a un SystemId
    private CurrentAppUserDetailsProvider currentAppUserDetailsProvider;
    @Override //Renvoie RepositoryFactory
    protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
        return new MyRepositoryFactory(entityManager, currentAppUserDetailsProvider);
    }
    private static class MyRepositoryFactory<E, I extends Serializable> extends JpaRepositoryFactory {
        private final EntityManager entityManager;
        private final CurrentAppUserDetailsProvider currentAppUserDetailsProvider;
        public MyRepositoryFactory(EntityManager entityManager,
                CurrentAppUserDetailsProvider currentAppUserDetailsProvider) {
            super(entityManager);
            this.entityManager = entityManager;
            this.currentAppUserDetailsProvider = currentAppUserDetailsProvider;
        }
        @Override
        protected Object getTargetRepository(RepositoryMetadata metadata) {
            Object repository = super.getTargetRepository(metadata);
            SessionFactory sessionFactory = entityManager.getEntityManagerFactory().unwrap(SessionFactory.class);
            Session session = sessionFactory.getCurrentSession(); //Il y a une exception! !!
            session.enableFilter("SYSTEM_ID_FILTER")
                    .setParameter("systemId", getSystemId());
            return repository;
        }
        private int getSystemId() {
            return currentAppUserDetailsProvider
                    .getCurrentAppUserDetails()
                    .getSystemId();
        }
    }
}
Au moment de l'instanciation du référentiel, il n'y a pas de session car la transaction n'a pas démarré.
C'est naturel, non?
Recommended Posts