当前位置: 首页 > 知识库问答 >
问题:

如何确定spring数据JPA被执行?

耿招
2023-03-14

我正在尝试在springboot 2.5.3和h2数据库中扩展JPARepository。

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long> {
      boolean deleteCustomerById(Long id);
}

返回一个布尔值,因为服务和控制器需要知道操作是否成功并发送适当的响应实体。

 public boolean delete(Long id) {
        return customerRepository.deleteCustomerById(id);
    }

控制器

@DeleteMapping(path = "/customers/{id}")
public ResponseEntity<?> deleteCustomer(@PathVariable("id") Long id){
    Optional<Customer> foundCustomer= customerService.findById(id);
    return foundCustomer.map(customer -> {
        if (customerService.delete(id)){
            return ResponseEntity.ok().build();
        }else {
            return ResponseEntity.internalServerError().build();
        }
    }).orElse(ResponseEntity.notFound().build());
}

这样做会在测试存储库时出错。

@Test
public void deleteCustomerByIdSuccess(){
    boolean result=customerRepository.deleteCustomerById(1L);
    assertTrue(result,"Customer should be deleted successfully");
    Optional<Customer> foundCustomer=customerRepository.findById(1L);
    assertFalse(foundCustomer.isPresent(),"Customer 1 should be deleted and not be found.");
}

错误:

java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.Boolean (java.lang.Integer and java.lang.Boolean are in module java.base of loader 'bootstrap')

    at com.sun.proxy.$Proxy92.deleteCustomerById(Unknown Source)
    at com.prabhakar.customer.repository.CustomerRepositoryTest.deleteCustomerByIdSuccess(CustomerRepositoryTest.java:67)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:221)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

但当我将存储库更改为:

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long> {
      int deleteCustomerById(Long id);
}

并用1验证它是否有效。

有一个默认的deleteById方法,但它返回void。

void deleteById(ID var1);

它希望它返回一个布尔值,所以我尝试使用我自己的实现,如上所述。

Spring数据JPA在内部使用什么?(它是执行更新吗?我可以看到日志和SQL查询,但是我们如何知道它是否已被执行或通过返回vile。

共有2个答案

鲍建业
2023-03-14

这是< code >派生删除查询的一个例子

可以使用几种不同的返回类型来验证删除操作。

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long> {
      Customer deleteById(Long id); // To get deleted record
      Long deleteById(Long id); // To get deleted record count
      void deleteById(Long id); // To get ignore result
}

如果要确保记录已被删除,则必须检查结果。

据我所知,派生删除查询不支持booleantype

但是,如果<code>deleteById</code>将返回<code>布尔值</code>,则必须检查结果为false时发生了什么错误。这意味着该实体不能被删除,因为这会产生误导。

卢俊发
2023-03-14

我认为您必须创建自己的自定义delete方法。请注意,下面的CustomerRepository还扩展了CustomCustomerRepository

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long>, CustomCustomerRepository {
      
}

创建“自定义”存储库:

public interface CustomCustomerRepository {

    boolean deleteCustomerById(Long id);
}

和在中提供了delete方法的自定义实现

public class CustomCustomerRepositoryImpl implements CustomCustomerRepository {

        @Override    
        boolean deleteCustomerById(Long id) {
            // your specific code here, 
            // delete the record and return either true or false 
            // depending what you have in mind
        }
}

也可以参考这里:https://docs . spring . io/spring-data/JPA/docs/current/reference/html/# repositories . custom-implementations

 类似资料:
  • 使用Spring Boot应用程序。我有一个类UserService,我在其中创建了一个动态查询,根据请求参数具有多个or条件: 我有UserRepository接口,我需要执行这个查询。到目前为止,我使用了findById等JPA函数或@Query(“从事件中选择id”)。 如何将此查询从服务类传递到存储库并执行它?

  • 有没有办法知道实体是否是从数据库中读取的? 这个问题与如何知道一个分离的JPA实体是否已经被持久化有关?。但是检查其主键的变通方法没有回答我的问题。对于从导入文件中读取主键的实体来说,它是不起作用的。 将问题引申如下: JPA实现如何确定是否要插入或更新实体?

  • 在我的@Repository接口中,我使用包含参数(addressType)的JPQL@Query创建了自定义查找方法。 在该方法中,我没有在参数上指定@Param(“addressType”)。所以我要 java.lang.IllegalArgumentException:参数绑定的名称不能为空或空!对于命名参数,您需要使用@Param查询Java版本上的方法参数 好的,这很清楚,但是我用的是J

  • 如何为查询指定超时?我使用的是Oracle11g,我希望可以使用类似这样的东西。

  • 我有两个实体。父母和孩子。 儿童知识库。JAVA 我试图通过标准找到子实体,它应该总是有父实体。 我得到一个例外,它试图在地址表中找到parentObj。 我找到了这个链接,并尝试了Joep给出的解决方案,但出现了相同的错误。 Spring数据JPA JpaSpecificationExecator EntityGgraph 我错过了什么。我无法理解为什么/如何在just Child对象中查找pa

  • 我试图使用Spring数据JPA(2.1)和Hibernate在PostgreSQL上执行跳过锁定查询。查询如下所示: 根据Spring数据JPA native query skip locked和Select for update skip locked from JPA level,它应该可以工作,但生成的查询只选择update而不跳过锁定的行。 生成的查询: Hibernate:选择obj0