jpaRepository delete()或deleteById()不起作用,springBoot

u5rb5r59  于 2023-11-17  发布在  Spring
关注(0)|答案(3)|浏览(408)

我需要删除一个Archivo记录,我有下一个案例。我有问题删除使用detele()和deleteById()的代码是什么也不做。
下一个是主代码:

  1. @Override
  2. public RespuestaVo delete(Integer archId) {
  3. RespuestaVo respuestaVo = new RespuestaVo();
  4. try {
  5. if (!validarArchivoDeUsuario(archId)){
  6. respuestaVo = new RespuestaVo(401, HttpStatus.UNAUTHORIZED, "Acceso a recursos no autorizado.");
  7. return respuestaVo;
  8. }
  9. respuestaVo = new RespuestaVo(201, HttpStatus.OK, "El archivo ha sido eliminado con éxito.");
  10. iArchivosDao.deleteById(archId);
  11. } catch (Exception ex) {
  12. respuestaVo = new RespuestaVo(400, HttpStatus.BAD_REQUEST, "No ha sido posible eliminar el archivo, inténtelo más tarde.");
  13. Logger.getLogger(LogosEmprendimientosServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
  14. }
  15. return respuestaVo;
  16. }

字符串
这段代码使用了一个叫做“validarArchivoDealliario()”的方法,它只是用来验证用户是否收到了归档文件。这个方法做了它必须做的事情。

  1. private boolean validarArchivoDeUsuario(int archId) {
  2. Personas persona = new Personas();
  3. persona = jwtProvider.getUserID();
  4. List<Emprendimientos> emprendimientos;
  5. emprendimientos = iEmprendimientosDao.findByPersIdAndEmprEstado(persona, ACTIVO);
  6. for (Emprendimientos emprendimiento: emprendimientos){
  7. for (Archivos archivo: emprendimiento.getArchivosCollection()){
  8. if (archivo.getArchId().equals(Integer.valueOf(archId))){
  9. return true;
  10. }
  11. }
  12. }
  13. return false;
  14. }


如果我像现在这样使用代码,它会转到验证,然后转到iArchivosDao.deleteById(archId);行,但它不会做任何事情。
但是如果我在validarArchivoDealliario中注解“for”,并像下一个代码一样硬编码返回true。它也会转到iArchivosDao.deleteById(archId);行,但在这种情况下,它会删除记录:
log:org.hibernate.SQL:delete from archivos where arch_id=?Hibernate:delete from archivos where arch_id=?

  1. private boolean validarArchivoDeUsuario(int archId) {
  2. Personas persona = new Personas();
  3. persona = jwtProvider.getUserID();
  4. List<Emprendimientos> emprendimientos;
  5. emprendimientos = iEmprendimientosDao.findByPersIdAndEmprEstado(persona, ACTIVO);
  6. /*for (Emprendimientos emprendimiento: emprendimientos){
  7. for (Archivos archivo: emprendimiento.getArchivosCollection()){
  8. if (archivo.getArchId().equals(Integer.valueOf(archId))){
  9. return true;
  10. }
  11. }
  12. }*/
  13. return true;
  14. }


看起来像一些在这里影响删除.我尝试设置emprendimientos,archivo,emprendimiento为null之前返回true,但没有工作
Emprendimientos.java网站...

  1. @OneToMany(cascade = CascadeType.ALL, mappedBy = "emprId")
  2. private Collection<Archivos> archivosCollection;


...
Archivos.java网站...

  1. @Entity
  2. @Table(name = "ARCHIVOS")
  3. @Data
  4. public class Archivos {
  5. ...
  6. @JsonBackReference("emprId-Archivo")
  7. @JoinColumn(name = "EMPR_ID", referencedColumnName = "EMPR_ID")
  8. @ManyToOne(optional = false)
  9. priva


te Emprendimientos emprId;
...
谢谢你的健康!

0wi1tuuw

0wi1tuuw1#

看起来这个问题可能与Sping Boot 应用程序中JPA实体和关联关系的Map方式有关。当您在validarArchivoDealliario方法中取消注解for循环时,可能会加载关联的实体和关系,并且删除操作按预期工作。
尝试将@ transmitting注解应用到delete方法中

  1. @Transactional
  2. public RespuestaVo delete(Integer archId) {
  3. RespuestaVo respuestaVo = new RespuestaVo();
  4. try {
  5. // ... Add your existing code ...
  6. respuestaVo = new RespuestaVo(201, HttpStatus.OK, "El archivo ha sido eliminado con éxito.");
  7. iArchivosDao.deleteById(archId);
  8. } catch (Exception ex) {
  9. // ... your existing error handling ...
  10. }
  11. return respuestaVo;
  12. }

字符串

展开查看全部
niknxzdl

niknxzdl2#

对我来说,它看起来像,for循环无法找到记录,也无法删除它。请尝试以下操作:

  1. for (Emprendimientos emprendimiento: emprendimientos) {
  2. for (Archivos archivo: emprendimiento.getArchivosCollection()) {
  3. if (archivo.getArchId().equals(Integer.valueOf(archId))) {
  4. // Check if the record exists
  5. if (iArchivosDao.findById(archId).isPresent()) {
  6. // Delete the record
  7. iArchivosDao.deleteById(archId);
  8. return true;
  9. } else {
  10. // The record does not exist
  11. return false;
  12. }
  13. }
  14. }
  15. }

字符串
不要忘记**@ translation**注解,因为您正在修改数据库。

展开查看全部
z9gpfhce

z9gpfhce3#

问题在于archivosCollectionMap上的级联选项,特别是级联PERSIST(包含在CascadeType.ALL中)。您正在删除Archivos的示例,但在同一个持久化单元中保留了一个仍然引用该示例的Emprendimientos示例。JPA将处理您的删除请求,但在检查托管的Emprendimientos示例时,JPA将找到相同的引用,并需要将其持久化回去,撤消删除操作。
在删除之前,你应该先删除this和任何其他对此Archivos的引用。如果你不这样做,你可能会在奇怪的时候发现类似的行为,这样做会给予你的应用程序一个机会和位置,在以后实现缓存时,把回调放到清除缓存中。
您已经有了一个解决方案-通过直接调用本机查询,您将直接向数据库强制执行delete语句。尽管如此,JPA仍然会相信它在该高速缓存中的Archivos存在,并且不会尝试重新插入它-无论如何,现在是这样。您需要确保在提交后清除Emprendimientos的任何缓存示例并从数据库中重新读取,否则您可能会重新读取过时的数据。稍后插入。
或者,您可以从关系中删除cascadeType.PERSIST:

  1. @OneToMany(cascade = CascadeType.DELETE, mappedBy = "emprId")
  2. private Collection<Archivos> archivosCollection;

字符串
只在你确定必须使用级联操作的地方使用级联操作--在大多数情况下,手动创建一个archivosCollection.forEach(arch -> em.persist(arch));要比不使用级联操作容易得多。
第三个选项,我在大多数情况下都推荐的选项,是维护双向关系。由于要删除Archivos,因此应该清除对它的任何引用。有时出于性能原因,不这样做;默认的方法可能是调用

  1. if (null != archivos.emprId) {
  2. archivos.emprId.archivosCollection.remove(archivos);
  3. }


如果所有内容都还没有加载,可能会强制执行一系列SQL查询。这可以通过使用isLoaded检查来检查关系是否已经加载来调节:

  1. if (null != archivos.emprId) {
  2. if (Persistence.getPersistenceUtil().isLoaded(archivos.emprId, "archivosCollection") ) {
  3. archivos.emprId.archivosCollection.remove(archivos);
  4. }
  5. }

展开查看全部

相关问题