Announcement Announcement Module
Collapse
No announcement yet.
Spring Documentation on integrating Spring and JPA is not correct Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring Documentation on integrating Spring and JPA is not correct

    Hi,
    I have been reading Spring 3.0.x documentation for integrating JPA 2.0 with Spring 3.0.
    Section 13.5.2 in the documentation (Implementing DAOs based on plain JPA) says :

    Spring can understand @PersistenceUnit and @PersistenceContext annotations both at field and method level if a PersistenceAnnotationBeanPostProcessor is enabled.
    This seems to be a bit unclear as it doesnt talk about how PersistenceAnnotationBeanPostProcessor can be enabled in different ways. I now understand that PersistenceAnnotationBeanPostProcessor can either be enabled by defining a spring bean or by using context:annotation-config or component-scan or tx:annotation-driven.
    Last edited by kumara; May 19th, 2011, 08:13 AM. Reason: Unclear understanding

  • #2
    Then you either have a context:annotation-config or component-scan that automatically enables the PersistenceAnnotationBeanPostProcessor.

    Comment


    • #3
      I do not have either of the above, although I do have <tx:annotation-driven/> in my spring xml file that I am refrencing in my JavaConfig file using @ImportResource.

      But I need to have it otherwise Spring is not detecting the classes annotated with @TransactionAttribute.

      This is what I have tried :

      TRY 1:

      I just define the following beans in my Config.java file :
      Code:
      private @Value("#{jdbcProperties['jdbc.driver']}") String jdbcDriver;
          private @Value("#{jdbcProperties['jdbc.url']}") String url;
          private @Value("#{jdbcProperties['jdbc.username']}") String username;
          private @Value("#{jdbcProperties['jdbc.password']}") String password;
          private @Value("#{jdbcProperties['jdbc.showSql']}") Boolean showSql;
      
      public @Bean BasicDataSource dataSource() {
              System.out.println("jdbcDriver is :" + jdbcDriver);
              BasicDataSource dataSource = new BasicDataSource();
              dataSource.setDriverClassName(jdbcDriver);
              dataSource.setUrl(url);
              dataSource.setUsername(username);
              dataSource.setPassword(password);
              return dataSource;
          }
      
      public @Bean(name="entityManagerFactory") @DependsOn({"dataSource"})EntityManagerFactory entityManagerFactory(){
              LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
              entityManagerFactory.setPersistenceXmlLocation("classpath:META-INF/persistence.xml");
              entityManagerFactory.setPersistenceUnitName("testTransaction");
              entityManagerFactory.setDataSource(dataSource());
              HibernateJpaVendorAdapter jpaAdaptor = new HibernateJpaVendorAdapter();
              jpaAdaptor.setShowSql(showSql);
              jpaAdaptor.setGenerateDdl(true);
              jpaAdaptor.setDatabasePlatform("org.hibernate.dialect.HSQLDialect");
              entityManagerFactory.setJpaVendorAdapter(jpaAdaptor);
              //This is the most important line as now it will not be called by Spring and we have to call it ourself
              entityManagerFactory.afterPropertiesSet();
              return entityManagerFactory.getObject();
          }
      
      public @Bean(name="transactionManager") JpaTransactionManager transactionManager(){
              JpaTransactionManager transactionManager = new JpaTransactionManager();
              transactionManager.setEntityManagerFactory(entityManagerFactory());
              return transactionManager;
      
          }
      
      public @Bean PersistenceAnnotationBeanPostProcessor beanPostProcessor(){
              PersistenceAnnotationBeanPostProcessor processor = new PersistenceAnnotationBeanPostProcessor();
              return processor;
          }
      
      .......
      
      and my test Service bean that has @TransactionAttribute present on it.
      It fails first with the NullPointerException at the following line :

      Code:
      jpaAdaptor.setShowSql(showSql);
      where showSql is being read from a properties file using @Value annotation.


      TRY 2: I hard code all the values for JDBC access and try again.

      My dataSource bean now looks like :
      Code:
       public @Bean BasicDataSource dataSource() {
              System.out.println("jdbcDriver is :" + jdbcDriver);
              BasicDataSource dataSource = new BasicDataSource();
      //        dataSource.setDriverClassName(jdbcDriver);
      //        dataSource.setUrl(url);
      //        dataSource.setUsername(username);
      //        dataSource.setPassword(password);
              dataSource.setDriverClassName("org.hsqldb.jdbc.JDBCDriver");
              dataSource.setUrl("jdbc:hsqldb:mem:.");
              dataSource.setUsername("sa");
              dataSource.setPassword("");
              return dataSource;
          }
      Rest all remains same. It fails with error :
      Code:
      Exception in thread "main" javax.persistence.TransactionRequiredException: no transaction is in progress
      	at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:419)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:597)
      	at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365)
      	at $Proxy14.flush(Unknown Source)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:597)
      	at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:224)
      	at $Proxy14.flush(Unknown Source)
      	at org.example.dao.model.TestDao.insert(TestDao.java:29)
      	at org.example.service.TestService.testMethod(TestService.java:32)
      	at org.example.transaction.config.LoadConfiguration.main(LoadConfiguration.java:17)
      finally I introduce <tx:annotation-driven/> in my spring.xml file and and things start working again. Although @Value still doesnt work. I have to remove the PersistenceAnnotationBeanPostProcessor bean in order to have it working again.

      Thanks,
      Anuj

      Comment


      • #4
        btw, I had reported the above issue with @Value and PersistenceAnnotationBeanPostProcessor in the folowing thread :

        http://forum.springsource.org/showth...ean-is-defined

        Comment


        • #5
          The problem is that @Value is also being processed by BeanFactoryPostProcessors and you probably have an ordering issue here. However I find the starting post of your thread misleading because it isn't the whole truth/storie...

          Comment


          • #6
            Seems like my previous post got lost somewhere. Reposting :

            I tried changing the order of the beans within my Config.java file such that PersistenceAnnotationBeanPostProcessor bean occurs before @Value. Still the result is same. @Value is not processed. Is there any other way I can enforce bean order?

            I agree that my above post might be misleading, now that I understand that PersistenceAnnotationBeanPostProcessor can be automatically enabled. I will edit the contents of my above post.

            Also, do you think the above issue requires a separate thread? If it is, then I can create a new thread with the issue.

            Thanks for the quick replies.

            Anuj

            Comment

            Working...
            X