2014-03-13 1 views
5

Я пытаюсь развернуть сеанс Hibernate из инъецируемого EntityManager, так как мне нужно использовать собственный API-интерфейс Hibernate.Отсутствует транзакционный EntityManager - работает с JPA Api, ошибка с сеансом Hibernate

Когда я пытаюсь использовать критерии я получаю следующее исключение:

Caused by: java.lang.IllegalStateException: No transactional EntityManager available 
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:224) 
at com.sun.proxy.$Proxy28.unwrap(Unknown Source) 
at sk.uniba.ais2.fajr.dao.impl.PouzivatelDAOHibernate.findByLogin(PouzivatelDAOHibernate.java:22) 
at sk.uniba.ais2.fajr.bo.PouzivatelService.findByLogin(PouzivatelService.java:20) 
at sk.uniba.ais2.fajr.mvc.controller.FooController.getFoooFOO(FooController.java:38) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:606) 
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215) 
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) 
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:690) 
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945) 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876) 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) 
... 62 more 

Однако, когда я использую API запросов от самого EntityManager, все работает просто отлично.

Моя конфигурация:

db.xml

<?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:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" 
    default-autowire="byName" xmlns:jpa="http://www.springframework.org/schema/data/jpa" 
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
     http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd 
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 

    <!-- Scans within the base package of the application for @Components to 
     configure as beans --> 
    <bean id="placeholderConfig" 
     class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
     <property name="location" value="classpath:db.properties" /> 
    </bean> 

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 
    destroy-method="close"> 
    <property name="driverClass" value="${db.driver}" /> 
    <property name="jdbcUrl" value="${db.url}" /> 
    <property name="user" value="${db.username}" /> 
    <property name="password" value="${db.password}" /> 
</bean> 

    <bean id="jpaVendorAdapter" 
     class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
     <property name="showSql" value="true" /> 
     <property name="database" value="ORACLE" /> 
    </bean> 

    <bean id="entityManagerFactory" 
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="jpaVendorAdapter" ref="jpaVendorAdapter" /> 
     <property name="packagesToScan" value="sk.uniba.ais2.fajr.entities" /> 
     <property name="jpaPropertyMap"> 
      <map> 
       <entry key="hibernate.default_schema" value="AIS2" /> 
      </map> 
     </property> 

    </bean> 

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="entityManagerFactory" /> 
    </bean> 

    <tx:annotation-driven transaction-manager="transactionManager" 
     proxy-target-class="true" /> 
    <jpa:repositories base-package="sk.uniba.ais2.fajr.dao" /> 
</beans> 

PouzivatelDAOHibernate который не работает:

@Repository 
public class PouzivatelDAOHibernate implements PouzivatelDAO { 

    @PersistenceContext 
    private EntityManager entityManager; 

    @Override 
    public Pouzivatel findByLogin(String login) { 
     Criteria criteria = entityManager.unwrap(Session.class).createCriteria(Pouzivatel.class); 
     return (Pouzivatel) criteria.add(Restrictions.eq("login", login)).uniqueResult(); 
    } 

} 

PouzivatelDAOHibernate, который делает работу:

@Repository 
public class PouzivatelDAOHibernate implements PouzivatelDAO { 

    @PersistenceContext 
    private EntityManager entityManager; 

    @Override 
    public Pouzivatel findByLogin(String login) { 
//  Criteria criteria = entityManager.unwrap(Session.class).createCriteria(Pouzivatel.class); 
//  return (Pouzivatel) criteria.add(Restrictions.eq("login", login)).uniqueResult(); 
     Query query = entityManager.createQuery("select p from Pouzivatel p where login=?"); 
     query.setParameter(1, login); 
     return (Pouzivatel) query.getSingleResult(); 
    } 

} 

EDIT: Я использую Spring Data JPA

ответ

18

Я на самом деле решить эту проблему (решение было довольно тривиально): использовать org.springframework.transaction.annotation.Transactional вместо javax.transaction.Transactional

7

Рассмотрите возможность использования @Transactional над вашими методами DAO. Кажется, что ваша конфигурация верна.

+0

Я также попробовал это, до сих пор ничего EDIT: Но ваш ответ был частью решения, upvote :) –

+0

Неа :) http://stackoverflow.com/questions/1079114/where-do-the-transactional-annotation –

+0

Цель данного конкретного приложения заключалась в том, чтобы загружать только объекты из БД, выполнять некоторую постобработку (объекты карты в некоторые DTO) и публиковать данные через некоторые конечные точки REST. Полностью прочитанный, без бизнес-логики, поэтому я в общем случае пропустил сервисный уровень. –

-1

При добавлении единого определения боб весна контейнер будет выступать в качестве контейнера JPA и впрыснуть в EnitityManager от вашего EntityManagerFactory ,

см https://spring.io/blog/2006/08/07/using-jpa-in-spring-without-referencing-spring

+0

Это, к сожалению, не ответ на этот вопрос - у меня уже была работа PersistenceContext, единственной проблемой была обработка транзакций –