it-swarm.dev

Primavera: no hay.

Recibo este error al intentar invocar el método "persistir" para guardar el modelo de entidad en la base de datos en mi aplicación web Spring MVC. Realmente no puedo encontrar ninguna publicación o página en Internet que pueda relacionarse con este error en particular. Parece que algo está mal con el bean EntityManagerFactory, pero soy bastante nuevo en la programación de Spring, así que para mí parece que todo está bien inicializado y de acuerdo con varios artículos tutoriales en la web.

dispatcher-servlet.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:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
 http://www.springframework.org/schema/mvc 
 http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
 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/jdbc
  http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.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/data/repository
  http://www.springframework.org/schema/data/repository/spring-repository-1.5.xsd
  http://www.springframework.org/schema/jee
  http://www.springframework.org/schema/jee/spring-jee-3.2.xsd">

    <context:component-scan base-package="wymysl.Controllers" />
    <jpa:repositories base-package="wymysl.repositories"/> 
    <context:component-scan base-package="wymysl.beans" /> 
    <context:component-scan base-package="wymysl.Validators" /> 
    <bean
     class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
     <bean class="org.springframework.orm.hibernate4.HibernateExceptionTranslator"/>

     <bean id="passwordValidator" class="wymysl.Validators.PasswordValidator"></bean>

     <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="system" />
        <property name="password" value="polskabieda1" />
    </bean>

 <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceXmlLocation" value="classpath:./META-INF/persistence.xml" />
    <property name="dataSource" ref="dataSource" />

    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="databasePlatform" value="org.hibernate.dialect.H2Dialect" />
            <property name="showSql" value="true" />
            <property name="generateDdl" value="false" />
        </bean>
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.max_fetch_depth">3</prop>
            <prop key="hibernate.jdbc.fetch_size">50</prop>
            <prop key="hibernate.jdbc.batch_size">10</prop>
        </props>
    </property>
</bean>

    <mvc:annotation-driven />

    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="classpath:messages" />
</bean>

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


    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
        <value>/WEB-INF/jsp/</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>

    <mvc:resources mapping="/resources/**" location="/resources/" />
    <mvc:resources mapping="/resources/*" location="/resources/css/"  
    cache-period="31556926"/>



</beans>

RegistrarseController.Java

@Controller
public class RegisterController {

    @PersistenceContext
    EntityManager entityManager;

    @Autowired
    PasswordValidator passwordValidator;

    @InitBinder
    private void initBinder(WebDataBinder binder) {
        binder.setValidator(passwordValidator);
    }

    @RequestMapping(value = "/addUser", method = RequestMethod.GET)
    public String register(Person person) {


        return "register";

    }

    @RequestMapping(value = "/addUser", method = RequestMethod.POST)
    public String register(@ModelAttribute("person") @Valid @Validated Person person, BindingResult result) {
        if(result.hasErrors()) {
            return "register";
        } else {
            entityManager.persist(person);
            return "index";

        }




    }
87
Michał Bil

Tuve el mismo problema y anoté el método como @Transactional y funcionó.

ACTUALIZACIÓN: verificando la documentación de primavera que parece, por defecto, PersistenceContext es de tipo Transacción, por lo que el método debe ser transaccional ( http://docs.spring.io/spring/docs/current/spring-framework- referencia/html/orm.html ):

La anotación @PersistenceContext tiene un tipo de atributo opcional, que por defecto es PersistenceContextType.TRANSACTION. Este valor predeterminado es lo que necesita para recibir un proxy EntityManager compartido. La alternativa, PersistenceContextType.EXTENDED, es un asunto completamente diferente: esto da como resultado un llamado EntityManager extendido, que no es seguro para subprocesos y, por lo tanto, no se debe utilizar en un componente al que se accede simultáneamente, como un bean singleton administrado por Spring. Se supone que los EntityManagers extendidos solo se deben usar en componentes con estado que, por ejemplo, residen en una sesión, con el ciclo de vida del EntityManager no vinculado a una transacción actual, sino que está completamente a la altura de la aplicación.

174
mlg

Obtuve esta excepción al intentar utilizar un método personalizado deleteBy en el repositorio de datos de Spring. La operación se intentó desde una clase de prueba JUnit.

La excepción no se produce al usar la anotación @Transactional en el nivel de clase JUnit.

54
Kishore Guruswamy

Este error me tuvo atrapado durante tres días, la situación que enfrenté produjo el mismo error. Siguiendo todos los consejos que pude encontrar, jugué con la configuración pero sin éxito.

Eventualmente lo encontré, la diferencia, el Servicio que estaba ejecutando estaba contenido en un contenedor común, el problema resultó ser que AspectJ no trataba a la instanciación del Servicio por igual. En efecto, el proxy simplemente estaba llamando al método subyacente sin que se ejecutara toda la magia Spring normal antes de la llamada al método.

Al final, la anotación de @Scope colocada en el servicio según el ejemplo resolvió el problema:

@Service
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
@Transactional
public class CoreServiceImpl implements CoreService {
    @PersistenceContext
    protected EntityManager entityManager;

    @Override
    public final <T extends AbstractEntity> int deleteAll(Class<T> clazz) {
        CriteriaDelete<T> criteriaDelete = entityManager.getCriteriaBuilder().createCriteriaDelete(clazz);
        criteriaDelete.from(clazz);
        return entityManager.createQuery(criteriaDelete).executeUpdate();
    }

}

El método que he publicado es un método de eliminación, pero las anotaciones afectan a todos los métodos de persistencia de la misma manera.

Espero que esta publicación ayude a otra persona que haya tenido problemas con el mismo problema al cargar un servicio de un contenedor.

15
Chris March

Tuve el mismo error porque cambié de configuración XML a Java.

El punto era que no migré la etiqueta <tx:annotation-driven/>, como sugirió Stone Feng.

Así que acabo de agregar @EnableTransactionManagement como se sugiere aquí Configuración de transacciones guiadas por anotación en Spring en @Configuration Class , y ahora funciona

7
Sergej Werfel

Tuve el mismo problema y agregué tx:annotation-driven en applicationContext.xml y funcionó.

4
Stone Feng

Tuve el mismo error al acceder a un método ya anotado transaccional desde un método no transaccional dentro del mismo componente:

Before:
    @Component
    public class MarketObserver {
        @PersistenceContext(unitName = "maindb")
        private EntityManager em;

        @Transactional(value = "txMain", propagation = Propagation.REQUIRES_NEW)
        public void executeQuery() {
          em.persist(....);
        }


        @Async
        public void startObserving() {
          executeQuery(); //<-- Wrong
        }
    }

    //In another bean:
     marketObserver.startObserving();

Solucioné el error llamando a executeQuery () en el componente que hace referencia a sí mismo:

Fixed version:
    @Component
    public class MarketObserver {
        @PersistenceContext(unitName = "maindb")
        private EntityManager em;

        @Autowired
        private GenericApplicationContext context;

        @Transactional(value = "txMain", propagation = Propagation.REQUIRES_NEW)
        public void executeQuery() {
          em.persist(....);
        }


        @Async
        public void startObserving() {
          context.getBean(MarketObserver.class).executeQuery(); //<-- Works
        }
    }
1
YDZOGODOQ

Para nosotros, el problema se redujo a la misma configuración de contexto en múltiples archivos de configuración. Comprueba que no hayas duplicado lo siguiente en varios archivos de configuración.

<context:property-placeholder location="classpath*:/module.properties"/>
<context:component-scan base-package="...." />
1
Nick West

Tuve el mismo código de error cuando usé @Transaction en un método/nivel de acción incorrecto.

methodWithANumberOfDatabaseActions() { 
   methodA( ...)
   methodA( ...)
}

@Transactional
void methodA( ...) {
  ... ERROR message
}

Tenía que colocar el @Transactional justo por encima del método methodWithANumberOfDatabaseActions(), por supuesto.

Eso solucionó el mensaje de error en mi caso.

0
Jandroid1

Tuve este problema durante días y nada de lo que encontré en ningún lugar en línea me ayudó, estoy publicando mi respuesta aquí en caso de que ayude a alguien más.

En mi caso, estaba trabajando en un microservicio al que se llamaba mediante comunicación remota, y el proxy remoto no recogía mi anotación @Transactional en el nivel de servicio.

Agregar una clase de delegado entre el servicio y las capas dao y marcar el método de delegado como transaccional lo solucionó para mí.

0
fleeblewidget

Quité el modo de

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

para hacer este trabajo

0
ropo

boardRepo.deleteByBoardId (id);

Ante el mismo problema. GOT javax.persistence.TransactionRequiredException: No hay EntityManager con transacción real disponible para el hilo actual

Lo resolví agregando @Transactional anotación sobre el controlador/servicio.

0
Vikram S