Embeddable键上的OneToMany映射

时间:2017-04-05 21:44:18

标签: java jpa jpql

我正在尝试构建用户访问项目(存储在表tab中)的权限规则(存储在表users中)。是否查看内容的可用性存储在permissions_tabs表中。

结果应该像运行语句一样(对于id = 2的用户):

SELECT project.tab.tab_id, project.tab.parent, project.tab.name
FROM project.tab
INNER JOIN project.permissions_tabs
ON project.tab.tab_id=project.permissions_tabs.tab_id
WHERE permissions_tabs.user_id=2 AND permissions_tabs.view=true;

我试图通过@OneToMany注释来做,但它失败了 - 我收到了消息:

  

部署失败。消息是:例外描述:   @JoinColumns在带注释的元素[field allowedTabs]上   实体类[class   com.jtsmr.scheduler.persistence.entities.UsersEntity]不完整。   当源实体类使用复合主键时,a   必须使用。为每个连接列指定@JoinColumn   @JoinColumns。名称和referencedColumnName元素都必须   在每个@JoinColumn中指定。

在修改数据库并添加permissions_tab之前,一切正常。当我添加它时 - 我无法编写正确的@OneToMany注释,也没有成功为我的案例查找手册。

如果不可能,通过JPQL的解决方案就足够了(我无法构建连接操作)。

这是我的设置:

DB(创建语句以便于理解):

CREATE TABLE `users` (
  `user_id` bigint(20) NOT NULL,
  `username` varchar(45) NOT NULL,
  `password` varchar(45) NOT NULL,
  `name` varchar(45) NOT NULL,
  `email` varchar(80) NOT NULL,
  PRIMARY KEY (`user_id`),
  UNIQUE KEY `user_id_UNIQUE` (`user_id`),
  UNIQUE KEY `username_UNIQUE` (`username`)
);
CREATE TABLE `tab` (
  `tab_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `parent` bigint(20) NOT NULL DEFAULT '0',
  `name` varchar(45) NOT NULL,
  PRIMARY KEY (`tab_id`)
);
CREATE TABLE `permissions_tabs` (
  `user_id` bigint(20) NOT NULL,
  `tab_id` bigint(20) NOT NULL,
  `to_view` bit(1) DEFAULT b'0',
  `to_edit` bit(1) DEFAULT b'0',
  PRIMARY KEY (`user_id`,`tab_id`),
  KEY `user_id_idx` (`user_id`),
  KEY `tab_id_idx` (`tab_id`),
  CONSTRAINT `tab_id` FOREIGN KEY (`tab_id`) REFERENCES `tab` (`tab_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
);

JPA Mapping如下(功能省略):
标签:

@Entity
@Table(name = "tab")
public class TabEntity implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "tab_id", insertable = false, updatable = false)
    private Long tabId;
    @Column(name = "parent", insertable = false, updatable = false)
    private Long parent;
    @Column(name = "name", insertable = false, updatable = false)
    private String name;
}

用户:

@Entity
@Table(name = "users")
public class UsersEntity implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_id")
    private Long userId;
    @Column(name = "username")
    private String username;
    @Column(name = "password")
    private String password;
    @Column(name = "name")
    private String name;
    @Column(name = "email")
    private String email;
    @OneToMany
    @JoinTable(
        name = "permissions_tabs",
        joinColumns
        = {
            @JoinColumn(name = "user_id", referencedColumnName = "user_id")},
        inverseJoinColumns
        = {
            @JoinColumn(name = "tab_id", referencedColumnName = "tab_id")})
    private List<PermissionsTabsEntity> allowedTabs;
}

PermissionsTabsEntity类的主键:

@Embeddable
public class PermissionsTabsPK implements Serializable {
    @Column(name = "user_id")
    private Long userId;
    @Column(name = "tab_id")
    private Long tabId;
}

PermissionsTabsEntity:

@Entity
@Table(name = "permissions_tabs")
public class PermissionsTabsEntity implements Serializable {
    @EmbeddedId
    private PermissionsTabsPK id;
    @Column(name = "to_view")
    private boolean toView;
    @Column(name = "to_edit")
    private boolean toEdit;
}

提前谢谢!

0 个答案:

没有答案