Как передать заголовок http в качестве спящего фильтра в dropwizard?

Я работаю над многопользовательским приложением, использующим аннотацию Hibernate @Filter для неявной фильтрации объектов по пользователю (как описано в этом блоге: http://blog.lunatech.com/2011/03/04/play-framework-writing-multitenancy-application-hibernate-filters)

Идентификатор клиента передается в заголовке HTTP, который перехватывается фильтром Джерси и устанавливается в сеансе Hibernate, используя следующий код:

public class TenantFilter implements ContainerRequestFilter {
    private SessionFactory sessionFactory;

    public TenantFilter(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public ContainerRequest filter(ContainerRequest request) {
        String tenantId = request.getHeaderValue("X-TENANT-ID");
        Session currentSession = sessionFactory.openSession();
        currentSession.enableFilter("tenant").setParameter("tenant_id", tenantId);
        return request;
    }
}

Но этот параметр фильтра не устанавливается, когда DAO выполняет запрос, поскольку сеанс гибернации, используемый в методе Resource и фильтре, не совпадает (использование currentSession приводит к ошибке недоступности сеанса)

Как передать параметр арендатора в сеанс Hibernate в Dropwizard в том же контексте транзакции, что и метод ресурса Dropwizard? Фильтр Джерси не выполняется в том же контексте транзакции, поскольку @UnitOfWork находится в методе Resource.

1 ответ

В игре сеансы БД обрабатываются самой платформой. Подобно открытию соединения и установке открытого сеанса для текущего потока / тот, кто аннотирован @Transaction, будет доступен только там. Вы не можете открыть сеанс и закрыть сеанс в своем коде.

Вы должны создать свой собственный JPAPlugin, как плагин jpa игры. Создайте один сеанс для каждого запроса и свяжите его с текущим потоком (Threadlocal) и используйте его, пока запрос не будет обработан.

Во время первоначального создания сеанса вы можете включить фильтр, а в конце процесса запроса вы можете отключить фильтр и закрыть сеанс.

Таким образом, мы обрабатывали роли и разрешения в наших приложениях (используя аспекты).

Пожалуйста, взгляните на пост, приведенный ниже, он даст вам представление о том, как создать свой собственный плагин db.

Play2 Как управлять транзакцией из сервисного слоя вместо экшн-слоя?

Надеюсь, что это даст намек.

SessionImplementor currentSession = ((SessionImplementor) em (ключ).getDelegate()); currentSession.enableFilter("tenant").setParameter("tenant_id", tenantId);

Другие вопросы по тегам