Spring Data JPA Many to Many with extra column Use

2019-08-25 18:38发布

问题:

I want to use many-to-many relationships using spring boot JPA between User and Role entity.

I was able to achieve this using code below BUT in my requirement, I need one extra column in the pivot table(users_to_role).

@ManyToMany
@JoinTable(
        name = "users_to_roles",
        joinColumns = @JoinColumn(
                name = "user_id", referencedColumnName = "id"),
        inverseJoinColumns = @JoinColumn(
                name = "role_id", referencedColumnName = "id"))
private List<Role> roles;

Here is my new code

User.java

@Entity
@Table(name = "users")
public class User {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;

   private String username;

   @OneToMany(mappedBy="users", cascade = CascadeType.ALL)
   private List<Role> roles;

   //getters and setters here
}

Role.java

@Entity
@Table(name = "roles")
public class Role {

   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;

   private String name;

   @OneToMany(mappedBy="roles", cascade = CascadeType.ALL)
   private List<User> users;

   //getters and setters here
}

UserRole.java

@Entity
@Table(name = "users_to_role")
public class UserRole {

   @Id
   @ManyToOne
   @JoinColumn(name = "user_id")
   private User user;

   @Id
   @ManyToOne
   @JoinColumn(name = "role_id")
   private Role role;

   private Date createdAt;

  //getters and setters here
}

Could someone help me to point out what I am doing wrong?

Here is error stack:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Illegal use of mappedBy on both sides of the relationship: com.example.entities.Role.users

回答1:

It is because in your User Entity in @OneToMany you are specifying mappedBy as users while in your UserRole Entity , User Entity is represented by the object user (not users). Similar is the case with Role Entity.

Just synchronize the value in mappedBy attribute with name of objects you are mentioning in UserRole .

Secondly in both User and Role Entities you should have List<UserRole> (not the list of User or Role)because you will have foreign key in users_to_role table.

The following change will work

User.java

@OneToMany(mappedBy="user", cascade = CascadeType.ALL)
private List<UserRole> roles;

Role.java

@OneToMany(mappedBy="role", cascade = CascadeType.ALL)
private List<UserRole> users;

UserRole.java

public class UserRole implements Serializable {}