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.