0

The final goal that I want to achieve is to use some information from the request headers to use on a Hibernate filter.

The webapp is a fairly neat Spring boot webapp using Jpa Repositories.

I've configured a filter definition in the model entity and I want to have it activated on the webapp. I use a request handler:

The Entity:

@Entity
@Getter
@Setter
@Table(name = "personas")
@FilterDef(name = "filtro_personas", parameters = @ParamDef(name = "idparam", type = "int"))
public class Persona implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Filter(name  = "filtro_personas", condition = ":idparam = id")
    private Integer id;
    private String nombre;
    @OneToMany(mappedBy ="persona")
    private List<Wallet> cuentas;

}

The request handler:

public class LangHeaderInterceptor implements HandlerInterceptor {

    private EntityManager entityManager;

    public LangHeaderInterceptor( EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
        
        if (entityManager != null ) {
            // Sample of use of the filter.at this point the HttpServletRequest and entity manager are filled. 
            Session s = entityManager.unwrap(Session.class);
            s.enableFilter("filtro_personas").setParameter("idparam", 1).;
        }
        return true;
    }
}

The request handler configuration:

@Configuration
public class WebConfigurer implements WebMvcConfigurer {

    @Autowired
    private EntityManager entityManager;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        WebMvcConfigurer.super.addInterceptors(registry);
        //System.out.println("TRACING MESSAGE: CUSTOM INTERCEPTOR ADDED");
        registry.addInterceptor(new LangHeaderInterceptor(entityManager));
    }
}
Antonio E.
  • 359
  • 1
  • 9
  • 27
  • I'm open to discussion about if this is the aproach on where to set the filter activation. I've read about AspectJ for an AOP implementation of this intent. – Antonio E. Jan 29 '22 at 21:12
  • 1
    Researching on the matter: https://dzone.com/articles/how-does-spring-transactional I see that every time @Transactional is put in use a new entityManager may be created so maybe I'm trying to modify an entityManager or a session that won't be in use. – Antonio E. Jan 30 '22 at 12:53
  • Insight on @Transactional behaviour and insides: https://www.marcobehler.com/guides/spring-transaction-management-transactional-in-depth – Antonio E. Jan 30 '22 at 15:25
  • See https://stackoverflow.com/a/76210504/98632 for a possible solution – mtpettyp May 09 '23 at 14:46

1 Answers1

0

Hey friend you can't do this in the way you're trying without mixing concerns. The InterceptorRegistry usage that you try is an odd place to try this (you are not likely to start a transaction before going inside the execution of a controller's methods).

The use that Springboot makes of Hibernate and Jpa's interface makes the actual session on your data access only trully available on the context of an @Transactional annotation.

You should do an AOP approach to your intent so you catch the transaction/session.

Some links on the matter:

Antonio E.
  • 359
  • 1
  • 9
  • 27