当id匹配正确的数据库行时,JpaRepository findById方法返回Optional.empty吗?

时间:2019-03-13 13:48:16

标签: spring-boot spring-mvc spring-mvc-test

出于某种原因,在此测试中,我的PluginRepository接口不想返回保存在数据库中的对象。

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class PluginServiceIntegrationTest {

@Autowired
private PluginRepository pluginRepository;

@Autowired
private PluginService pluginService;

@Autowired
private PluginController pluginController;

@LocalServerPort
private int port;

private String resourceUrl;

@Before
public void setUp() {
    resourceUrl = "http://localhost:" + port + "/plugin/";
}

@Test
public void notNullTest() {
    assertNotNull(pluginRepository);
    assertNotNull(pluginService);
    assertNotNull(pluginController);
}

@Test
public void postPluginTest() {
    RestTemplate restTemplate = new RestTemplate();

    PluginDTO requestDto = new PluginDTO();

    HttpEntity<PluginDTO> request = new HttpEntity<>(requestDto);
    ResponseEntity<PluginDTO> response = restTemplate.exchange(resourceUrl + "create", HttpMethod.POST, request, PluginDTO.class);

    assertEquals(response.getStatusCode(), HttpStatus.OK);
    PluginDTO pluginDTO = response.getBody();
    assertNotNull(pluginDTO);
}

@Test
public void getPluginTest() throws Exception {
    PluginDTO createdDto = new PluginDTO(UUID.fromString("20a246e8-7b74-4081-bb62-6911b8ef43ef"),"Foo", "0.1", "TestAuthor");
    Plugin created = new Plugin(createdDto.getUuid(), createdDto.getName(), createdDto.getVersion(), createdDto.getAuthor());
    pluginRepository.saveAndFlush(created);

    pluginRepository.findAll().forEach(plugin -> System.out.print(plugin.toString()));

    try {
        Plugin plugin = pluginRepository.findById(createdDto.getUuid());
    } catch (Exception ex) {
        ex.printStackTrace();
    }

    System.out.println(pluginService.fetchPlugin(createdDto.getUuid()).toString());

    assertEquals(pluginService.fetchPlugin(createdDto.getUuid()), created);

    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<PluginDTO> response = restTemplate.getForEntity(resourceUrl + createdDto.getUuid(), PluginDTO.class);

    assertEquals(response.getStatusCode(), HttpStatus.OK);
}

@After
public void tearDown() {
    pluginRepository.deleteAllInBatch();
}
}

    System.out.println(pluginRepository.findById(createdDto.getUuid()).get().toString()); // this line 

    assertEquals(pluginService.fetchPlugin(createdDto.getUuid()), created);

    RestTemplate restTemplate = new RestTemplate();
    ResponseEntity<PluginDTO> response = restTemplate.getForEntity(resourceUrl + createdDto.getUuid(), PluginDTO.class);

    assertEquals(response.getStatusCode(), HttpStatus.OK);
}

即使固定值是由createdDto对象设置的,它也不会返回它,我也可以看到这些值也在数据库中。这就是它返回的内容...

20a246e8-7b74-4081-bb62-6911b8ef43ef:Foo:0.1:TestAuthor
java.util.NoSuchElementException: No value present

at java.util.Optional.get(Optional.java:135)
at net.ihq.plugin.controller.PluginServiceIntegrationTest.getPluginTest(PluginServiceIntegrationTest.java:79)
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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

我很沮丧,因为我不明白为什么它可以保存对象,但无法使用与设置它相同的固定值将其取回,但实际上它是从我那里打印出来的错误发生之前就在数据库上。

存储库

@Repository
public interface PluginRepository extends JpaRepository<Plugin, UUID> {

@Query(value = "SELECT * FROM plugins WHERE name=?", nativeQuery = true)
Plugin findByName(String name);
}

实体

@Data
@Entity
@Table(name = "plugins")
@NoArgsConstructor
public class Plugin {

@Id
@Convert(converter = UUIDConverter.class)
@Column(unique = true, updatable = false, length = 36)
private UUID uuid;
private String name;
private String version;
private String author;

public Plugin(UUID uuid, String name, String version, String author) {
    this.uuid = uuid;
    this.name = name;
    this.version = version;

    if (author == null) author = "JoeTAMatthews";

    this.author = author;
}

public Plugin(String name, String version, String author) {
    this(UUID.randomUUID(), name, version, author);
}

public void update(PluginDTO updated) {
    this.name = updated.getName();
    this.version = updated.getVersion();
    this.author = updated.getAuthor();
}

@Override
public String toString() {
    return uuid.toString() + ":" + name + ":" + version + ":" + author;
}
}

1 个答案:

答案 0 :(得分:1)

很抱歉给您带来不便,但是它不起作用的原因是因为数据库中不支持UUID类型,所以我要做的就是获取uuid的字符串类型,因为我的UUIDConverter实际上获得了结果,感谢您的所有帮助。