Задаване и получаване на обвързан със сесия атрибут през пролетта

Проследих урок за динамично маршрутизиране на източници на данни урок през пролетта . За това трябва да разширя AbstractRoutingDataSource, за да кажа на пролетта кой източник на данни да получа, така че правя:

public class CustomRouter extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return CustomerContextHolder.getCustomerType();
    }
}

Всичко върви добре, докато не намеря класа, отговорен за запазването на стойността на customerType (трябва да е същото по време на цялата сесия):

    public class CustomerContextHolder {

        private static final ThreadLocal<Integer> contextHolder = new ThreadLocal<Integer>(); 

        public static void setCustomerType(Integer customerType) {
            contextHolder.set(customerType);
        } 
        public static Integer getCustomerType() {
            return (Integer) contextHolder.get();
        }
        public static void clearCustomerType() {
            contextHolder.remove();
        }
    }

Това създава обвързана с нишка променлива customerType, но имам уеб приложение с spring и JSF, не мисля с нишки, а със сесии. Затова го зададох в страницата за вход с нишка A (Преглед), но след това нишка B (Hibernate) изисква стойността, за да знае какъв източник на данни да използва, наистина е null , защото има нова стойност за тази нишка.

Има ли някакъв начин да го направите ограничено до сесия вместо ограничено до нишка?

Неща, които съм пробвал досега:

  • Инжектирайте CustomRouter в изгледа, за да го зададете в сесията: Не работи, причинява цикъл в зависимостите
  • Заменете ThreadLocal с цяло число: Не работи, стойността винаги се задава от последния влязъл потребител

person Eugenio Cuevas    schedule 02.10.2012    source източник
comment
защо хибернацията се изпълнява в друга нишка?   -  person ElderMael    schedule 02.10.2012
comment
Не трябва ли да е така? Когато отстранявам грешки в методите на DAO, виждам, че всеки път има различна нишка, която има достъп до метода. това грешно ли е   -  person Eugenio Cuevas    schedule 02.10.2012
comment
Доколкото знам контейнерите на сървлети използват нишка за заявка, това означава, че когато се направи HTTP заявка, се създава нишка или се извлича от пул, за да я обслужва и само една нишка. Така че различна нишка, която има достъп до метода, е ОК само ако тази нишка обслужва различна заявка.   -  person ElderMael    schedule 02.10.2012
comment
Ето защо той има различни стойности, защото за нова нишка ще бъде създаден нов ThreadLocal предполагам. Така че трябва по някакъв начин да го съхраня в сесията, която е постоянна между заявките   -  person Eugenio Cuevas    schedule 03.10.2012
comment
ThreadLocals не се създават, когато се изпълнява нова нишка. Вместо това той съхранява нова стойност, слаба препратка към нишката.   -  person ElderMael    schedule 03.10.2012


Отговори (1)


FacesContext.getCurrentInstance() работи ли? Ако е така, можете да опитате с това:

public class CustomerContextHolder { 

    private static HttpSession getCurrentSession(){
             HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance()
                 .getExternalContext().getRequest();

             return request.getSession();
    }

    public static void setCustomerType(Integer customerType) {

       CustomerContextHolder.getCurrentSession().setAttribute("userType", customerType);

    }

    public static Integer getCustomerType() {

        return (Integer) CustomerContextHolder.getCurrentSession().getAttribute("userType");
    }

    public static void clearCustomerType() {
        contextHolder.remove(); // You may want to remove the attribute in session, dunno
    }
}
person ElderMael    schedule 02.10.2012