many-to-many-relationship between two entities in spring boot - java

I have two Entities in my Spring-Boot Application:
User.java
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Long id;
String firstname;
String lastname;
String username;
String password;
}
and
Role.java
Entity
#Table(name = "role")
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
Long id;
String name;
String description;
}
for my MySql database
I have excluded the getter and setter methods for this question.
I want to realise a Many-to-Many-Relationship between both Entities. Every user should be able to assign multiple roles to himself
I already Created a mapping table for both tables in my database. It has the rows
user_id
role_id.
I also created a new Entity UserRole.java which looks like this:
#Entity
#Table(name = "user_role")
public class UserRole implements Serializable{
private User user;
private Role role;
#Id
#ManyToOne
#JoinColumn(name = "user_id")
public User getuser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
#Id
#ManyToOne
#JoinColumn(name = "role_id")
public Role getrole(){
return role;
}
public void setRole(Role role){
this.role = role;
}
}
Now my question: is this construction correct? If yes, how do i add existing roles to an existing user and get the roles of this user in spring-boot?

You can find any tutorial connected with many-to-many relationship using Hibernate/Spring Data, example:
Spring Data many-to-many
With your model it's simple to add the relationship mappings, like this:
#Entity
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String description;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable
private Set<User> users;
}
and this:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstname;
private String lastname;
private String username;
private String password;
#ManyToMany(mappedBy = "users")
private Set<Role> roles;
}

Related

Why JpaRepository<User, Long> returns null value

I have a Spring Boot project, in which I have problem with JpaRepository<User,Long>.
I defined following interface
public interface UserDAO extends JpaRepository<User, Long> {
User findByEmail(String email);
}
which was implemented in UserServiceImpl
#Override
public User findByEmail(String email) {
return userDAO.findByEmail(email);
}
and I need it in UserDetailsServiceImpl but next line
User user = userDAO.findByEmail(email);
returns null.
My model classes:
User
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private long id;
#Column(name = "email")
private String email;
#Column(name = "login")
private String login;
#Column(name = "password")
private String password;
#ManyToMany
#JoinTable(name = "user_roles",
joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> roles;
#Transient
private String confirmPassword;
//getters-setters
}
Role
#Entity
#Table(name = "roles")
public class Role implements GrantedAuthority {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "name")
private String name;
#ManyToMany(mappedBy = "roles")
private Set<User> users;
What can I do?
You need to follow JavaBean specification for entity(you need to have default contrucor and getters and setters in User and Role)
Try to use the annotations on the getter, not the fields.

Hibernate One to One, not generating Foreign key

I have 4 tables here: Register, User, User roles and User Profile Image
Register and User are mapped my a One to One relationship and a reference of Register is generated in Users table...... This is fine..
Now talking about One to Many Relation between User and the Roles table, it also works perfectly by generating a User table reference in the roles table..
But problem is when working with One to One between User and the Profile Image. Profile Image is not generating reference of User....Why the user reference is not generated in Profile Image table
Register
#Entity
#Getter
#Setter
public class Register {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#OneToOne(cascade = CascadeType.ALL,orphanRemoval = true,mappedBy = "register")
private User user;
}
User
#Entity
#Getter
#Setter
public class User {
#Id
#Column(name = "User_Id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#OneToOne(cascade = CascadeType.ALL,fetch=FetchType.EAGER)
#JoinColumn(name = "user_id")
private UserProfileImage userProfileImage;
#OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
#JoinColumn(name = "user_id")
private List<UserRoles> userRoles;
}
User Profile Image
#Entity
#Getter
#Setter
public class UserProfileImage {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "name")
private String name;
#Column(name = "type")
private String type;
#Column(name = "picByte", length = 100000)
private byte[] picByte;
public UserProfileImage() {
super();
}
public UserProfileImage(String name, String type, byte[] picByte) {
this.name = name;
this.type = type;
this.picByte = picByte;
}
}
Profile mapping in User class is not correct and in your profile class there is no user field and hence it's not generating the user reference in the profile class.
Also, User to Roles mapping is also not correct, your user class will not populate roles with your mappings.
Try this:
public class User {
...
#OneToOne(cascade = CascadeType.ALL,fetch=FetchType.EAGER)
#JoinColumn(name = "PROFILE_IMAGE_ID") // foreign key column in User table
private UserProfileImage userProfileImage;
#OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER,mappedBy="user")
private List<UserRoles> userRoles;
}
public class UserProfileImage {
...
#OneToOne(mappedBy="userProfileImage")
private User user;
...
}
public class UserRole {
...
#ManyToOne
#JoinColumn(name="USER_ID") // foreign key column in User Role table
private User user;
...
}

Attribute many ids to single from other tables JPA

I want to create entity USERS_GROUP to link some user_ids to group_id.
I guess I overthink this case and now I can't find a solution.
#Entity
#Table(name = "users")
#Data
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id")
private String userId;
private String name;
#OneToMany(mappedBy = "user")
private List<UserGroups> userGroups;
#Table(name = "groups")
#Data
public class Group {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "group_id")
private String groupId;
private String category;
private String name;
private String description;
#OneToMany(mappedBy = "group")
private List<UserGroups> userGroups;
#Entity
#Data
#Table(name = "user_groups")
public class UserGroups {
#EmbeddedId
UserGroupsCompositeKey id;
#ManyToOne
#MapsId("userId")
#JoinColumn(name = "user_id")
private Users user;
#ManyToOne
#MapsId("featureId")
#JoinColumn(name = "group_id")
private Group group;
#Embeddable
public class UserGroupsCompositeKey implements Serializable {
#Column(name = "user_id")
String userId;
#Column(name = "group_id")
String groupId;
}
I want to sent POST requests like "/group/{group_id}/users"
to send in request body some lists of user_ids to connect them.
I think I overconfigured this solution with a composite key.
Is there some easier and more readable solution for that case ?
EDIT: This solution is not working as I want it to do.
I create jpaRepository class with CompositeKey (Not sure if it's correct way )
#Repository
public interface ProductFeaturesRepository extends JpaRepository<UserGroups, UserGroupsCompositeKey> {
}
And I want to add some Controller method to group class to add some users to group with request body like:
Endpoint:/group/{group_id}/users
Body:
[
{
"userId": "USER-NR423423534634"
},
{
"userId": "USER-NR2355321"
}
]
It's not working properly nothing is added to database after that request

#ManyToOne and #OneToMany in Hibernate causing default value error

I'm trying to use a foreign key in Hibernate/Spring Boot with the #OneToMany and #ManyToOne annotations, but I keep getting this error:
java.sql.SQLException: Field 'note_id' doesn't have a default value
My code:
Note.java
#Entity
#Table(name = "notes")
#EntityListeners(AuditingEntityListener.class)
public class Note {
public Note() {
}
public Note(String name, String content) {
this.name = name;
this.content = content;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "note_id")
private Integer id;
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
#NotBlank
private String name;
#NotBlank
#Column(columnDefinition="LONGTEXT")
private String content;
User.java
#Entity
#Table(name = "user")
#EntityListeners(AuditingEntityListener.class)
public class User implements Serializable {
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id")
private Integer id;
#OneToMany(mappedBy = "user", cascade = ALL)
private Set<Note> notes;
#NotEmpty
#Column(nullable = false, unique = true)
private String username;
#NotEmpty
private String password;
The error occurs whenever I try to create a note.
Thanks in advance!

JPA retrieve entities relationships

I am trying to retrieve the list of all entities containing relations that references the specified entity.
"Role" Entity :
#Entity
#Table(name="Role")
#Access(AccessType.PROPERTY)
public class Role implements Serializable {
private String description;
private Long roleId;
#Column(name = "role_id")
#Id
public Long getRoleId() {}
#Column(name = "description")
public String getDescrition() {}
}
"User" Entity :
#Entity
#Table(name="users")
#Access(AccessType.PROPERTY)
public class User implements Serializable {
private Long userId;
private String name;
private Role role;
#Column(name = "user_id")
#Id
public Long getUserId() {}
#ManyToOne()
JoinColumn(name="role_id")
public Role getRole() {}
public String getName() {}
}
"Group" Entity :
#Entity
#Table(name="groups")
#Access(AccessType.PROPERTY)
public class User implements Serializable {
private Long groupId;
private String description;
private Role role;
#Column(name = "group_id")
#Id
public Long getGroupId() {}
#ManyToOne()
JoinColumn(name="role_id")
public Role getRole() {}
public String getDescription() {}
}
I need a that works like this :
List<Class<?>> entities = getEntityReferences(Role.class);
foreach (Class<?> entity : entities )
System.out.println(entity.getName());
The output would be :
User
Group
I think JPA use something like this for the bean validations or cascade mechanics but I can't find a simple way to achieve this.
The only way I found by now is to iterate through all the annotations of all the entities (returned by "entityManagerFactory.getMetamodel().getEntities()") to look for relations (ManyToOne, OneToOne ect.). It seems a bit tedious, I'm sure there's a better way to do it...
Thank you all...

Categories

Resources