Announcement Announcement Module
Collapse
No announcement yet.
How configure PersistenceExceptionTranslationPostProcessor for JavaConfig... Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • How configure PersistenceExceptionTranslationPostProcessor for JavaConfig...

    Hello Guys

    I have two main type of applications, one working only with Hibernate and other working only with JPA (with HibernateJpaVendorAdapter), these applications are created with:

    1) XML + Annotations
    2) Only XML
    3) Only JavaConfig.

    For both projects of type (1) I have the repositories classes annotated with @Repository and in the XML files I have declared the PersistenceExceptionTranslationPostProcessor

    Practically something like this

    Hibernate:

    Code:
    @Repository
    @Transactional
    public class ArticuloHibernateRepository implements ArticuloRepository{
    
    	private SessionFactory sessionFactory;
    	
    	@Autowired
    	public ArticuloHibernateRepository(SessionFactory sessionFactory){
    		this.sessionFactory = sessionFactory;
    	}
    ...
    }
    With

    Code:
    <bean id="sessionFactory" 
              class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    ...
    </bean>
    		
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

    JPA:

    Code:
    @Repository
    @Transactional
    public class ArticuloJpaRepository implements ArticuloRepository{
    
    	private EntityManager entityManager;
    	
    	@PersistenceContext
    	public void setEntityManager(EntityManager entityManager) {
    		this.entityManager = entityManager;
    	}
            ....
    }
    With

    Code:
    <bean id="entityManagerFactory"
              class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
              <property name="dataSource" ref="dataSource" />
    	  <property name="jpaVendorAdapter">
    		     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
              </property>
               ...
    </bean>
    		      
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
    I have read carefully the Spring Reference Documentation, the target chapter was 15. Object Relational Mapping (ORM) Data Access, specially the section 15.2.2 Exception translation, where says

    Code:
    However, Spring enables exception translation to be applied transparently through the @Repository annotation:
    Now I have the follow question....

    How I would get this same Exception translation bean post processor functionality if I have the same repositories declared without @Repository?

    I mean, only Java code.

    Hibernate:

    Code:
    public class ArticuloHibernateRepository implements ArticuloRepository{
    
    	private SessionFactory sessionFactory;
    	
    	public ArticuloHibernateRepository(SessionFactory sessionFactory){
    		this.sessionFactory = sessionFactory;
    	}
    ...
    }
    JPA


    Code:
    public class ArticuloJpaRepository implements ArticuloRepository{
    
    	private EntityManager entityManager;
    	
    	public void setEntityManager(EntityManager entityManager) {
    		this.entityManager = entityManager;
    	}
            ....
    }
    therefore these repositories would be declared through XML or JavaConfig...
    (I will share only for Hibernate, it to avoid make this post verbose)..

    Something like this

    XML

    Code:
    <bean id="articuloRepository"
    	 class="com.manuel.jordan.repository.hibernate.sinannotations.ArticuloHibernateRepository" >
       <constructor-arg ref="sessionFactory" />
    </bean>
    Or

    JavaConfig: Well since JavaConfig belong to Spring, has sense only here use some annotations...


    Code:
    @Configuration
    public class SpringFrameworkHibernateRepositoryConfiguration {
    
    	private SessionFactory sessionFactory;
    	
    	@Autowired
    	public void setSessionFactory(SessionFactory sessionFactory) {
    		this.sessionFactory = sessionFactory;
    	}
    
    	@Bean
    	public ArticuloRepository articuloRepository(){
    		ArticuloRepository articuloRepository = new ArticuloHibernateRepository(sessionFactory);
    		return articuloRepository;
    	}
    ...
    }
    Now, I have running these projects in many variations...I mean:

    1) XML + Annotations
    2) Only with Spring with XML
    3) Only with Spring JavaConfig

    I have these projects working fine....

    but later I have remember that this PersistenceExceptionTranslationPostProcessor was not declared for the projects (2) and (3).

    Therefore how was possible get all working fine if in both projects I am not using @Repository?.

    The PersistenceExceptionTranslationPostProcessor APi says..

    Code:
    Bean post-processor that automatically applies persistence exception translation to any bean marked with Spring's @Repository annotation, adding a corresponding PersistenceExceptionTranslationAdvisor to the exposed proxy (either an existing AOP proxy or a newly generated proxy that implements all of the target's interfaces).
    Just like playing for JavaConfig I have declared...

    Code:
    @Bean
    public PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor(){
    	return new PersistenceExceptionTranslationPostProcessor();
    }
    And now I get...

    Code:
    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: 
    Error creating bean with name 'persistenceExceptionTranslationPostProcessor' defined in class path resource [com/manuel/jordan/javaconfig/SpringFrameworkHibernateConfiguration.class]: 
    Initialization of bean failed; nested exception is java.lang.IllegalStateException: 
    No persistence exception translators found in bean factory. Cannot perform exception translation.
    ....
    Caused by: java.lang.IllegalStateException: No persistence exception translators found in bean factory. 
    Cannot perform exception translation
    ...
    Some appreciations and ideas are highly appreciated

    Thank You.

  • #2
    The 'PersistenceExceptionTranslationPostProcessor' will be automatically registered if JPA is detected and when using context-component-scan or context-annotation-config.

    Next to that exception translation is (also) done by springs transaction support and those classes call the same code as the PersistenceExceptionTranslator support.

    Comment


    • #3
      Hello Marten...

      The 'PersistenceExceptionTranslationPostProcessor' will be automatically registered if JPA is detected and when using context-component-scan or context-annotation-config.
      Remember that the Java Repositories/Services classes has none Spring annotation.
      Therefore the blue parts has none sense for this situation... Just imagine a boss with the requirement of have all the classes without annotations....

      Next to that exception translation is (also) done by springs transaction support and those classes call the
      same code as the PersistenceExceptionTranslator support.
      How? If these classes has no the @Transactional nor @Repository annotations.....

      According with the API, PersistenceExceptionTranslationPostProcessor is only applied for classes annotated with @Repository...

      Imagine two types of application/
      1) Java classes without annotations and all configured with XML
      2) Java classes without annotations and all configured with JavaConfig
      (these configuration classes can have @Autowired @Bean @Import etc...)

      Comment


      • #4
        The use of java config implies the use of annotations and as such those Bean(Factory)Processors are also registered and as mentioned is is also part of springs transaction support, regardless if you use annotations or not.

        According with the API, PersistenceExceptionTranslationPostProcessor is only applied for classes annotated with @Repository...
        Correct BUT exception translation is also done when using springs transaction support/transaction managers those also convert exception by using the same mechanism as the interceptor registered by the PersistenceExceptionTranslationPostProcessor. Because it is part of the transaction support it doesn't require the PersistenceExceptionTranslationPostProcessor to be registered.

        I suggest you take a look at the implementations of the PersistenceExceptionTranslator interface and the calls to the translateExceptionIfPossible method of that interface (well actually the translateIfNecessary method on the DataAccessUtils). You will then notice it is used by both the transaction support and the PersistenceExceptionTranslationInterceptor.

        Comment


        • #5
          Hello Marten

          Correct BUT exception translation is also done when using springs transaction support/transaction managers those also convert exception by using the same mechanism as the interceptor registered by the PersistenceExceptionTranslationPostProcessor. Because it is part of the transaction support it doesn't require the PersistenceExceptionTranslationPostProcessor to be registered.
          Thank You by the explanation...

          I suggest you take a look at the implementations of the PersistenceExceptionTranslator interface and the calls to the translateExceptionIfPossible method of that interface (well actually the translateIfNecessary method on the DataAccessUtils). You will then notice it is used by both the transaction support and the PersistenceExceptionTranslationInterceptor.
          It will be done..

          Thank You!

          Comment

          Working...
          X