No Session found for current thread przy wywołaniu metody.

0

Witam. Próbuje wyświetlić ma mojej stronie w tabeli listę administratorów z bazy danych, jednak napotkałem na problem. Mianowicie próba wyświetlenia administratorów kończy się błędem:

SEVERE: Servlet.service() for servlet [appServlet] in context with path [/ibank] threw exception [Request processing failed; nested exception is org.hibernate.HibernateException: No Session found for current thread] with root cause org.hibernate.HibernateException: No Session found for current thread

Metodę wywołuję w kontrolerze, jest to metoda o nazwie getAdminList()

@Controller
public class AdminController {

    @Autowired
    private UserService userService;

    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/admin/adminlist", method = RequestMethod.GET)
    public ModelAndView goAdminList() {
        ModelAndView mav = new ModelAndView("admin/adminlist");
        List<User> admins = userService.getAdminList();
        mav.addObject("admins", admins);
        return mav;
    }
} 

Interfejs serwisu:

public interface UserService {

    void createUser(User user);

    void updateUser(User user);

    void deleteUser(int id);

    User getUser(int id);

    @SuppressWarnings("rawtypes")
    List getAdminList();

    User findByUsername(String username);
} 

Implementacja:

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    UserDao userDao;

    @Override
    public void createUser(User user) {
        userDao.createUser(user);
    }

    @Override
    public void updateUser(User user) {
        userDao.updateUser(user);
    }

    @Override
    public void deleteUser(int id) {
        userDao.deleteUser(id);
    }

    @Override
    public User getUser(int id) {
        return userDao.getUser(id);
    }

    @SuppressWarnings("rawtypes")
    @Override
    public List getAdminList() {
        return userDao.getAdminList();
    }

    @Override
    public User findByUsername(String username) {
        return userDao.findByUsername(username);
    }

} 

Dao:

@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private SessionFactory sessionFactory;
    
    @SuppressWarnings("rawtypes")
    @Override
    public List getAdminList() {
        return getCurrentSession()
                .createQuery(
                        "from User u, UserRole ur where u.id = ur.user.id and ur.user = 'ROLE_ADMIN'")
                .list();
    }

    private Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

} 

root-context:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
	<!-- Root Context: defines shared resources visible to all other web components -->

	<tx:annotation-driven transaction-manager="transactionManager" />

	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:XE" />
		<property name="username" value="HR" />
		<property name="password" value="asdfghj" />
	</bean>

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="packagesToScan" value="pl.piotr.ibank.model" />
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.Oracle10gDialect
				</prop>
				<prop key="hibernate.show_sql">
					true
				</prop>
			</props>
		</property>
	</bean>

	<bean id="transactionManager"
		class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>

	<bean id="myAuthenticationSuccessHandler" class="pl.piotr.ibank.security.MyAuthenticationSuccessHandler" />

</beans> 

servlet-context:

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

	<!-- DispatcherServlet Context: defines this servlet's request-processing 
		infrastructure -->
	<context:component-scan base-package="pl.piotr.ibank" />

	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />
	<!-- Handles HTTP GET requests for /resources/** by efficiently serving 
		up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources 
		in the /WEB-INF/views directory -->
	<beans:bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>

</beans:beans>
 

Dlaczego nie ma sesji? Metoda logowania, która również korzysta z sessionFactory.getCurrentSession() nie rzuca takiego błędu.

2

Przerzuć

<tx:annotation-driven transaction-manager="transactionManager" />

do servlet context

0

@olek1 piszesz ten cały projekt w tragicznym stylu. Czemu nie JPA tylko gołe Hibernate? Czemu @Autowire zamiast @Inject? Czemu nie umiesz używać Genericów tylko używasz rawtypes? Po co w ogóle dzieliłeś kontekst na kilka skoro nie umiesz tego poprawnie zrobić bo nie wiesz jaki jest lifecycle komponentów i w jakiej kolejności są inicjalizowane?

0
Shalom napisał(a):

@olek1 piszesz ten cały projekt w tragicznym stylu. Czemu nie JPA tylko gołe Hibernate? Czemu @Autowire zamiast @Inject? Czemu nie umiesz używać Genericów tylko używasz rawtypes? Po co w ogóle dzieliłeś kontekst na kilka skoro nie umiesz tego poprawnie zrobić bo nie wiesz jaki jest lifecycle komponentów i w jakiej kolejności są inicjalizowane?

  1. A co złego w gołym Hibernate? Chodzi o późniejszą przenośność na inną implementację JPA? Z tego co widziałem na necie większość przykładów na necie jest robiona tym sposobem.
  2. @Autowire to Springowy odpowiednik @Inject to przecież na to samo wychodzi. Chodzi o jakąś zgodność ze standardem?
  3. Z generykami nie rozumiem pytania.
  4. Co do tego podziału to Spring przy tworzeniu projektu podzielił na servlet-context i root-context. Ja jeszcze nie bardzo orientuję się w Springu to myślałem, że tak musi zostać i wolałem nie mieszać w tym. Dotąd jeśli chodzi o web miałem styczność z JEE i powiem, że znacznie mniej problemów mi sprawiała niż Spring. Wydaje mi się znacznie mniej skomplikowana.
2
  1. Tak, pewnie tutoriale które maja po 3-4 lata ;] JPA jest bardziej uniwersalne, nie tylko ze względu na podmianę dostawcy JPA ale też dla ciebie. Bo daje ci większe szanse przy szukaniu pracy, ale jak tam sobie chcesz ;)
  2. Tak. Chodzi o to że @Inject jest adnotacją standardu javy a @Autowire nie.
  3. Masz rację, wydaje ci się ;) Zgaduje też że nie piszesz tego w IntelliJ ;]
0
Shalom napisał(a):
  1. Tak, pewnie tutoriale które maja po 3-4 lata ;] JPA jest bardziej uniwersalne, nie tylko ze względu na podmianę dostawcy JPA ale też dla ciebie. Bo daje ci większe szanse przy szukaniu pracy, ale jak tam sobie chcesz ;)
  2. Tak. Chodzi o to że @Inject jest adnotacją standardu javy a @Autowire nie.
  3. Masz rację, wydaje ci się ;) Zgaduje też że nie piszesz tego w IntelliJ ;]
  1. To może spróbuje faktycznie przenieść to na gołe JPA. W takim razie skąd się uczyć jak nie z tutoriali od hindusów i chińczyków?
  2. No niestety w Eclipsie piszę.
3
  1. Nie czytać nic od hindusów, bo to te tutki można na opał brać. W tym miesiącu wychodzi książka http://www.manning.com/walls5/ która jest na czasie(Spring 4).
    Dodatkowo: http://spring.io/guides i dokumentacja w pdfie: http://docs.spring.io/spring/docs/current/spring-framework-reference/pdf/spring-framework-reference.pdf
  2. Ściągnij sobie triala Intellij Idea 14, ogarnij środowisko
0

mam podobny problem jak autor tego watku, mianowicie przy probie uruchomienia strony w przegladarce mam blad ktory mowi:

 
type Exception report

message Request processing failed; nested exception is org.hibernate.HibernateException: No Session found for current thread

description The server encountered an internal error that prevented it from fulfilling this request.

exception 

mysle ze jest to problem z ustawieniami w dispatcher servlecie, wyglada on tak:

 <context:component-scan base-package="com.student.recruitment.app.controller" />

   <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="prefix" value="/WEB-INF/jsp/" />
      <property name="suffix" value=".jsp" />
   </bean>
	
	<bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="classpath:messages"></property>
        <property name="defaultEncoding" value="UTF-8"></property>
    </bean>
    <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
        p:location="/WEB-INF/jdbc.properties"></bean>
    <bean id="dataSource"
        class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"
        p:driverClassName="${jdbc.driverClassName}"
        p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
        p:password="${jdbc.password}"></bean>
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
        
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${jdbc.dialect}</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>
    <bean id="employeeDAO" class="com.student.recruitment.app.dao.EmployeeDaoImpl"></bean>
    <bean id="employeeManager" class="com.student.recruitment.app.service.EmployeeManagerImpl"></bean>

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
	
 

wyczytalem na necie ze kluczowe jest dodanie tego:
<tx:annotation-driven transaction-manager="transactionManager"/>

ale gdy to dodaje dostaje wyjatek przy starcie serwera:

Caused by: org.xml.sax.SAXParseException; lineNumber: 53; columnNumber: 66; cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'tx:annotation-driven'.
 

i nie mam pojecia co zrobic, pomoze ktos?

0

Tutaj masz rozwiązanie: http://stackoverflow.com/questions/6058037/the-matching-wildcard-is-strict-but-no-declaration-can-be-found-for-element-tx

Musisz dopisać do swojego xsi:schemaLocation to co jest w powyższym linku.

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