Spring Boot JPA,存储库不删除记录

Posted

技术标签:

【中文标题】Spring Boot JPA,存储库不删除记录【英文标题】:Spring Boot JPA, Repository don't delete record 【发布时间】:2020-01-21 14:31:32 【问题描述】:

我在 REST 控制器 (UserOfferController) 中创建方法 (acceptUseroffermapping),我想在其中删除数据库 (UserOfferMapping 表) 中的记录。但是问题是我运行这个方法后记录没有被删除并且关系也被保存了。

我还有 UserOfferMapping 类映射到 User 类。在UserOfferController 中,我使用UserOfferMapping 进行操作:创建、从数据库中选择记录并尝试删除记录但失败了。

UserOfferController.java:

/*...*/
    @POST
    @RequestMapping("/acceptUserOfferMapping")
    public void acceptUseroffermapping(@RequestBody Map<String,
            String> body) throws ParseException 

        String userId = body.get("userId");
        String offerId = body.get("offerId");

        Optional<User> user = userRepository.findById(Integer.parseInt(userId));

        UserOfferMapping mapping = userOfferMappingRepository.getById(Integer.parseInt(userId));
        user.get().getUserOfferMapping().remove(mapping);
        userRepository.save(user.get());
        userOfferMappingRepository.deleteById(Integer.parseInt(offerId));
    
/*...*/

用户.java:

/*some imports*/

@Entity
@Table(name = "User")
@JsonIgnoreProperties("hibernateLazyInitializer", "handler")
public class User 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private int id;
/* ...
 * a lot of fields
 * ...
 */
    // Important section which describes all Role Project and Skill mapping
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    private Set<UserUserrolemapping> userrolemapings = new HashSet<>();

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    private Set<Userprojectmapping> userprojectmappings = new HashSet<>();

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    private Set<UserOfferMapping> userOfferMapping = new HashSet<>();

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    @OrderBy
    private Set<Userskillmapping> userskillmappings = new HashSet<>();

 /* ...
  *  a lot of fields too
  * ...
  */

  /* getter and setters */


UserOfferMappingRepository.java:

public interface UserOfferMappingRepository extends JpaRepository<UserOfferMapping, Integer> 
    public List<UserOfferMapping> getAllByUser(Optional<User> user);

    public UserOfferMapping getUserOfferMappingByUserAndProjectAndUserRole(User user, Userproject userproject, Userrole userrole);

    public UserOfferMapping getById(int id);

    public void deleteById(int id);

UserOfferMapping.java:

@Entity
public class UserOfferMapping 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @ManyToOne
    @JoinColumn(name = "userid")
    @JsonBackReference
    private User user;

    @ManyToOne
    @JoinColumn(name = "roleid")
    private Userrole userRole;

    @ManyToOne
    @JoinColumn(name = "projectid")
    private Userproject project;
    @Column(name = "fromdate", nullable = true)
    private Date fromdate;
    @Column(name = "todate", nullable = true)
    private Date todate;

    @Column(name = "chance")
    private int chance;
    @Column(name = "percent")
    private int percent;

    public int getId() 
        return id;
    

    public User getUser() 
        return user;
    

    public Userrole getUserRole() 
        return userRole;
    

    public Userproject getProject() 
        return project;
    

    public Date getFromdate() 
        return fromdate;
    

    public int getChance() 
        return chance;
    

    public int getPercent() 
        return percent;
    

    public void setId(int id) 
        this.id = id;
    

    public void setUser(User user) 
        this.user = user;
    

    public void setUserRole(Userrole userRole) 
        this.userRole = userRole;
    

    public void setProject(Userproject project) 
        this.project = project;
    

    public void setFromdate(Date fromdate) 
        this.fromdate = fromdate;
    

    public void setChance(int chance) 
        this.chance = chance;
    

    public void setPercent(int percent) 
        this.percent = percent;
    

    public void setTodate(Date todate) 
        this.todate = todate;
    

    public Date getTodate() 
        return todate;
    


【问题讨论】:

请提供UserOfferMapping的代码。 @Woland 好的,将其添加到问题中 【参考方案1】:

你可以试试这个


  public interface UserOfferMappingRepository extends JpaRepository<UserOfferMapping, Integer> 
    public List<UserOfferMapping> getAllByUser(Optional<User> user);

    public UserOfferMapping getUserOfferMappingByUserAndProjectAndUserRole(User user, Userproject userproject, Userrole userrole);

    public UserOfferMapping getById(int id);

   // public void deleteById(int id);

   @Modifying(clearAutomatically = true)
  @Query(value = "Delete from UserOfferMapping c WHERE c.id=:id")
  public void deleteById(@Param("id") int id);

【讨论】:

欢迎你,亲爱的【参考方案2】:

因此,您具有双向实体关联。 尝试在userRepository.save之前添加mapping.setUser(null);

【讨论】:

哦,没用(【参考方案3】:

持久化和删除对象需要 JPA 中的事务,因此您必须在 Repository 中的方法之前定义 @Transactional 注释,例如 `

@Transactional
 public void deleteById(@Param("id") int id);

【讨论】:

以上是关于Spring Boot JPA,存储库不删除记录的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot JPA+Hibernate 在 SaveAll() 上的低性能

基于Spring Boot,使用JPA动态调用Sql查询数据

使用spring data jpa删除数据库记录时出错

如何在 Spring Boot 中从应用程序属性文件中读取 jpa 命名查询?

Spring Boot JPA Hibernate - 以毫秒精度存储日期

Spring Boot JPA 存储库查询