I have two tables USERS and FILES. I want to be able to control the users that can download a file, and for this I was thinking of creating and intermediary table FILE_PERMISSIONS with a user_id and a file_id.
Looking at database level I understand how can I solve the problem, but going up at Hibernate level, I can't really understand how should I map this relation. The way I see it is something like this:
public class User {
private Integer userId;
}
public class File {
private Integer fileId;
private List<Integer> userIds;
}
So I want my File object to know the id property of all the users that can download the file, but not vice versa, so that a user doesn't know about those files.
From what I read I can use a many to many unidirectional relation but I'm not sure that I can only have the id of the user, and not the user object itself.
You can manage it having the following structure.
User:
@Entity
public class User {
@Id
private Integer userId;
// getters, setters
}
File:
@Entity
public class File {
@Id
private Integer fileId;
@ManyToMany
@JoinTable(
name = "file_permissions",
joinColumns = @JoinColumn(name = "file_id"),
inverseJoinColumns = @JoinColumn(name = "user_id")
)
private Set<User> users;
// getters, setters
}
You can benefit from making an easier design using @OneToMany relationship instead. This way you could create a service in order to manage File permissions, instead of relying on user service or file services to do so.
I propose something like:
User.java
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Version
private Integer version;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval = true)
private List<FilePermissions> filePermissionsList= new ArrayList<>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public List<FilePermissions> getFilePermissionsList() {
return filePermissionsList;
}
public void setFilePermissionsList(List<FilePermissions> filePermissionsList) {
this.filePermissionsList = filePermissionsList;
}
}
Notice User has a list of FilePermissions.
Your FilePermission class should be like:
@Entity
public class FilePermissions {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Version
private Integer version;
@ManyToOne
private User user;
@OneToOne
private File file;
private Permission permission;
public FilePermissions() {
}
public FilePermissions(User user, File file, Permission permission) {
this.user = user;
this.file = file;
this.permission = permission;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public Permission getPermission() {
return permission;
}
public void setPermission(Permission permission) {
this.permission = permission;
}
}
Notice the @ManytoOne relationship back to the user, as well as the @OneToOne relationship to the File class. Here you can store the detail on what permission user have, in this case i have a enumeration.
Your File class is straight forward:
@Entity
public class File {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Version
private Integer version;
private String name;
public File() {}
public File(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
You can see solution in detail here: https://github.com/ccoloradoc/HibernateFilePermissionSample
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.