Spring Web 4.0.1 i Hibernate 4.3.1 - No Session found for current thread

0

Witam, to mój pierwszy projekt z Springa połączonego z Hibernate'm. Walczę z tym wyjątkiem już od jakichś 2 godzin - bezskutecznie.

Poniżej konfiguracja ważnych plików:

applicationContext.xml:

<?xml version='1.0' encoding='UTF-8' ?>
<!-- was: <?xml version="1.0" encoding="UTF-8"?> -->
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xmlns:p="http://www.springframework.org/schema/p"
   xsi:schemaLocation="
   http://www.springframework.org/schema/beans     
   http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
   http://www.springframework.org/schema/context 
   http://www.springframework.org/schema/context/spring-context-4.0.xsd
   http://www.springframework.org/schema/mvc
   http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
   http://www.springframework.org/schema/tx 
   http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

    <context:component-scan base-package="org.server" />
    <mvc:resources mapping="/resources/**" location="/resources/" cache-period="31556926"/>
    <mvc:annotation-driven />
    <tx:annotation-driven transaction-manager="transactionManager" />
    
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="localization/messages"/>
    </bean>
    
    <mvc:interceptors> 
        <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
            <property name="paramName" value="language" />
        </bean>
    </mvc:interceptors>

    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
        <property name="defaultLocale" value="en_US" />
    </bean>
    
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
            </props>
        </property>
        <property name="packagesToScan" value="org.server.model" />
    </bean>
  
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager" 
        p:sessionFactory-ref="sessionFactory">
    </bean>
    
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:databaseConnection.properties</value>
            </list>
        </property>
    </bean>
</beans> 

Hibernate.cfg.xml:

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://192.168.0.100:3306/analysisserver?zeroDateTimeBehavior=convertToNull</property>
    <property name="hibernate.connection.username">login</property>
    <property name="hibernate.connection.password">haslo</property>
    <property name="show_sql">true</property>
  </session-factory>
</hibernate-configuration>

Model User:

 package org.server.model;

import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;

@Entity
@Table(name="users")
public class User implements Serializable 
{
    @Id
    @Column(name="ID")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
    
    @Column(name="E-mail", length=320)
    @NotNull
    private String email;
    
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
    
    @Column(name="Name", length=45)
    @NotNull
    private String name;
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    @Column(name="Password", length=128)
    @NotNull
    private String password;
    
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    
    @Column(name="RegistrationDate", columnDefinition="DATETIME")
    @Temporal(TemporalType.TIMESTAMP)
    private Date registrationDate;
    
    public Date getRegistrationDate() {
        return registrationDate;
    }

    public void setRegistrationDate(Date registrationDate) {
        this.registrationDate = registrationDate;
    }
    
    @Column(name="AccessToken", length=1000)
    @NotNull
    private String accessToken;
    
    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }
    
    @Column(name="AccessTokenSecret", length=1000)
    @NotNull
    private String accessTokenSecret;
    
    public String getAccessTokenSecret() {
        return accessTokenSecret;
    }

    public void setAccessTokenSecret(String accessTokenSecret) {
        this.accessTokenSecret = accessTokenSecret;
    }
    
    @Column(name="ConsumerKey", length=1000)
    @NotNull
    private String consumerKey;
    
    public String getConsumerKey() {
        return consumerKey;
    }

    public void setConsumerKey(String consumerKey) {
        this.consumerKey = consumerKey;
    }
    
    @Column(name="ConsumerKeySecret", length=1000)
    @NotNull
    private String consumerKeySecret;
    
    public String getConsumerKeySecret() {
        return consumerKeySecret;
    }

    public void setConsumerKeySecret(String consumerKeySecret) {
        this.consumerKeySecret = consumerKeySecret;
    }
    
    @Column(name="Activated")
    boolean isActivated = true;
    
    public boolean isIsActivated() {
        return isActivated;
    }

    public void setIsActivated(boolean isActivated) {
        this.isActivated = isActivated;
    }
    
    @Column(name="Premium")
    boolean isPremium;  
    
    public boolean isIsPremium() {
        return isPremium;
    }

    public void setIsPremium(boolean isPremium) {
        this.isPremium = isPremium;
    }
}

Serwisy które odpowiadają za pobieranie informacji:

UsersDAOImpl:

@Service
public class UsersDAOImpl implements UsersDAO
{
    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public void saveUser(User user) 
    {
        sessionFactory.getCurrentSession().save(user);
    }

    @Override
    public User getUserByEmail(String email) 
    {
        Query query = sessionFactory.getCurrentSession().createQuery("from users where E-mail = :mail");
        query.setParameter("mail", email);
        return (User) query.uniqueResult();
    }

    @Override
    public List<User> getAllUsers() 
    {
        return sessionFactory.getCurrentSession().createCriteria(User.class).list();
    }  
} 

UsersManagerImpl:

@Service
public class UsersManagerImpl implements UsersManager
{
    @Autowired
    UsersDAO userDao;
    
    @Override
    @Transactional
    public void addNewUser(User user) 
    {
        userDao.saveUser(user);
    }

    @Override
    @Transactional
    public User getUserByEmail(String mailAddress) 
    {
        return userDao.getUserByEmail(mailAddress);
    }

    @Override
    @Transactional
    public List<User> getAllUsers() 
    {
        return userDao.getAllUsers();
    }
} 

Co dostaję z GlassFisha co może okazać się przydatne przy debugowaniu:

Info:  HHH000206: hibernate.properties not found
Info:   HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
Info:   HHH000422: Disabling contextual LOB creation as connection was null
Info:   HHH000399: Using default transaction strategy (direct JDBC transactions)
Info:   HHH000397: Using ASTQueryTranslatorFactory 

Używam MariaDB 10.01 oraz HeidiSQL i nie mam pojęcia czemu dostaję Access Denied skoro dokładnie tymi samymi danymi na ten sam host - nie ma znaczenia czy "Pececik" czy 192.168.0.100 czy "localhost" mogę się zalogować bez najmniejszego problemu.

Prosiłbym o pomoc.

0

Przepraszam za double post, ale błędu z Access Denied już nie dostaję - lecz to nie rozwiązuje problemu.

0

Popatrz na to: https://github.com/Pharisaeus/SpringScaffoldApplication i zobacz czy ci wystartuje "od kopa" z tą twoja konfiguracją bazy danych.

0

Ruszyło, Hibernate też bo dostaję Exception związany z brakiem danej tabeli w mojej bazie danych.

0

A dodaj w swojej konfiguracji springa <context:annotation-config/>

0

Dalej nic ale po dodaniu @Transactional w metodach UsersDAOImpl zamiast w serwisie - UsersManagerImpl

czyli:

UserManagerImpl:

@Service
public class UsersManagerImpl implements UsersManager
{
    @Autowired
    UsersDAO userDao;
    
    @Override
    public void addNewUser(User user) 
    {
        userDao.saveUser(user);
    }

    @Override
    public User getUserByEmail(String mailAddress) 
    {
        return userDao.getUserByEmail(mailAddress);
    }

    @Override
    public List<User> getAllUsers() 
    {
        return userDao.getAllUsers();
    }
} 

UsersDAOImpl:

@Service
public class UsersDAOImpl implements UsersDAO
{
    @Autowired
    private SessionFactory sessionFactory;

    @Override
    @Transactional
    public void saveUser(User user) 
    {
        sessionFactory.getCurrentSession().save(user);
    }

    @Override  
    @Transactional
    public User getUserByEmail(String email) 
    {
        Query query = sessionFactory.getCurrentSession().createQuery("from users where Email = :mail");
        query.setParameter("mail", email);
        return (User) query.uniqueResult();
    }

    @Override
    @Transactional
    public List<User> getAllUsers() 
    {
        return sessionFactory.getCurrentSession().createCriteria(User.class).list();
    }  
} 

To wtedy działa, tylko w poradniku który czytałem @Transactional było dodawane w wyższej warstwie serwisu, również czytałem że w taki sposób to powinno być wykorzystywane i teraz już nie wiem.

0

"Im wyżej tym lepiej" ;) A pokaż mi jeszcze jak wstrzykujesz te swoje serwisy. Bo jeśli robisz to nie-przez-interfejs, to nie zadziała, bo spring nie będzie w stanie zrobić AOP proxy.

0

Twój post Shalom, wszystko mi wyjaśnił i muszę bardzo przeprosić za wszelkie kłopoty.
Oczywiście błędy to całość po mojej stronie, dopiero jak napisałeś o wstrzykiwaniu to zajrzałem do Controllera, a tam zamiast serwisu wstrzykiwałem DAO zamiast serwisu który opakowywał to DAO @Transaction. Metody nazywało się tak samo i dlatego tego nie zauważyłem.

Jeszcze raz przepraszam i dziękuję za zwrócenie uwagi.

Wszystko już działa.

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