title: Unable to enable hibernate filter in spring EntityManager using spring aop
body: <p>I'm trying to enable a hibernate filter through spring <code>EntityManager</code> by tyring to pointcut a service implementation method annotated with custom annotation <code>@TenantAware</code> and add <code>@Around</code> advise to that method. I want to enable custom filter which adds a differentiator <code>where tenant_id = :tenantId</code> on all entities that extend a <code>BaseEntity</code>. Hence I created the custom annotation and using it on <code>@Transactional</code> methods where it is required.  It is intercepting the method successfully but the variable values when I log them are showing up empty and neither is the filter being set.</p>
  
  <p>The project is a spring-boot 2 application and I'm using spring aop for creating the aspect. I'm using Hibernate 5 as the JPA implementation provider.</p>
  
  <p>Load time weaving of the <code>SimpleJpaRepository.class</code> is not possible since it does not expose a noarg constructor.</p>
  
  <p>This is my <code>TenantFilterAdvisor</code> class.</p>
  
  <pre><code>package org.foo.bar.advisors;
  
  @Aspect
  @Slf4j
  @Component
  public class TenantFilterAdvisor {
  
      @PersistenceContext
      private EntityManager entityManager;
  
      public TenantFilterAdvisor() {
          log.debug("###########################################################################");
          log.debug("###################### Tenant Advisor Filter Started ######################");
          log.debug("###########################################################################");
      }
  
      @Pointcut(value = "@annotation(org.foo.bar.TenantAware)")
      public void methodAnnotatedWithTenantAware() {
      }
  
      @Pointcut(value = "execution(public * * (..))")
      public void allPublicMethods() {
  
      }
  
      @Around(value = "methodAnnotatedWithTenantAware() &amp;&amp; allPublicMethods()")
      public Object enableTenantFilter(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
  
          log.debug("###########################################################################");
          log.debug("###################### Before enabling tenant filter ######################");
          log.debug("###########################################################################");
  
          if (null != entityManager) {
  
              log.debug("Tenant filter name: ", "tenantFilter");
              log.debug("Tenant filter property: ", "tenantId");
              log.debug("Setting tenant id to: ", new Long(10));
  
              Session session = entityManager.unwrap(Session.class);
              Filter filter = session.enableFilter("tenantFilter");
              filter.setParameter("tenantId", new Long(10));
  
          }
  
  
          Object result = proceedingJoinPoint.proceed();
  
          // Code to disable the hibernate filter goes here.
          log.debug("###########################################################################");
          log.debug("###################### After disabling tenant filter ######################");
          log.debug("###########################################################################");
  
          return result;
  
      }
  
  }
  </code></pre>
  
  <p>The relevant part of service interface and implementation class is </p>
  
  <pre><code>public interface InventoryService {
      Inventory getInventoryById(Long id);
  }
  </code></pre>
  
  <pre><code>@Service
  public class InventoryServiceImpl implements InventoryService {
  
      @Autowired
      private InventoryRepository repo;
  
      @Override
      @Transactional
      @TenantAware
      public Inventory getInventoryById(Long id) {
         LOG.debug("getInventoryById() called  with: id = {}", id);
          final Optional&lt;Inventory&gt; inventoryOp = repo.findById(id);
  
          if (inventoryOp.isPresent()) {
              return inventoryOp.get();
          } else {
              throw new InventoryNotFoundException(String.format(MESSAGE_INVENTORY_NOT_FOUND_FOR_ID, id));
          }
      }
  }
  </code></pre>
  
  <p>The repository interface is</p>
  
  <pre><code>@Repository
  @Transactional(readOnly = true)
  public interface InventoryRepository extends BaseRepository&lt;Inventory, Long&gt; {  
  }
  </code></pre>
  
  <p>The BaseRepository interface extends JpaRepository.</p>
  
  <p>And the aspect configuration class is </p>
  
  <pre><code>@Configuration
  @ComponentScan(basePackages = {"org.foo.bar.advisors"})
  @EnableAspectJAutoProxy(proxyTargetClass = true)
  public class AOPConfig {
  }
  </code></pre>
  
  <p>And finally the relevant MappedSuperClass which is inherited by other classes has the filter defined as</p>
  
  <pre><code>@Getter
  @NoArgsConstructor(access = AccessLevel.PROTECTED)
  @MappedSuperclass
  @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
  @FilterDef(
          name = "tenantFilter",
          parameters = @ParamDef(name = "tenantId", type = "long")
  )
  @Filter(name = "tenantFilter", condition = "tenant_id = :tenantId")
  public abstract class BaseTransactionalEntity extends BaseEntity {
  
      @Column(name = "tenant_id", nullable = false)
      private Long tenantId;
  
  }
  </code></pre>
  
  <p>Here is the cutom annotation class if you need the detail</p>
  
  <pre><code>@Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.METHOD)
  @Inherited
  public @interface TenantAware {
  }
  </code></pre>
  
  <p>I need the hibernate filter to be enabled in session and disabled after the proceeding join point completes the execution. But it is not so. What am I missing?</p>