Как передать заголовок 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);