spring data jpa:插入而不是删除

时间:2018-06-15 11:23:27

标签: spring-boot junit spring-data-jpa spring-data junit4

我有一个基本的SpringBoot应用程序。使用Spring Initializer,JPA,嵌入式Tomcat,Thymeleaf模板引擎和包作为可执行的JAR文件。我创建了这个Repository类:

@Repository
public interface MenuRepository extends CrudRepository<Menu, Long> {

      @Cacheable("menus")
      @Query("select cur from Menu cur where cur.MenuId = ?1")
      Menu findMenuByMenuId (String MenuId);

      @Cacheable("menus")
      @Query("select cur from Menu cur where lower (cur.symbol) = lower (?1) ")
      Menu findMenuBySymbol (String symbol);

和这项服务:

@Service
public class MenuService {

        @Autowired
    protected MenuRepository menuRepository;    

    @Autowired
    MenuPriceService menuPriceService;


     @Transactional
     public Menu save (Menu menu) {              
         return menuRepository.save (menu);
     }


     @Transactional
     public void delete (Menu menu) {
         menuRepository.delete  (menu);
     }
     ..
}


}

和这个JUNIT测试:

    @Test
    @Transactional
    public void testDelete () {

        String menuName = System.currentTimeMillis()+"";

        Menu menu = new Menu(); 
        menu.setMenuId(menuName);
        menuService.delete (menu);
}

但这是我在控制台中看到的

Hibernate: 
    insert 
    into
        t_menu
        (...) 
    values
        (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

2 个答案:

答案 0 :(得分:1)

虽然删除@Transactional as suggested in another answer可能会使行为消失,但我还是质疑测试的有效性。

问题实际上是:为什么要尝试删除不在数据库中的实体?

解决方案:

如果你模拟不知道实体是否存在的情况,使用deleteById它会在数据库中没有id时抛出异常,你当然可以捕获它。

有关此插入的发生方式和原因的一些背景知识:

delete(T entity)是通过SimpleJpaRepository.delete(T entity)实现的,它基本上包含这一行代码。

em.remove(em.contains(entity) ? entity : em.merge(entity));

正如您所看到的,如果实体未出现在merge中,它会对实体执行EntityManager。如果没有merge,如果EntityManager中存在具有相同类和ID的另一个实例,则您可能会在会话中找到重复的实体。但是,由于您的实体根本不存在,因此会触发插入数据库。

您可能会这样认为:您创建一个实例,让EntityManager知道它(通过告诉它删除它)并删除它,所以这些是需要在数据库 - &gt;插入+删除。

答案 1 :(得分:0)

删除@Transactional

@Test
    public void testDelete () {

        String menuName = System.currentTimeMillis()+"";

        Menu menu = new Menu(); 
        menu.setMenuId(menuName);
        menuService.delete (menu);
}