Błąd: org.hibernate.HibernateException: No Session found for current thread

0

Witam. Piszę prosty program w celach szkoleniowych z wykorzystaniem Springa, Hibernate i Apache Shiro. Niestety próba odczytu z bazy danych kończy się błędem
org.hibernate.HibernateException: No Session found for current thread

Konfiguracja programu wygląda następująco:

web.xml

<!-- Login page -->
    <servlet>
        <servlet-name>SpringLoginDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringLoginDispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>  
    
    <!-- Spring -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/root-context.xml</param-value>
    </context-param>

...

servlet-context.xml

<mvc:annotation-driven />
    
    <context:component-scan base-package="com.bobbuzdom.dzienniczek"/>  
   
    <tx:annotation-driven/>     

    <mvc:resources mapping="/resources/**" location="/resources/" /> 
   
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>

root-context.xml

<context:component-scan base-package="com.bobbuzdom.dzienniczek.core"/>
     
   
      
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://192.168.1.101:3306/dzienniczek"/>
        <property name="username" value="root" />
        <property name="password" value="root"/>
         
    </bean>

    <bean id="sessionFactory"
          class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.bobbuzdom.dzienniczek.core.entity" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="javax.persistence.schema-generation.database.action">none</prop>
                <prop key="hibernate.format_sql">true</prop>     
                <prop key="hibernate.show_sql">true</prop>  
                           
            </props>
        </property>
    </bean>

    <bean id="transactionManager"
          class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref bean="sessionFactory" />
        </property>
    </bean>
    
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <property name="loginUrl" value="/auth/login/"/>
                 
        <property name="filterChainDefinitions">
            <value>
                / = anon
                /resources/** = anon 
                /auth/login/** = anon
                /auth/logout/** = logout
                /admin/admin/** = authc
                /dzienniczek/** = authc
                /** = authc
            </value>
        </property>
    </bean>
    
    <bean id="builtInCacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />
    
    <bean id="credentialsDAO" class="com.bobbuzdom.dzienniczek.core.dao.credentialsdao.CredentialsDAOImpl" />    
    
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"
          depends-on="credentialsDAO">
        <property name="realm" ref="myRealm"/>
        <property name="cacheManager" ref="builtInCacheManager"/>
    </bean>

    <bean id="myRealm" class="com.bobbuzdom.dzienniczek.settings.MyShiroRealm" />     


    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

    <!-- Enable Shiro Annotations for Spring-configured beans.  Only run after -->
    <!-- the lifecycleBeanProcessor has run: -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor"/>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>
@Transactional
public class CredentialsDAOImpl implements CredentialsDAO<Credentials, Integer>
{

    @Autowired
    private SessionFactory sessionFactory;

   
    private Session getSession()
    {
        return sessionFactory.getCurrentSession();
    }
    
    @Override
    public void persist(Credentials entity)
    {
        getSession().persist(entity);
    }

    @Override
    public void update(Credentials entity)
    {
        getSession().update(entity);
    }

    @Override
    public Credentials findById(Integer id)
    {
        return (Credentials) getSession().get(Credentials.class, id);
    }

    @Override
    public void delete(Credentials entity)
    {
        getSession().delete(entity);
    }

    @Override
    public List<Credentials> findAll()
    {
        return getSession().createQuery("from Credentials").list();
    }

    @Override
    public void deleteAll()
    {
        List<Credentials> credentialsList = this.findAll();
        for(Credentials credentials : credentialsList)
        {
            this.delete(credentials);
        }
    }
    
    @Override   
    public Credentials findByLogin(String login)
    {
        String query = "from Credentials c where c.login = :login";
        Credentials c = null;
        try
        {
            Session s = this.getSession();            
            c = (Credentials) s.createQuery(query).setString("login", login);
            
        }
        catch(Exception e)
        {
            System.out.println(e.toString());
        }
 
        return c;
    }
}

MyShiroRealm

@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
    {
        Credentials credentials = null;
        UsernamePasswordToken tk = (UsernamePasswordToken) token;
        try
        {
            credentials = (Credentials) credentialsDAO.findByLogin(tk.getUsername());            
        }
        catch (AuthenticationException ex)
        {
            System.out.println(ex);
            throw new AuthenticationException(ex);
        }

        return new SimpleAuthenticationInfo(credentials.getLogin(), credentials.getPassword(), getName());

    }

Bardzo proszę o pomoc. Siedzę nad tym już parę godzin i nie wiem gdzie znajduje się błąd.

0
lordbobstein napisał(a):
    <bean id="credentialsDAO" class="com.bobbuzdom.dzienniczek.core.dao.credentialsdao.CredentialsDAOImpl" />    
    </bean>
@Transactional
public class CredentialsDAOImpl implements CredentialsDAO<Credentials, Integer>
{
    @Autowired
    private SessionFactory sessionFactory;

Pewności nie mam ale niie powinieneś mu tam factory session wstrzykiwać ?
Ps. w ogóle z bazą się łączy czy na konfigurowaniu się krzaczy? I pokaz log z błędu.

0

Jedyny komunikat to:

 
org.hibernate.HibernateException: No Session found for current thread

wyrzucany tutaj:

@Override
   
    public Credentials findByLogin(String login)
    {
        String query = "from Credentials c where c.login = :login";
        Credentials c = null;
        try
        {
            Session s = this.getSession(); <<--- TU RZUCANY JEST WYJĄTEK
            
            c = (Credentials) s.createQuery(query).setString("login", login);
            
        }
        catch(Exception e)
        {
            System.out.println(e.toString()); <<--- PROFESJONALNA OBSŁUGA WYJĄTKU
        }    
        return c;
    }

Sprawdziłem w debuggerze i SessionFactory jest poprawnie wstrzyknięte.

0

Na oko: transakcje nie działają i stąd problem.

0

@Shalom ma racje. Nie widze tutaj konfiguracji hibernate. Z tego co pamietam to musisz wskazac czy chcesz transakcje lokalne (baujace na threadlocal) czy bierzesz je z kontenera (JTA).

0

Wydaje mi się że problem leży tu raczej w tym kiedy i gdzie tworzy sie transaction manager. Bo generalnie ta linia:
<tx:annotation-driven/>
wygląda tak:
<tx:annotation-driven transaction-manager="txManager"/>
Jeśli transaction managerów byłoby więcej niż 1. Ale zauważ że w kontekście w którym masz tą linię nie ma żadnego managera. Możliwe że to jest problem. Zobacz co się stanie jak podmienisz tą linijkę z tx:annotation-driven albo spróbuj ją przenieść do drugiego kontekstu.
Bo może jest po prostu tak, że to @Transactional nie łapie poprawnie ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1