[ACCEPTED]-How to enable hibernate filter for sessionFactory.getCurrentSession()?-hibernate-filters

Accepted answer
Score: 19

The solution you have is pretty simple, but 56 I'm guessing what you are trying for is 55 to make it so that you don't have to provide 54 a "getSession" implementation 53 in each of your DAOs. Ultimately your method 52 of implementing this is going to depend 51 on how flexible you want to be with this 50 filter. Here's two ways I might solve this.

The 49 simplest way would be to simply make your 48 UserDAOImpl extend a new base class that 47 contains the "getSession" logic 46 in it. This method would allow you to reduce 45 code in that you would have this filter 44 logic applied in most cases, but then you 43 could override the filtering when you need 42 to.

You could create something like this:

public class BaseDAO
{

    // ... possibly some other methods and variables

    @Autowired(required = true)
    private SessionFactory sessionFactory;

    protected Session getSession()
    {
        //Your session filter logic above
    }
}

Now 41 you could just have your UserDAOImpl subclass 40 this and get a session when it needs to 39 do something. This is a very simple way 38 to do what you are looking for, but it isn't 37 foolproof. If you are writing a framework 36 for others to use, then what would stop 35 them from simply getting their own reference 34 to your SessionFactory by having Spring 33 inject it and then they could get an unfiltered 32 Session? You might want this in certain 31 circumstances for administrative processes 30 that can act on all data, but the next way 29 I'll describe should prevent this from happening.

This 28 second way to solve the problem involves 27 using AOP to wrap the getSession method 26 of SessionFactory with your logic to apply 25 the filter before the session is returned. This 24 method means that even if someone gets a 23 reference to your SessionFactory themselves, they 22 will still have this filtering logic applied.

First, if 21 you aren't familiar with AOP in spring have 20 a look at the reference http://static.springsource.org/spring/docs/current/spring-framework-reference/html/aop.html. I'm going to 19 use the schema based method to apply advice 18 to Hibernate, because we don't want to modify 17 the source of Hibernate. ;) You can find 16 the specifics of this method at http://static.springsource.org/spring/docs/current/spring-framework-reference/html/aop.html#aop-schema.

First, make 15 sure you have the following schema and aop:config 14 section in your application context XML 13 for spring:

<?xml version="1.0" encoding="UTF-8"?>
<beans ...
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
        ...
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    ...

<aop:config>
    <aop:aspect id="forceFilter" ref="sessionFilterAdvice">
        <aop:pointcut id="hibernateSessionFactoryGetSession"
            expression="execution(* org.hibernate.SessionFactory.openSession(..))" />
        <aop:after-returning method="setupFilter"
            pointcut-ref="hibernateSessionFactoryGetSession" returning="session" />
    </aop:aspect>
</aop:config>

    ...
</beans>

Next, you need to add a bean 12 to your project to implement the sessionFilterAdvice 11 bean we reference above with the aop:aspect 10 tag. Create the following class:

package net.grogscave.example;

import org.hibernate.Filter;
import org.hibernate.Session;
import org.springframework.stereotype.Service;

@Service
public class SessionFilterAdvice
{
    public void setupFilter(Session session)
    {
        Session session = sessionFactory.getCurrentSession();
        Filter filter = session.enableFilter("restrictToCurrentCompany");
        filter.setParameter("currentCompanyNumber", UserUtils.getCurrentCompany());
    }
}

The final 9 thing to make sure of is that your project 8 includes the spring-aop jar and the aspectjweaver 7 jar. I don't know if you use dependency 6 management or not, but you somehow need 5 to get those jars into your project classpath.

You 4 should now be able to recompile your project, and 3 now any calls to any of the openSession 2 methods on classes that implement SessionFactory 1 will add your filter to them.

Score: 1

Hibernate hbm file: Declare filter in your hbm file. Here 3 filterByFacilityIDs is a filter and facilityIDsParam 2 is a List< String > type parameter.

<hibernate-mapping package="com.ABC.dvo">
 <class name="ItemMasterDVO" table="Item_Master">
  ....
<set name="inventoryTaxesSet" inverse="true" cascade="all">
<key column="item_ID" />
<one-to-many class="InventoryTaxesDVO" />
    <filter name="filterByFacilityIDs" condition="Facility_ID in(:facilityIDsParam)"/>  
</set>
</class>
<filter-def name="filterByFacilityIDs">
 <filter-param name="facilityIDsParam" type="string"/>
</filter-def>
</hibernate-mapping>

** Java 1 class **

public List<ItemMasterDVO> getItemMaster(String[] itemIDs, String[] facilityIDs){
    Session session = getSessionFactory().getCurrentSession();
    Criteria criteria = session.createCriteria(ItemMasterDVO.class)
        .add(Restrictions.in("itemNumber", itemIDs))
        .setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
    if(facilityIDs!=null && facilityIDs.length>0){          
        org.hibernate.Filter filter = session.enableFilter("filterByFacilityIDs");
        filter.setParameterList("facilityIDsParam", facilityIDs);
    }   
    criteria.addOrder(Order.asc("itemNumber"));
    List<ItemMasterDVO> result = criteria.list(); 
    return result;
    }

More Related questions