简体   繁体   English

Hibernate作为JPA提供者的Spring DATA JPA

[英]Spring DATA JPA with Hibernate as JPA provider

Using Spring boot application with spring data jpa with hibernate as jpa provider. 将Spring Boot应用程序与带有Hibernate的spring数据jpa一起用作jpa提供程序。

Created one default method in one interface which is extending JpaRepository. 在扩展JpaRepository的一个接口中创建了一个默认方法。

Please check the code. 请检查代码。

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();
    }
}

Now when I am calling this softDelete() from the service layer, it does not return existing user. 现在,当我从服务层调用此softDelete()时 ,它不会返回现有用户。 It is returning as NULL. 它返回为NULL。

This is the log stack trace. 这是日志堆栈跟踪。

    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)

Any idea what I am missing ??? 任何想法我想念的???

Couple of things: 几件事情:

  1. You would always get an EntityNotFoundException exception irrespective of whether you get the record or not because i am assuming you want to send that exception when you dont find any record. 无论是否获取记录,您都会始终获得EntityNotFoundException异常,因为我假设您想在找不到任何记录时发送该异常。
  2. You may want to return back the user too, but your return type is void. 您可能也想返回该用户,但是您的返回类型为空。 I would modify the return type to be User instead as below: 我将返回类型修改为User,如下所示:

     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 } 

In addition to the answer provided by SMA also couple of things. 除了SMA提供的答案外,还有其他一些问题。

  1. I do not recall right now but AFAIR it is advised to also name custom classes extending Spring Data Repository as Repository and not Dao . 我现在不记得了,但是建议AFAIR也将扩展Spring Data Repository的自定义类命名为Repository,而不是Dao

  2. Are You sure that You are having this user in a DB? 您确定您在数据库中有该用户吗? How do you initialize the database - Flyway? 如何初始化数据库-Flyway? Spring Boot automatic schema.sql and data.sql files? 春天开机自动schema.sql文件和文件data.sql?

  3. With the code You've provided exception will be thrown even if the entity is in the DB. 使用该代码,即使该实体位于数据库中,也会引发异常。

SMA got your question spot on! SMA吸引了您的疑问! I just have to add that you should try using the JpaRepository without putting any logic inside, just use it for CRUD operations and do the logic in your service layer. 我只需要补充一点,您应该尝试使用JpaRepository而不放入任何逻辑,仅将其用于CRUD操作并在服务层中进行逻辑处理。 Like so: 像这样:

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;
}

and then you can do the error handling in your service. 然后您可以在服务中进行错误处理。 The reference docs are showing some great examples for writing custom queries to better match your needs 参考文档显示了一些很棒的示例,用于编写自定义查询以更好地满足您的需求

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM