Announcement Announcement Module
Collapse
No announcement yet.
Missing JPA 2.0 validation in the LocalContainerEntityManagerFactoryBean Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Missing JPA 2.0 validation in the LocalContainerEntityManagerFactoryBean

    Hi,

    It seems there is a piece of the puzzle missing regarding the LocalContainerEntityManagerFactoryBean, which is the validation (JSR-303) being triggered automatically if validation-mode is set to CALLBACK in persistence.xml and hibernate validator 4.0.2 is in the classpath.
    Indeed, with a persistence.xml like this:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
      <persistence-unit name="Default" transaction-type="RESOURCE_LOCAL">
          <validation-mode>CALLBACK</validation-mode>
      </persistence-unit>
    </persistence>
    and an spring config as this:
    Code:
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
        
        <context:annotation-config/>
        <context:component-scan base-package="com.xxx.system.model" />
    
        <tx:annotation-driven transaction-manager="transactionManager"/>
    
        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
            <property name="entityManagerFactory" ref="entityManagerFactory"/>
        </bean>
    
        <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="persistenceUnitName" value="Default" />
            <property name="jpaVendorAdapter">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
            </property>
            <property name="jpaProperties">
                <props>
                    <prop key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</prop>
                    <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.format_sql">true</prop>
                    <prop key="hibernate.hbm2ddl.auto">update</prop>
                </props>
            </property>
            <!-- no need with Hibernate
            <property name="loadTimeWeaver">
                <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
            </property>-->
        </bean>
    
        <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
        <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
    we should not need to call explicitely for bean validation.
    Currently, with this code I get the behaviour I want, which is the validation of the bean before persisting:
    Code:
        @Override
        public void saveOrUpdate(PlaceOfService _pos) {
            ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
            Validator validator = factory.getValidator();
    
            Set<ConstraintViolation<PlaceOfService>> constraintViolations = validator.validate(_pos);
    
            if (constraintViolations.size() > 0) {
                throw new ConstraintViolationException(new HashSet<ConstraintViolation<?>>(constraintViolations));
            }
    
            if (_pos.getId()>0)
                this.em.merge(_pos);//an update of a potentially detached object...
            else
                this.em.persist(_pos);//an insert
        }
    But this should be enough and the validation should be handled by a bean post-processor, as the implementation of the CALLBACK mode implies, right?
    Code:
        @Override
        public void saveOrUpdate(PlaceOfService _pos) {
            if (_pos.getId()>0)
                this.em.merge(_pos);//an update of a potentially detached object...
            else
                this.em.persist(_pos);//an insert
        }
    Thanks,
    Damien

  • #2
    This is implemented with the @Service annotation

    And not with the @Repository annotation, at DAO level, for those who might be interested...
    It happens on the flush as well, so if you have a unit test with no flush, the validation is not triggered.
    Last edited by dbeurton; Feb 22nd, 2010, 08:33 AM.

    Comment

    Working...
    X