簡體   English   中英

Spring Boot + JPA +異常處理

[英]Spring Boot + JPA + Exception Handling

我正在研究將項目轉換為Spring Boot應用程序的概念證明。 我有一個帶有2種方法的存儲庫類:保存並查找。

@Repository
public class UserDataRepo {
    private EntityManager em;

    public boolean save(UserDataModel model) {
        try {
            UserDataModel existingModel = find(model.getTable(), model.getFieldName();
            model.setId(existingModel.getId());
            this.em.merge(model);
            this.em.flush();
            return false;
        } catch (NoResultException e) {
            this.em.persist(model);
            this.em.flush();
            return true;
        }
    }

    public UserDataModel find(String table, String field) {
        Query query = this.em.createQuery(FIND_USERDATA_STATEMENT);
        query.setParameter("table", table);
        query.setParameter("fieldName", field);
        return (UserDataModel) query.getSingleResult(); // throws NoResultException
    } 
}

在我的Spring Boot Application類中,添加了@EnableJpaRepositories@EnableTransactionManagement 我的應用程序啟動正常,沒有任何錯誤。 但是如您所見,save方法取決於find方法來確定是合並還是持久化。 如果沒有記錄,則find方法將引發NoResultException。 我正在觀察的是它永遠不會落在save方法的catch塊內。 Spring Boot只是拋出一個錯誤,提示NoResultException。

在合並的情況下,它就像一個魅力。 因此,這意味着實體經理可以正常工作。

我不知道還需要配置什么。 有什么想法嗎?

從日志中添加錯誤:

org.springframework.dao.EmptyResultDataAccessException: No entity found for query; nested exception is javax.persistence.NoResultException: No entity found for query
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:389)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:223)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:417)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

我不推薦這種行為。 不建議像這樣使用getSingleResult() 在此處閱讀有關為什么永不在JPA中使用getSingleResult的更多信息。 而是嘗試這樣的查詢。

    Query query = this.em.createQuery(FIND_USERDATA_STATEMENT);
    query.setParameter("table", table);
    query.setParameter("fieldName", field);

    List results = query.getResultList();
    if (results.isEmpty()) {
        return null;
    }
    else if (results.size() == 1)  {
        return results.get(0);
    }
    throw new NonUniqueResultException();

對於像這樣的簡單持久性案例,我強烈建議您查看Spring Data JPA,它可以使您避免進行任何復雜的手動持久性管理。 如果這對您不起作用,我強烈建議您不要對邏輯使用異常。 也就是說,我不是依靠失敗的Find查詢中的異常來確定對象是否需要保留或合並,而是先使用計數來確定對象是否存在,然后根據結果繼續查詢。合並或堅持。 通常,在業務邏輯中使用異常被認為是一種反模式,請參閱: 什么時候可以對業務邏輯使用異常處理?

我剛剛在find方法中添加了“ throws NoResultException”,它可以正常工作。 不確定在Spring Boot中配置應用程序時為什么必須將其專門添加到簽名中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM