未删除Java spring JPA存储库实体
在我的代码中,我使用扩展了未删除Java spring JPA存储库实体,java,spring,hibernate,Java,Spring,Hibernate,在我的代码中,我使用扩展了JpaRepository的接口ProductRepository获取一个实体并尝试删除它: @Repository public interface ProductRepository extends JpaRepository<Product, Long> {} 系统输出: long id from deleteProduct: 38 服务方法deleteProductById(): sysout fromdeleteProductById: pu
JpaRepository
的接口ProductRepository
获取一个实体并尝试删除它:
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {}
系统输出:
long id from deleteProduct: 38
服务方法deleteProductById()
:
sysout fromdeleteProductById
:
public void deleteProductById(long productId){
Product product = productRepository.getOne(productId);
System.out.println("Product:\n" + product);
productRepository.delete(product);}
Product: Product{id=38, productName='zip',
producer=lightmarket.mvc.model.domain.Producer@182a383}
但实体未被删除。。。
我必须指出,所有其他CRUD操作都是有效的。创建,更新,阅读-一切都好!只有“delete”不起作用。产品类的equals和hashcode可能有问题,并且从数据库加载的对象与试图删除的对象不同 按id删除产品的更好方法是使用id而不是产品对象 你可以代替
productRepository.delete(product);
与
其中productId的类型为Long。
这也可以避免额外的查询。
JpaRepository
扩展了crudepository
,因此您可以使用:
对于泛型类型,这需要很长时间(请参阅中的文档)
因此,在您的服务中,您将拥有以下功能:
@Service
public class ProductService {
@Autowired
ProductRepository repo;
public void deleteProductById(Long id) {
System.out.println("Deleting product with id: " + id);
// USE deleteById(Long id) and directly pass the id
// Defined in CrudRepository
repo.deleteById(id);
// DON'T use delete() and pass a product
//repo.delete(product);
}
}
然后您的控制器像正常情况一样从服务调用service.deleteProductById()
请参阅文档:增加某些hibernate包的日志详细程度,以了解发生了什么:
logging.level.org.hibernate.SQL=DEBUG logging.level.org.hibernate.type.descriptor.SQL.BasicBinder=TRACE
可能有帮助必须增加这些字符串的位置?在日志追加器的application.properties中。是,在application.properties中添加它们。您是否尝试在服务方法中添加@Transactional注释?请注意链接实体-在我的情况下,已删除实体的链接实体在同一事务中得到更新,因此Hibernate会自动取消原始实体删除的计划(通过Hibernate调试日志找到-谢谢@davidxxx!)这正是我的服务的名称:repo.deleteById(id);是的,但在您的方法中deleteProductById()
您正在调用JpaRepository.delete(产品)
传递Product
对象,而不是调用JpaRepository.deleteById(长id)
并传递long。我的观点是,您不应该创建一个Product
对象并调用delete()
,然后期望您的存储库找到匹配的产品,因为我们不知道它是使用equals()
方法还是其他方法。您应该直接使用deleteById()crudepository
crudepository
中定义的方法是一个crudepository
。delete(T实体)
方法接受类型为T
的参数,在这种情况下,Product
,它可能会使用Product.equals()
方法检查要删除的产品是否正确。如果未覆盖此方法,默认情况下,内存中对象引用的地址用于比较,这是唯一的。因此,我们使用deleteById(ID ID)
,在这种情况下,它接受Long
。
productRepository.delete(productId);
@Service
public class ProductService {
@Autowired
ProductRepository repo;
public void deleteProductById(Long id) {
System.out.println("Deleting product with id: " + id);
// USE deleteById(Long id) and directly pass the id
// Defined in CrudRepository
repo.deleteById(id);
// DON'T use delete() and pass a product
//repo.delete(product);
}
}