Spring JPA no transaction is in progress

前端 未结 3 2099
轮回少年
轮回少年 2020-12-14 08:23

I am new to Spring and JPA, wasted 5 days and no result with searching internet. I want to save object to SQL SERVER, connection is correct but when I write .flush() I get t

相关标签:
3条回答
  • 2020-12-14 08:55

    You should introduce your entity manager to your transaction manager, so that when you annotate your function with @Transactionalit loads instances from the pool

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="myEmf" />
    </bean>
    <tx:annotation-driven />
    

    HTH!

    0 讨论(0)
  • 2020-12-14 09:12

    You have two Spring contexts:

    1. the main one, configured by jpaContext.xml, where beans from the service and repository packages are scanned, and proxied by a transactional interceptor.

    2. the mvc one, configured by the other xml file (you didn't name it) whose role is to describe the MVC part of the application, i.e. define and configure for example the controller beans, the view resolver, etc. This context is a child of the main one.

    The problem is that you also scan the service and repository packages in this child context. You thus end up with two instances of each service and repository:

    • one in the main context, which is transactional
    • one in the child context, which is not (since the child context doesn't care about transaction management)

    The controller is thus injected with a service coming from the same context as the controller: the not transactional one.

    To confirm that, you could add traces in the constructor of the beans and see how many times they are instantiated.

    And to avoid the problem, there are two solutions:

    • avoid scanning the repository and service packages in the mvc context: this context should only care about mvc-related beans. When Spring injects a service in a controller, it would thus not find the service in the mvc context, and thus look it up, and find it in the main context. The transactional service would thus be injected.
    • use a single context: the one of the servlet, where all the beans in the application would be defined.
    0 讨论(0)
  • 2020-12-14 09:12

    To make the story short, try adding @Transactional at the very beginning of your method. That was an issue in my case.

    0 讨论(0)
提交回复
热议问题