Spring-현재 스레드에 사용할 수있는 실제 트랜잭션이있는 EntityManager가 없습니다. '지속성'호출을 안정적으로 처리 할 수 없습니다.
Spring MVC 웹 애플리케이션의 데이터베이스에 엔티티 모델을 저장하기 위해 "persist"메소드를 호출하려고 할 때이 오류가 발생합니다. 이 특정 오류와 관련된 인터넷 게시물이나 페이지를 실제로 찾을 수 없습니다. EntityManagerFactory 빈에 문제가있는 것 같지만 저는 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";
}
}
나는 같은 문제가 있었고 방법에 주석을 달았고 @Transactional
작동했습니다.
UPDATE: checking the spring documentation it looks like by default the PersistenceContext is of type Transaction, so that's why the method has to be transactional (http://docs.spring.io/spring/docs/current/spring-framework-reference/html/orm.html):
The @PersistenceContext annotation has an optional attribute type, which defaults to PersistenceContextType.TRANSACTION. This default is what you need to receive a shared EntityManager proxy. The alternative, PersistenceContextType.EXTENDED, is a completely different affair: This results in a so-called extended EntityManager, which is not thread-safe and hence must not be used in a concurrently accessed component such as a Spring-managed singleton bean. Extended EntityManagers are only supposed to be used in stateful components that, for example, reside in a session, with the lifecycle of the EntityManager not tied to a current transaction but rather being completely up to the application.
I got this exception while attempting to use a deleteBy custom method in the spring data repository. The operation was attempted from a JUnit test class.
The exception does not occur upon using the @Transactional
annotation at the JUnit class level.
This error had me foxed for three days, the situation I faced produced the same error. Following all the advice I could find, I played with the configuration but to no avail.
Eventually I found it, the difference, the Service I was executing was contained in a common jar, the issue turned out to be AspectJ not treating the Service instantiation the same. In effect the proxy was simply calling the underlying method without all the normal Spring magic being executed before the method call.
In the end the @Scope annotation placed on the service as per the example solved the issue:
@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();
}
}
The method I have posted is a delete method but the annotations affect all persistence methods in the same way.
I hope this post helps someone else who has struggled with the same issue when loading a service from a jar
I had the same error because I switched from XML- to java-configuration.
The point was, I didn't migrate <tx:annotation-driven/>
tag, as Stone Feng suggested.
So I just added @EnableTransactionManagement
as suggested here Setting Up Annotation Driven Transactions in Spring in @Configuration Class, and it works now
I had the same problem and I added tx:annotation-driven
in applicationContext.xml
and it worked.
boardRepo.deleteByBoardId(id);
Faced the same issue. GOT javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread
I resolved it by adding @Transactional annotation above the controller/service.
For us, the problem came down to same context settings in multiple configuration files. Check you've not duplicated the following in multiple config files.
<context:property-placeholder location="classpath*:/module.properties"/>
<context:component-scan base-package="...." />
I had the same error when accessing an already transactional-annotated method from a non-transactional method within the same component:
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();
I fixed the error by calling the executeQuery() on the self-referenced component:
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
}
}
I had the same error code when I used @Transaction
on a wrong method/actionlevel.
methodWithANumberOfDatabaseActions() {
methodA( ...)
methodA( ...)
}
@Transactional
void methodA( ...) {
... ERROR message
}
I had to place the @Transactional
just above the method methodWithANumberOfDatabaseActions()
, of course.
That solved the error message in my case.
I removed the mode from
<tx:annotation-driven mode="aspectj"
transaction-manager="transactionManager" />
to make this work
I had this issue for days and nothing I found anywhere online helped me, I'm posting my answer here in case it helps anyone else.
In my case, I was working on a microservice being called through remoting, and my @Transactional annotation at the service level was not being picked up by the remote proxy.
Adding a delegate class between the service and dao layers and marking the delegate method as transactional fixed this for me.
This helped us, maybe it can help others in the future. @Transaction
was not working for us, but this did:
@ConditionalOnMissingClass("org.springframework.orm.jpa.JpaTransactionManager")
'program story' 카테고리의 다른 글
nServiceBus vs Mass Transit vs Rhino Service Bus vs 기타? (0) | 2020.08.15 |
---|---|
MS SQL Server 2008 용 포트를 찾는 방법은 무엇입니까? (0) | 2020.08.14 |
중복 된 코드는 단위 테스트에서 더 견딜 수 있습니까? (0) | 2020.08.14 |
JavaScript를 사용하여 브라우저 언어를 얻는 방법 (0) | 2020.08.14 |
벡터 드로어 블에서 비트 맵 가져 오기 (0) | 2020.08.14 |