2017-08-27 82 views
0

使用Spring數據jpa與Spring作爲jpa提供程序的Spring應用程序。春季數據JPA與Hibernate作爲JPA提供程序

在擴展JpaRepository的一個接口中創建一個默認方法。

請檢查驗證碼。

public interface UserDao extends JpaRepository<User, UUID> { 

default void softDelete(UUID id) { 
    User existingUser = findOne(id); 

    if (existingUser != null) 
     existingUser.setActive(false); 

    throw new EntityNotFoundException(); 
    } 
} 

現在,當我從服務層調用這個softDelete(),它不會返回現有的用戶。它返回爲NULL。

這是日誌堆棧跟蹤。

2017-08-27 13:25:01 [http-nio-8080-exec-2] ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaObjectRetrievalFailureException: nested exception is javax.persistence.EntityNotFoundException] with root cause 
javax.persistence.EntityNotFoundException: null 
    at org.rout.projmgmt.dao.UserDao.softDelete(UserDao.java:31) 
    at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627) 
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:62) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) 
    at com.sun.proxy.$Proxy107.softDelete(Unknown Source) 
    at org.rout.projmgmt.service.user.UserServiceImpl.delete(UserServiceImpl.java:53) 
    at org.rout.projmgmt.controller.UserController.delete(UserController.java:53) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) 
    at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:894) 

任何想法我失去了什麼?

回答

2

幾件事情:

  1. 你總會得到一個EntityNotFoundException例外,不論你是否得到了記錄,或者不是因爲我假設你希望當你不找到任何記錄發送例外。
  2. 你也可能想要返回用戶,但是你的返回類型是無效的。我會修改返回類型是用戶,而不是如下:

    default User softDelete(UUID id) { 
        User existingUser = findOne(id); 
        if (existingUser != null) { 
         existingUser.setActive(false); 
        } else { 
         throw new EntityNotFoundException(); 
        } 
        return existingUser;//you may want to save this user again with isActive flag now false 
    } 
    
+0

OMG。我只是忘記了我的Java基礎知識。我很抱歉發佈這個問題。但是非常感謝大家。這真是太愚蠢了。 :( – blackOcean

0

除了通過SMA也對夫婦的事情提供了答案。

  1. 我現在不記得,但AFAIR,建議來命名延長春數據倉庫自定義類,而不是

  2. 是否確定要讓此用戶在數據庫中?你如何初始化數據庫 - Flyway? Spring Boot automatic schema.sql and data.sql files?

  3. 即使實體位於數據庫中,您提供的代碼異常也會被拋出。

0

SMA把你的問題提上了!我只需要補充一點,你應該嘗試使用JpaRepository而不用放入任何邏輯,只是將它用於CRUD操作並在服務層中執行邏輯。像這樣:

public interface UserDao extends JpaRepository<User, UUID> { 

@Modifying 
@Query("update User u set u.active = false where u.id = :id") 
default User softDelete(@Param("id) UUID id) throws EntityNotFoundException; 
} 

然後你可以在你的服務中做錯誤處理。 reference docs顯示了一些很好的例子來編寫自定義查詢,以更好地匹配您的需求