I have two tables with foreign key relations. I\'ve tried searching on how to do it and it always leads to OneToMany & ManyToOne mapping. I have these two tables.
<You have to annotate the Java fields not the getter like:
@OneToMany(targetEntity=User.class, mappedBy="userRole",cascade=CascadeType.ALL, fetch = FetchType.LAZY)
private List<User> user;
and for User.class
@ManyToOne
@JoinColumn(name="role_id")
private UserRole userRole;
In addition, do you have defined the role_id
column in the user
table? I can't see this in the screenshot
I can re-create your exception by mixing my annotation mapping between fields and properties. I see in the problem you described above you annotate the field Id, but then annotate the property userRole, if I do the same I get the same error. I can fix the error by either annotating just properties or fields. Both these models work:
@Entity
@Table(name = "USER")
public class User {
private Long id;
private UserRole userRole;
String userName;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Column(name = "USER_NAME")
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@ManyToOne()
@JoinColumn(name="role_id")
public UserRole getUserRole() {
return userRole;
}
public void setUserRole(UserRole userRole) {
this.userRole = userRole;
}
}
This also works:
@Entity
@Table(name = "USER")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne()
@JoinColumn(name="role_id")
private UserRole userRole;
@Column(name = "USER_NAME")
String userName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public UserRole getUserRole() {
return userRole;
}
public void setUserRole(UserRole userRole) {
this.userRole = userRole;
}
}
Example of the other model object annotating the fields
@Entity
@Table(name = "USER")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne()
@JoinColumn(name="role_id")
private UserRole userRole;
@Column(name = "USER_NAME")
String userName;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public UserRole getUserRole() {
return userRole;
}
public void setUserRole(UserRole userRole) {
this.userRole = userRole;
}
}
Test Code (I added this because there is often confusion that one must set the bidirectional relationship in order to get both users and userRole to persist with a save to the UserRole).
List<User> users = new ArrayList<>();
User user1 = new User();
user1.setUserName("user1");
users.add(user1);
User user2 = new User();
user2.setUserName("user2");
users.add(user2);
UserRole userRole = new UserRole();
userRole.setRoleName("admin");
//Unidirectional relationship
user1.setUserRole(userRole);
user2.setUserRole(userRole);
//set Bidirectional relationship
userRole.setUsers(users);
userRole = userRoleRepository.save(userRole);
//Show that the two users and the UserRole persisted
UserRole result = userRoleRepository.findById(userRole.getId()).get();
assertEquals(2, result.getUsers().size());
Can you move the relationship to a related object like this
@ManyToOne()
@JoinColumn(name="role_id", referencedColumnName = "role_id", insertable = false, updatable = false)
private UserRole userRole;
and same do for userRole
@OneToMany(targetEntity=User.class, mappedBy="userRole",cascade=CascadeType.ALL, fetch = FetchType.LAZY)
private List<User> user = new ArrayList<>();
Update
The jar file seems to be corrupted. Try removing the content from the .m2\repository and mvn clean install
OR
Right-click your project, select Maven, Update Project, check on Force Update of Snapshots/Releases.
Just a hint, check your entity classes and ensure you have included @Entity annotation just before the class declaration statement.
@Entity
public class MyEntityClass{
//code
}
Then on any other entity class that uses MyEntityClass above under the @ManyToMany or @OneToMany relationship add the following.
@OneToMany(mappedBy="mappingItem", cascade=CascadeType.ALL, orphanRemoval=true)
@JsonIgnore
private List<MyEntityClass> myEntityClassItemList;
This approach worked for me some how, may be it might help.