2011-07-06 211 views
3

我使用基於彈簧的驗證與在我的應用程序環境下啓用Hibernate驗證組合:數據庫訪問

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     .... 
     <property name="jpaPropertyMap"> 
      <map> 
       <entry key="javax.persistence.validation.factory" value-ref="validator" />  
      </map> 
     </property> 
    </bean> 

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/> 

,我實現了訪問數據庫的自定義驗證使用彈簧注入的DAO來檢查特定對象的有效性約束。這會導致java.lang.StackOverflowError,因爲看起來每次從驗證器中的數據庫加載對象時都會調用驗證,導致無限循環。爲了解決這個問題,我已經嘗試設置我的實體管理器的刷新模式,從下面的代碼驗證器內提交:

entityManager.setFlushMode(FlushModeType.COMMIT); 

這將導致「被刷新集合無法處理()」從休眠狀態中的異常。

是否有一個從自定義驗證程序中訪問數據庫的最佳實踐示例,這將允許我解決這兩個問題?

+0

類似的問題:http://stackoverflow.com/questions/8375704/make-custom-hibernate-validation-annotation-for-電子郵件存在IMHP春天的方式是'@ Autowired'服務或DAO類的驗證和通常使用它們。 –

回答

1

經過大量的實驗,看起來最好的方法是直接從代碼中使用EntityManagerFactory。在驗證器類的初始化(...)方法,我有以下代碼:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu_name"); 
entityManager = emf.createEntityManager(); 

的缺點是,你沒有得到Spring的DI功能,但你仍然可以訪問數據庫。

0

我就遇到了這個問題爲好,這裏是我如何解決它: @Autowired bean works with @Valid on controller but fails with CRUD repository

幾句話,我也到了EntityManagerFactory對象的引用。但是,在撥打我的服務方式之前,我將setFlushMode設置爲FlushModeType.COMMIT。最後,我把它設回FlushModeType.AUTO

下面是一個例子:

public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> { 

    @PersistenceContext 
    private EntityManager em; 

    @Autowired 
    UserService userService; 

    @Override 
    public void initialize(UniqueUsername constraintAnnotation) {  
    } 

    @Override 
    public boolean isValid(String username, ConstraintValidatorContext context) { 
     try { 
      em.setFlushMode(FlushModeType.COMMIT);   
      return userService.findByUsername(username) == null; 

      } finally { 
      em.setFlushMode(FlushModeType.AUTO); 
      }  
    } 
}