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

  • kumara
    replied
    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

    Leave a comment:


  • Marten Deinum
    replied
    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...

    Leave a comment:


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

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

    Leave a comment:


  • kumara
    replied
    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

    Leave a comment:


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

    Leave a comment:

Working...
X