복붙노트

[SPRING] Spring - 현재 스레드에 대해 실제 트랜잭션을 사용할 수있는 EntityManager가 없음 - 'persist'호출을 안정적으로 처리 할 수 ​​없음

SPRING

Spring - 현재 스레드에 대해 실제 트랜잭션을 사용할 수있는 EntityManager가 없음 - 'persist'호출을 안정적으로 처리 할 수 ​​없음

Spring MVC 웹 어플리케이션에서 엔티티 모델을 데이터베이스에 저장하기 위해 "persist"메소드를 호출하려고 할 때이 오류가 발생합니다. 이 오류와 관련된 인터넷의 게시물이나 페이지를 찾을 수 없습니다. EntityManagerFactory bean에 문제가있는 것 같지만 Spring 프로그래밍에 익숙하지 않아 모든 것이 초기화되었고 웹의 다양한 튜토리얼 기사에 따라 초기화 된 것처럼 보입니다.

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>

RegisterController.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";

        }




    }

해결법

  1. ==============================

    1.나는 같은 문제가 있었고 @Transactional과 같은 방식으로 주석을 달았습니다.

    나는 같은 문제가 있었고 @Transactional과 같은 방식으로 주석을 달았습니다.

    업데이트 : 기본적으로 PersistenceContext는 Transaction 유형이므로 스프링 문서를 확인하면 메서드가 트랜잭션이어야합니다 (http://docs.spring.io/spring/docs/current/spring-framework-reference/). html / orm.html) :

  2. ==============================

    2.Spring 데이터 저장소에서 deleteBy 사용자 정의 메서드를 사용하려고 시도하는 동안이 예외가 발생했습니다. 작업이 JUnit 테스트 클래스에서 시도되었습니다.

    Spring 데이터 저장소에서 deleteBy 사용자 정의 메서드를 사용하려고 시도하는 동안이 예외가 발생했습니다. 작업이 JUnit 테스트 클래스에서 시도되었습니다.

    JUnit 클래스 수준에서 @Transactional 주석을 사용할 때 예외가 발생하지 않습니다.

  3. ==============================

    3.이 오류는 내가 사흘 동안 나에게 사로 잡혔다. 내가 직면했던 상황도 같은 오류를 낳았다. 내가 찾을 수있는 모든 조언을 따라, 나는 구성으로 놀았지만 아무 소용이 없었다.

    이 오류는 내가 사흘 동안 나에게 사로 잡혔다. 내가 직면했던 상황도 같은 오류를 낳았다. 내가 찾을 수있는 모든 조언을 따라, 나는 구성으로 놀았지만 아무 소용이 없었다.

    궁극적으로 나는 그것을 발견했다. 차이점은, 내가 수행하고 있던 서비스가 일반적인 병에 담겨 있었고,이 문제는 AspectJ가 서비스 인스턴스화를 동일하게 취급하지 않는다는 것이 밝혀졌다. 실제로 프록시는 메서드 호출 전에 실행되는 모든 일반적인 Spring 매직없이 기본 메서드를 호출하고있었습니다.

    결국 예제에 따라 서비스에 배치 된 @Scope 주석은 문제를 해결했습니다.

    @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();
        }
    
    }
    

    필자가 게시 한 메소드는 삭제 메소드이지만 주석은 모든 지속성 메소드에 동일한 방식으로 영향을 미칩니다.

    이 게시물이 병에서 서비스를로드 할 때 같은 문제로 어려움을 겪어 온 다른 사람에게 도움이되기를 바랍니다.

  4. ==============================

    4.XML-에서 Java- 구성으로 전환했기 때문에 동일한 오류가 발생했습니다.

    XML-에서 Java- 구성으로 전환했기 때문에 동일한 오류가 발생했습니다.

    요점은 Stone Feng이 제안한 것처럼 태그를 마이그레이션하지 않았기 때문입니다.

    그래서 여기에 제안 된대로 @EnableTransactionManagement를 추가했습니다. @Configuration 클래스에서 Spring에서 Annotation-Driven Transactions 설정하기

  5. ==============================

    5.나는 같은 문제를 안고 applicationContext.xml에서 tx : annotation-driven을 추가했다.

    나는 같은 문제를 안고 applicationContext.xml에서 tx : annotation-driven을 추가했다.

  6. ==============================

    6.우리에게는 여러 구성 파일의 동일한 컨텍스트 설정 문제가 발생했습니다. 여러 구성 파일에 다음 내용이 중복되어 있지 않은지 확인하십시오.

    우리에게는 여러 구성 파일의 동일한 컨텍스트 설정 문제가 발생했습니다. 여러 구성 파일에 다음 내용이 중복되어 있지 않은지 확인하십시오.

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

    7.동일한 구성 요소 내의 비 트랜잭션 방식에서 이미 트랜잭션 주석이 달린 메소드에 액세스 할 때도 동일한 오류가 발생했습니다.

    동일한 구성 요소 내의 비 트랜잭션 방식에서 이미 트랜잭션 주석이 달린 메소드에 액세스 할 때도 동일한 오류가 발생했습니다.

    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();
    

    자체 참조 된 컴포넌트에서 executeQuery ()를 호출하여 오류를 수정했습니다.

    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
            }
        }
    
  8. ==============================

    8.모드를 삭제했습니다.

    모드를 삭제했습니다.

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

    이 일을 만들기 위해

  9. ==============================

    9.잘못된 메소드 / actionlevel에서 @Transaction을 사용할 때 동일한 오류 코드가 발생했습니다.

    잘못된 메소드 / actionlevel에서 @Transaction을 사용할 때 동일한 오류 코드가 발생했습니다.

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

    물론 @Transactional 메서드를 methodWithANumberOfDatabaseActions () 메서드 바로 위에 배치해야했습니다.

    그것은 내 경우에 오류 메시지를 해결했습니다.

  10. ==============================

    10.며칠 동안이 문제가 있었고 온라인 어디서나 온라인에서 도움을 구하지 못했습니다. 다른 사람들에게 도움이 될 경우를 대비하여 여기에 답변을 게시하고 있습니다.

    며칠 동안이 문제가 있었고 온라인 어디서나 온라인에서 도움을 구하지 못했습니다. 다른 사람들에게 도움이 될 경우를 대비하여 여기에 답변을 게시하고 있습니다.

    필자의 경우 원격 서비스를 통해 호출되는 마이크로 서비스에 대한 작업을 수행하고 있으며 서비스 수준의 @Transactional 주석은 원격 프록시에 의해 선택되지 않았습니다.

    서비스와 DAO 레이어 사이에 델리게이트 클래스를 추가하고 위임 메소드를 트랜잭션으로 표시하면 나를 위해이 문제가 해결되었습니다.

  11. ==============================

    11.boardRepo.deleteByBoardId (id);

    boardRepo.deleteByBoardId (id);

    같은 문제에 직면했다. GOT javax.persistence.TransactionRequiredException : 현재 스레드에 대해 실제 트랜잭션을 사용할 수있는 EntityManager가 없습니다.

    컨트롤러 / 서비스 위에 @Transactional 주석을 추가하여이 문제를 해결했습니다.

  12. from https://stackoverflow.com/questions/32269192/spring-no-entitymanager-with-actual-transaction-available-for-current-thread by cc-by-sa and MIT license