【问题标题】:How to update the data in Spring Boot MVC如何在 Spring Boot MVC 中更新数据
【发布时间】:2019-05-08 12:32:22
【问题描述】:

我有最常见的 Spring Boot MVC 项目。我正在尝试通过 PUT 写入更新数据。

@RestController
@RequestMapping(CommentController.PATH)
public class CommentController {

    public final static String PATH = "/comments";

    @Autowired
    private CommentService service;

    @PutMapping("/{id}")
    public Comment update(@RequestBody Comment comment, @PathVariable Long id) {
        return service.update(id, comment);
    }
}

@Service
public class CommentService {

    @Autowired
    private CommentRepository repository;

    public Comment update(Long id, Comment entity) {
        Optional<Comment> optionalEntityFromDB = repository.findById(id);
        return optionalEntityFromDB
                .map(e -> saveAndReturnSavedEntity(entity, e))
                .orElseThrow(getNotFoundExceptionSupplier("Cannot update - not exist entity by id: " + id, OBJECT_NOT_FOUND));
    }

    private Comment saveAndReturnSavedEntity(Comment entity, Comment entityFromDB) {
        entity.setId(entityFromDB.getId());
        return repository.save(entity);
    }

}

@Repository
public interface CommentRepository extends JpaRepository<Comment, Long> {
}

@Entity
public class Comment  {
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;

    @Column(name = "name")
    protected String name;
}

然后我编写一个能够检查更新数据的测试:

@SpringBootTest
@RunWith(SpringRunner.class)
@Transactional
// DBUnit config:
@DatabaseSetup("/comment.xml")
@TestExecutionListeners({
        TransactionalTestExecutionListener.class,
        DependencyInjectionTestExecutionListener.class,
        DbUnitTestExecutionListener.class
})
public class CommentControllerTest {

    private MockMvc mockMvc;
    private static String route = PATH + "/{id}";

    @Autowired
    private CommentController commentController;

    @Autowired
    private CommentRepository commentRepository;

    @PersistenceContext
    private EntityManager entityManager;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.standaloneSetup(commentController)
                .build();
    }

    @Test
    public void update_ShouldReturnCreated2() throws Exception {
        int id = 1;
        String name = "JohnNew";
        Comment expectedComment = new Comment();
        expectedComment.setName(name);

        ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
        String json = ow.writeValueAsString(expectedComment);

        this.mockMvc.perform(put(route, id)
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(json))
                .andDo(print());

        entityManager.clear();
        entityManager.flush();

        Comment commentUpdated = commentRepository.findById(1L).get();
        assertThat(commentUpdated.getName(), equalTo(name));        // not equals!
    }
}    

comment.xml:

<dataset>
    <Comment id="1" name="John" />
</dataset>

但问题是数据没有更新。 如果启用 Hibernat 的日志记录,那么也没有对数据库的更新请求。 我做错了什么?

【问题讨论】:

  • 1) 您提供的代码不会编译,您的 CommentService 不会扩展或实现任何类或接口 2) 您是否在视图中使用开放会话? 3)您使用哪种代理类型?
  • @AlmasAbdrazak 修复,我使用 spring boot 的所有默认值,没有自定义
  • 您应该在调试器中检查route 变量。

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


【解决方案1】:

您缺少CommentService 中的@Transactional 注释。虽然在每个方法级别添加它可能会更好,但请尝试将其添加到类级别以验证这是否可以解决问题:

@Service
@Transactional
public class CommentService {

【讨论】:

  • 不需要放置事务注释,因为默认情况下spring boot open session在视图中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-08
  • 1970-01-01
  • 2017-05-30
  • 2021-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多