2017-03-12 142 views
0

我有两个表USERS和FILES。我希望能够控制可以下载文件的用户,为此,我正在考虑使用user_id和file_id创建中间表FILE_PERMISSIONS。休眠多对多单向映射

看着数据库级别我明白我该如何解决这个问题,但是在Hibernate级别上,我无法真正理解我该如何映射这个关系。我看到它的方式是这样的:

public class User { 
    private Integer userId; 
} 

public class File { 
    private Integer fileId; 
    private List<Integer> userIds; 
} 

所以我想我的File对象知道所有可以下载该文件的用户的id属性,而不是相反,让用户不用了解这些文件。

从我读到的,我可以使用多对多的单向关系,但我不知道我只能拥有用户的id,而不是用户对象本身。

回答

1

您可以管理它,具有以下结构。

用户:

@Entity 
public class User { 
    @Id 
    private Integer userId; 

    // getters, setters 
} 

文件:

@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 
} 
+0

你真的要更新用户领域,保存文件中创建新用户? –

+0

要更改此行为,您可以使用'@ JoinColumn'注释的'insertable'和'updatable'标志进行操作。 –

+0

只需删除'cascade'。这就够了。 –

1

您可以使用@OneToMany关系而不是让一个更简单的设计中获益。通过这种方式,您可以创建服务来管理文件权限,而不是依赖用户服务或文件服务来执行此操作。

我建议是这样的:

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; 
    } 
} 

通知用户有FilePermissions的列表。

你的FilePermission类应该是这样的:

@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; 
    } 
} 

通知的@ManyToOne关系返回给用户,以及对文件类@OneToOne关系。在这里你可以存储用户拥有什么权限的细节,在这种情况下,我有一个枚举。

文件类是直截了当:

@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; 
    } 
} 

您可以详细看到这里的解决方案:https://github.com/ccoloradoc/HibernateFilePermissionSample