[英]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.