Java 将实体保存在SpringDataJPA中,其中包含另一种实体类型的列表

Java 将实体保存在SpringDataJPA中,其中包含另一种实体类型的列表,java,mysql,spring,hibernate,spring-data-jpa,Java,Mysql,Spring,Hibernate,Spring Data Jpa,伙计们,我刚到春天,所以请容忍我。 我有两个实体。用户和类型。 用户实体包含类型实体的列表。i、 e.“用户有风格” (“流派有用户”不是我的要求。) 我的两个实体 @Entity @Table(name = "user") @Getter @Setter @AllArgsConstructor @NoArgsConstructor @ToString public class User { @Id @GeneratedValue private in

伙计们,我刚到春天,所以请容忍我。 我有两个实体。用户和类型。 用户实体包含类型实体的列表。i、 e.“用户有风格” (“流派有用户”不是我的要求。)

我的两个实体

@Entity
@Table(name = "user")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {
    @Id
    @GeneratedValue
    private int id;
    private String username;
    private String userEmail;
    private String firstName;
    private String lastName;
    private String imgUrl;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "user_genres", joinColumns = @JoinColumn(name = "User_id"), inverseJoinColumns = @JoinColumn(name = "genres_id"))
    private List<Genre> genres;
  
}
这是我用来保存我的用户记录的请求正文

{
   "username":"test username",
   "userEmail":"test@gmail.com",
   "firstName":"test fname",
   "lastName":"test lname",
   "imgUrl":"url",
   "genres":[
      {
         "id":8,
         "name":"Drama"
      }
   ]
}
我保存了一个流派表。当我想保存一个用户时,我从表中选择一些类型,将它们保存在用户实体的列表中,并将它们发送到save()。我的期望是使用user\u id和genre\u id将这些关系保存在user\u genres表中

我的问题是,当我试图用流派对象保存用户时,如果已经有一个用户的流派对象id与我试图保存的用户中的相同,则会出现一个异常,表明流派id已经存在。

i、 假设我已经有一个用户,其中包含一个id为8的类型。现在我正在发送一个新用户,这意味着有一个新的用户id,它也包含一个id为8的类型。然后它会给我一个例外


SQLIntegrityConstraintViolationException:键“UK_1ro2jvu91tg2xsrdye9sk9j1q”的重复条目“8”

如果我使用不同id的不同类型,这很好。请告诉我获得预期结果的方法。谢谢

我的存储库

public interface UserRepository extends JpaRepository<User, Integer> {}
我的控制器

@Autowired
    UserServiceImpl userService;


    @PostMapping("/users")
    public ResponseEntity save(@RequestBody User user) {

        return userService.save(user);
    }
更新: 级联类型更改为合并 在用户方面

在体裁上

@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Genre)) return false;
        Genre genre = (Genre) o;
        return Objects.equals(getId(), genre.getId());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId());
    }

步骤1

根据用户和流派的Id字段,为它们创建
hashcode()
equals()
方法

步骤2

 @ManyToMany(fetch = FetchType.LAZY, cascade=CascadeType.MERGE)
 @JoinTable(name = "user_genres", joinColumns = @JoinColumn(name = "User_id"), 
 inverseJoinColumns = @JoinColumn(name = "genres_id"))
    private List<Genre> genres;
@ManyToMany(fetch=FetchType.LAZY,cascade=CascadeType.MERGE)
@JoinTable(name=“user\u genres”,joinColumns=@JoinColumn(name=“user\u id”),
inverseJoinColumns=@JoinColumn(name=“genres\u id”))
私人列表体裁;

现在你应该准备好出发了。

嘿,谢谢你的回复。我完成了上述两个步骤。在user中,我重写了equals和hashcode方法。请参阅更新。我添加了合并级联类型。但我还是得到了同样的例外,我也为《Genrey》做了同样的事情,你必须对基于我所做的田园诗的类型使用覆盖。当我更改cascade=CascadeType.ALL时,我会将其添加到更新中,我获得了
PersistentObjectException:传递给persistent的分离实体:
我将使用保存函数SQLIntegrityConstraintViolationException更新代码:“UK_1ro2jvu91tg2xsrdye9sk9j1q”键的重复条目“8”。对我来说,此错误意味着在用户类型中已经有一个值为UK_1ro2jvu91tg2xsrdye9sk9j1q的用户id。。您能否显示正在传递到REST端点的用户的有效负载?我想你可能使用了相同的用户id。只是thought@SusanMustafa谢谢你的评论。我已经发布了我发送的有效负载,以在问题详细信息中保存用户。实际上,用户id是整数,它是自动生成的。因此,“UK_1ro2jvu91tg2xsrdye9sk9j1q”不能是用户id。“重复条目“8”来自我在用户实体中传递的类型对象。而且我希望在user\u genres表中有多个具有相同user\u id的记录。因为我正在将多个用户映射到多个类型。您是否自己创建表?还是通过JPA完成的所有事情?我问的原因是,你的约束可能是错误的。列类型id可以设置为唯一约束,而不是JPA创建的(用户id和类型id)表的组合。但是在读了你的评论之后,我才意识到,即使我做了Boug建议的更改,我也没有放弃我以前的模式!!现在我放弃了我的模式并重新启动了服务。现在它工作得很好!谢谢你@SusanMustafay欢迎你
 @ManyToMany(fetch = FetchType.LAZY, cascade=CascadeType.MERGE)
 @JoinTable(name = "user_genres", joinColumns = @JoinColumn(name = "User_id"), 
 inverseJoinColumns = @JoinColumn(name = "genres_id"))
    private List<Genre> genres;
@Override

    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof User)) return false;
        User user = (User) o;
        return Objects.equals(getId(), user.getId());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId());
    
}
@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Genre)) return false;
        Genre genre = (Genre) o;
        return Objects.equals(getId(), genre.getId());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId());
    }
 @ManyToMany(fetch = FetchType.LAZY, cascade=CascadeType.MERGE)
 @JoinTable(name = "user_genres", joinColumns = @JoinColumn(name = "User_id"), 
 inverseJoinColumns = @JoinColumn(name = "genres_id"))
    private List<Genre> genres;