Reputation: 1050
I have three tables - role
, user
, and user_role
. This is supposed to be ManyToMany
but since I also want to generate id for the user_role
, I used OneToMany
and ManyToOne
.
Here are my entities with relevant fields only:
@Entity
public class Role {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "role")
private Set<UserRole> userRoles;
}
@Entity
public class User {
@Id
private String id;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user")
private Set<UserRole> userRoles;
}
@Entity
public class UserRole {
@Id
private String id;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
@ManyToOne
@JoinColumn(name = "role_id")
private Role role;
}
Then, this is how I create instances of them and save to the DB:
// Retrieve from DB by ID
Role role = ...;
// ID String is generated from UUID
User user = new User();
user.id("abc");
// ID String is generated from UUID
UserRole userRole = new UserRole();
userRole.setId("xyz");
Set<UserRole> userRoles = Set.of(userRole);
role.setUserRoles(userRoles);
user.setUserRoles(userRoles);
userRole.setUser(user);
userRole.setRole(role);
userRepository.save(user);
The issue that I find it difficult to resolve no matter how I have tried and googled:
2020-09-27 23:41:58.917 WARN 21948 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find com.example.entity.UserRole with id xyz; nested exception is javax.persistence.EntityNotFoundException: Unable to find com.example.entity.UserRole with id xyz]
Please help me. Thanks.
Upvotes: 5
Views: 8642
Reputation:
Stern has good point. You are trying to save only user
entity, but you don't have any cascade set anywhere. So when you call userRepository.save(user)
it is obviously missing role entities. Either save dependent entities before saving user
, or better, add cascade above userRoles
field in your User class etc.
Upvotes: 3
Reputation: 12205
As mentioned elsewhere you need to se minimum:
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user" , cascade = CascadeType.ALL)
private Set<UserRole> userRoles;
or minimum:
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user" , cascade =
CascadeType.PERSIST)
private Set<UserRole> userRoles;
But also if you need to fetch UserRoles
by User
you need to set:
// for each UserRole in the list.
userRole.setUser(user);
before persisting otherwise list will not be populated.
Upvotes: 5