Page 1 of 2 12 LastLast
Results 1 to 10 of 17

Thread: Spring 2.0 + JPA + @PersistenceContext annotation

  1. #1
    Join Date
    Aug 2006
    Posts
    21

    Default Spring 2.0 + JPA + @PersistenceContext annotation

    I'm looking for a smallest example (working and complete example!) of working with database using Spring 2.0 + JPA + @PersistenceContext annotation.

    I have tried to build a sample according to the instructions here: http://static.springframework.org/sp...m.html#orm-jpa
    (12.7.3. Implementing DAOs based on plain JPA), but seems that PersistenceAnnotationBeanPostProcessor is not called, so EntityManager reference is not injected and I get NullPointerException...

    I run a standalone J2SE app on Java 5.0. It should work with Spring 2.0 & JPA (Toplink).
    Can somebody help me?

  2. #2
    Join Date
    Aug 2004
    Location
    Berne, Switzerland
    Posts
    42

    Default

    I have the same setup and it works for me.

    I can show you my code, although it's similar to the steps shown in the manual

    First the DAO implementation:

    Code:
    @Repository
    public class PersonDAOJpaEntityManager implements PersonDAO {
    
        private EntityManager em;
        
        @PersistenceContext
        public void setEntityManager(EntityManager em) {
        	this.em = em;
        }
    
        ...
    }
    and here the important parts in the Spring configuration:

    <bean id="personDAO" class="com.trivadis.issuesmgmt.dao.impl.PersonDAOJ paEntityManager"/>
    <bean class="org.springframework.dao.annotation.Persiste nceExceptionTranslationPostProcessor"/>
    <bean class="org.springframework.orm.jpa.support.Persist enceAnnotationBeanPostProcessor"/>

    That's all I have. What is the exact error you get ?

    I can attach the sample I have, it's not completely stripped down, as it shows both the template based and the Entity Manager approach and also both Hibernate and Toplink essentials.
    Guido Schmutz
    Principal Consultant, Trivadis Switzerland
    Email: guido.schmutz AT trivadis.com

  3. #3
    Join Date
    Aug 2004
    Location
    Berne, Switzerland
    Posts
    42

    Default

    here is the stripped-down version only including the Entity Mangager version.

    to run it in eclipse, set the SPRING and HIBERNATE3 classpath variable. I'm also using an ORACLE10_HOME variable to get the JDBC driver ....
    Attached Files Attached Files
    Guido Schmutz
    Principal Consultant, Trivadis Switzerland
    Email: guido.schmutz AT trivadis.com

  4. #4
    Join Date
    Aug 2006
    Posts
    21

    Default

    gschmutz, thanks for you fast response!
    Seems that I have a similar beans configuration excepting that I did not write @Repository and <bean class="org.springframework.dao.annotation.Persiste nceExceptionTranslationPostProcessor"/> lines.

    I use Toplink to work with MySQL 5.0; my classpath is:

    commons-logging.jar
    junit.jar
    log4j-1.2.13.jar
    mysql-connector-java-5.0.3-bin.jar
    persistence.jar
    spring.jar
    spring-core.jar
    spring-jpa.jar
    spring-mock.jar
    toplink-essentials.jar


    I noted that PersistenceAnnotationBeanPostProcessor class was not called and even was not loaded at all ! (I used 'class-load' and 'method-level' breal point in the Eclipse debugger). So exact error was a NullPointerException thrown when I call something like em.persist();
    If I drop the @PersistenceContext annotation and configure entityManagerFactory dependency injection explicitly in the configuration file, things begin working! But it is not very beautiful to create EntityManagers from their factory manually...

    I will try to build your sample and to understand where the problem was; hope it will work - in fact, I did not see any complete sample on this topic yet.

    Thank you!

  5. #5
    Join Date
    Aug 2004
    Location
    Berne, Switzerland
    Posts
    42

    Default

    >>Seems that I have a similar beans configuration excepting that I did not write
    >>@Repository and <bean class="org.springframework.dao.annotation.Persiste nceExceptionTranslationPostProcessor"/> lines

    You are right, @Repository and PersistenceExcpetionTranslationPostProcessor are not necessary for the @PersistenceContext functionality to work.
    They "only" give you the additional functionality of the persistence exception translation.
    Last edited by gschmutz; Aug 29th, 2006 at 03:23 PM.
    Guido Schmutz
    Principal Consultant, Trivadis Switzerland
    Email: guido.schmutz AT trivadis.com

  6. #6
    Join Date
    Aug 2006
    Posts
    21

    Default

    gschmutz,
    I have built your sample in my environment. Yes, PersonDAOJpaEntityManagerTest class works, dependency injection is working!
    But the problem still exists: try to call PersonDAO bean from a simple class with main() function, without test environment (do not extend AbstractJpaTests class, just make a simple J2SE app). You will see a NullPointerException (EntityManager reference is not injected).

    The problem is: how to make @PersistenceContext annotation working without test environment...

    Here is my example:
    Code:
    public class Main {
    
    	public static void main(String[] args) {
    		XmlBeanFactory bf = new XmlBeanFactory(
    new ClassPathResource("context/testContext.xml"));
    		PersonDAO dao=(PersonDAO)bf.getBean("personDAO");
    		
    		Person p=new Person();
    		p.setFirstName("testName");
    		dao.save(p);
    	}
    
    }
    (I added import of all other xml files from testContext.xml for simplicity; also I simplified your entities - they have just 2 fields)

  7. #7
    Join Date
    Aug 2006
    Posts
    21

    Default

    Maybe, I misunderstand something... Maybe @PersistenceContext annotations work only in some "container" (Web app or tests as above) and not in a plain J2SE app?

  8. #8
    Join Date
    Aug 2004
    Location
    Berne, Switzerland
    Posts
    42

    Default

    No, the problem is much simpler, it's caused by the use of the BeanFactory instead of an ApplicationContext, which is used inside the unit test, behind the scene when using the AbstractJpaTests base class.

    If you change your Main class to

    Code:
    public class Main {
    
    	public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext("context/testContext.xml");
    		PersonDAO dao=(PersonDAO)ctx.getBean("personDAO");
    		
    		Person p=new Person();
    		p.setFirstName("testName");
    		dao.save(p);
    	}
    }
    it will work.

    The reason for that is a slightly different behavior between a BeanFactory and an ApplicationContext when it comes to BeanPostProcessors. From the Spring reference manual:

    It is important to know that a BeanFactory treats bean post-processors slightly differently than an
    ApplicationContext. An ApplicationContext will automatically detect any beans which are defined in the
    configuration metadata which is supplied to it that implement the BeanPostProcessor interface, and register
    them as post-processors, to be then called appropriately by the container on bean creation. Nothing else needs
    to be done other than deploying the post-processor in a similar fashion to any other bean. On the other hand,
    when using a BeanFactory implementation, bean post-processors explicitly have to be registered, with code
    like this:

    ConfigurableBeanFactory factory = new XmlBeanFactory(...);
    // now register any needed BeanPostProcessor instances
    MyBeanPostProcessor postProcessor = new MyBeanPostProcessor();
    factory.addBeanPostProcessor(postProcessor);
    // now start using the factory


    This explicit registration step is not convenient, and this is one of the reasons why the various
    ApplicationContext implementations are preferred above plain BeanFactory implementations in the vast
    majority of Spring-backed applications, especially when using BeanPostProcessors


    That's the whole reason, why your PersistenceAnnotationBeanPostProcessor never got loaded and therefore couldn't do its work!
    Guido Schmutz
    Principal Consultant, Trivadis Switzerland
    Email: guido.schmutz AT trivadis.com

  9. #9
    Join Date
    Aug 2006
    Posts
    21

    Default

    Thank you!!
    Yes, after I switched to ApplicationContext, it began to work
    Sorry... it was really confusing for me, I am novice in Spring, I always worked with Java EE and EJB 2.0-3.0.

    I think (just my opinion as novice) that the problem of Spring is that it is not well documented - in the Manual I see a detailed description of internal concepts, but there are no documents like "Getting Started" and "Examples", no documets describing Spring from the "user's point of view".
    If you compare, for example, WebLogic Server or Sun App Server documentations, you will see the difference.

    Of course, when you beging to understand Spring concepts, things look better

  10. #10
    Join Date
    Aug 2004
    Location
    Berne, Switzerland
    Posts
    42

    Default

    No problem, glad that I was able to help ...

    Quote Originally Posted by vatel
    I think (just my opinion as novice) that the problem of Spring is that it is not well documented - in the Manual I see a detailed description of internal concepts, but there are no documents like "Getting Started" and "Examples", no documets describing Spring from the "user's point of view".
    You're right in some ways, but you have to be fair, Spring is an open source project with no large company behind, and is in my opinion doing very well in terms of documentation and support. At least compared to a lot of other open source projects around. You won't find tutorials in the "offical" Spring documentation, that's right, but you can find a lot of excellent books

    http://www.springframework.org/bookreview

    about Spring, all written in different style, some more tutorial like (Spring Live) and other more in a user guide/reference style (Prof. Development with Spring Framework, Pro Spring). Most of them "only" cover Spring 1.x, of course because Spring 2.0 is not final yet. It was the books which helped me to understand Spring and I was using them together with the Spring reference manual.
    Another good source are the samples provided with the Spring distribution and of course the Spring forum!

    Last but not least, I'm currently writing another book, although in German ;-), covering lots of the Spring 2.0 stuff, which should also help to see the new features working. And JPA and the EntityManager style you were using is certainly covered!
    Guido Schmutz
    Principal Consultant, Trivadis Switzerland
    Email: guido.schmutz AT trivadis.com

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •