1

I am new to Spring and JPA I am having an issue with a TransactionRequiredException. I tried the tips located here, here and here (such as annotating with @Transactional, starting transactions manually etc.)

My code is as follows:

Goal.java

@Entity
@Table(name = "goals")
public class Goal
{
    @Id
    @GeneratedValue
    @Column(name = "GOAL_ID")
    private Long id;

    @Range(min = 1, max = 120)
    @Column(name = "MINUTES")
    private int minutes;

    public int getMinutes()
    {
        return minutes;
    }

    public void setMinutes(int minutes)
    {
        this.minutes = minutes;
    }
    public Long getId()
    {
        return id;
    }

    public void setId(Long id)
    {
        this.id = id;
    }
}

GoalRepositoryImpl.java

@Repository("goalRepository")
@Transactional
public class GoalRepositoryImpl implements IGoalRepository
{
    @PersistenceContext
    private EntityManager em;

    public Goal save(Goal goal)
    {
        em.persist(goal);
        return goal;
    }
}

GoalServiceImpl.java

@Service("goalService")
public class GoalServiceImpl implements IGoalService
{
    @Autowired
    private IGoalRepository goalRepository;

    @Transactional
    public Goal save(Goal goal)
    {
        return goalRepository.save(goal);
    }
}

GoalController

@Controller
@SessionAttributes("goal")
public class GoalController
{
    @Autowired
    private IGoalService goalService;

    @RequestMapping(value = "/addGoal", method = RequestMethod.POST)
    public String updateGoal(@Valid @ModelAttribute("goal") Goal goal, BindingResult result){

        if (result.hasErrors()){
            return "addGoal";
        }else{
            goalService.save(goal);
        }
        return "redirect:addMinutes.html";
    }
}

jpaContext.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:context="http://www.springframework.org/schema/context"
       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/context http://www.springframework.org/schema/context/spring-context.xsd
   http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

<context:annotation-config/>

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="punit" />
    <property name="dataSource" ref="datasource"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        </bean>
    </property>
    <property name="jpaPropertyMap">
        <map>
            <entry key="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
            <entry key="hibernate.hbm2ddl.auto" value="create"/>
            <entry key="hibernate.format_sql" value="true"/>
        </map>
    </property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/fitness_tracker?autoReconnect=true"/>
    <property name="username" value="root" />
    <property name="password" value="root" />
</bean>

Tomcat Log

SEVERE: Servlet.service() for servlet [fitTrackerServlet] in context with     path [] threw exception [Request processing failed; nested exception is javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call] with root cause
javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:282)
    at com.sun.proxy.$Proxy41.persist(Unknown Source)
    at ie.wit.repository.GoalRepositoryImpl.save(GoalRepositoryImpl.java:22)
    at ie.wit.service.GoalServiceImpl.save(GoalServiceImpl.java:25)
    at ie.wit.controller.GoalController.updateGoal(GoalController.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:442)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1082)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:623)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2517)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2506)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Community
  • 1
  • 1
JoeWemyss
  • 607
  • 1
  • 10
  • 28
  • Try removing the `@Transactional` from the repository and see if that makes a difference. You really want transactional boundaries to exist at the service level and not the repository level since you may want multiple repository interacts for a given unit of work within a single transaction. – Naros Jul 10 '16 at 20:46
  • I have tried that. Still no luck. I also added a `` to my jpaContext, as I thought that maybe that wasn't getting picked up from my servlet-config. That also didn't work. – JoeWemyss Jul 10 '16 at 20:53
  • You might be dealing with the same issue encountered [here](http://stackoverflow.com/questions/33781945/no-entitymanager-with-actual-transaction-available-for-current-thread-cannot-r). – Rae Burawes Jul 11 '16 at 03:47
  • maybe silly question but which Transactional annotation are you using? the JPA one or the Spring one? – Apostolos Jul 11 '16 at 06:13
  • That could be it actually, that's one approach that I haven't checked. I'm not in frond of my dev machine at the minute. But I'll investigate when I am. – JoeWemyss Jul 11 '16 at 08:11
  • OK, if this is the case, please let me know so as to post it as an answer to accept it :) thnx – Apostolos Jul 11 '16 at 09:28
  • No, I was using the correct annotation. I made a temporary fix, I added the `@EnableTransactionManagement`annotation to the Service Tier class. Is it possible to enable this in the xml config file? All the documentation explains how to use it with java config but not xml. I guess I could just add the annotation to every class that initiates a transaction, but I would prefer to just specify it once in my config file. – JoeWemyss Jul 11 '16 at 17:25
  • `` should take care of the XML integration for `@Transactional`. – Naros Jul 12 '16 at 12:08
  • It didn't seem to. Its working now, with the `@EnableTransactionManagement` annotation on all classes that initiate transactions – JoeWemyss Jul 12 '16 at 20:01
  • If you have to add `@EnableTransactionManagement` across your transactional classes, this is a sure sign of some bad setup. – Naros Jul 12 '16 at 23:46

1 Answers1

1

There are things i cannot see from your project, so i cannot be sure

  1. include spring.tx in your pom or add the library whichever way you are doing it
  2. @Configuration @EnableTransactionManagement

without these two steps you cannot start or commit a transaction.

Comfort Chauke
  • 126
  • 1
  • 9