Announcement Announcement Module
Collapse
No announcement yet.
EntityManager + @Transactional Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • EntityManager + @Transactional

    I want to use JPA in my Spring 3.1 project but i have a problem with service layer.
    Code:
    @Service
    @Repository
    @Transactional
    public class VideoService  {
    
    	@PersistenceContext
    	EntityManager entityManager;
    	
    	public void save(Video video) {
    		
    		Video video1 = new Video();
    		
    		entityManager.persist(video1);
    
    	}
    Code:
    <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
        <persistence-unit name="video_pu" transaction-type="RESOURCE_LOCAL" >
        	<provider>org.hibernate.ejb.HibernatePersistence</provider>
        	
        	<properties>
        		<property name="hibernate.hbm2ddl.auto" value="create-drop" />
        		<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
        	</properties>
        	
        </persistence-unit>
    </persistence>
    Code:
    	<bean id="dataSource"
    		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
    		<property name="url" value="jdbc:mysql://localhost/video" />
    		<property name="username" value="root" />
    		<property name="password" value="root" />
    	</bean>		
    	
    	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
          <property name="persistenceUnitName" value="video_pu"/>
          <property name="dataSource" ref="dataSource" />      
          <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
               <property name="showSql" value="true" />
               <property name="generateDdl" value="true" />
               <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
            </bean>
         </property>
         
        </bean>
    
    
    
    	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
           <property name="entityManagerFactory" ref="entityManagerFactory"/>
        </bean>
        
        <!-- enable the configuration of transactional behavior based on annotations -->
      	<tx:annotation-driven transaction-manager="transactionManager"/>
        
        
    	<!-- post-processors for all standard config annotations -->
        <context:annotation-config/>
    The transaction in service method save(Video video) is never started so also never commited. Where is the error? When I use EntityManagerFactory it works perfectly, but I don't want to explicitly begin and commit transaction. I want to use it with @Transactional annotation.

  • #2
    Why is your bean both a @Service and @Repository?! It should be either one not both, also where is your bean defined? I see it nowhere nor do I see component scanning configured.

    Also explain a bit more about the setup (where do you use it web application? Scanning both in contextloaderlistener and dispatcherservlet).

    Last tip use the search as questions regarding non working transactions have been answered numerous times before.

    Comment


    • #3
      Originally posted by Marten Deinum View Post
      Why is your bean both a @Service and @Repository?! It should be either one not both, also where is your bean defined? I see it nowhere nor do I see component scanning configured.

      Also explain a bit more about the setup (where do you use it web application? Scanning both in contextloaderlistener and dispatcherservlet).

      Last tip use the search as questions regarding non working transactions have been answered numerous times before.
      @Service and @Repository can go together: Pro Spring 3 (page 353, Integration with JPA 2).

      My bean defined? Do you mean: where is it ijected?:

      Code:
      @Controller 
      public class HomeController {
      	       
      	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
      	    
      	@Autowired
      	VideoService videoService;
      	   
      	@RequestMapping(value = "/", method = RequestMethod.GET)
      	public String home(Locale locale, Model model) {
      		logger.info("Welcome home! the client locale is "+ locale.toString());
      		   
      	    Video video = new Video();
      	    
      	    videoService.save(video);
      		return "home";
      	}
      	
      }
      Code:
      @Service
      @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly=false)
      public class VideoService  {
      
      	@PersistenceContext
      	EntityManager entityManager;
      	public void save(Video video) {
      		entityManager.persist(video);
      	}
      }
      Code:
      <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
      
      	<!-- TODO change to proper data source -->
      	
      	<bean id="dataSource"
      		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
      		<property name="url" value="jdbc:mysql://localhost/video" />
      		<property name="username" value="root" />
      		<property name="password" value="root" />
      	</bean>
      
      	<bean id="entityManagerFactory"
      		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
      		<property name="persistenceUnitName" value="video_pu" />
      		<property name="dataSource" ref="dataSource" />
      		<property name="jpaVendorAdapter">
      			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
      				<property name="showSql" value="true" />
      				<property name="generateDdl" value="true" />
      				<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
      			</bean>
      		</property>
      
      	</bean>
      
      	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
      		<property name="entityManagerFactory" ref="entityManagerFactory" />
      		<property name="dataSource" ref="dataSource" />
      	</bean>
      
      	<!-- enable the configuration of transactional behavior based on annotations -->
      	<tx:annotation-driven transaction-manager="transactionManager"  />
      
      	<!-- post-processors for all standard config annotations -->
      	<context:annotation-config />
      
      	<context:component-scan base-package="uk.co.package" />
      Is that enough? I have changed what I could and it still doesn't work.
      Component scanning, only @Service, I am using spring MVC 3.0.

      I have made a walkthrough the subjects and I couldn't find any answer for my question.

      Comment


      • #4
        @Service and @Repository can go together but the question is do you want that in the light of single responsibility... But that isn't my decision to make.

        You are using component-scanning, my guess is, as mentioned earlier, you are scanning twice (once in the context for the ContextLoaderListener and once in the DispatcherServlet).

        Comment


        • #5
          Originally posted by Marten Deinum View Post
          @Service and @Repository can go together but the question is do you want that in the light of single responsibility... But that isn't my decision to make.

          You are using component-scanning, my guess is, as mentioned earlier, you are scanning twice (once in the context for the ContextLoaderListener and once in the DispatcherServlet).
          You are my hero today. Thanks!!

          Comment

          Working...
          X