2017-05-14 131 views
0

我需要關於bean屬性的hibernate映射的幫助,指的是多個類。如何在休眠狀態下動態地映射對象

在我的應用程序中,我們正在實施權限。這些權限不是特定於某個用戶的,它可能基於組(包含用戶列表)和角色。所以,權限將適用於用戶,角色和組。

以下是ddl和實體類。請檢查並幫助我。

DDL:

--stores the application users 
CREATE TABLE users (
    id serial PRIMARY KEY, 
    name text, 
    CONSTRAINT uk_users_name UNIQUE (name) 
); 

--stores the application groups 
CREATE TABLE groups (
    id serial PRIMARY KEY, 
    name text, 
    CONSTRAINT uk_groups_name UNIQUE (name) 
); 

--stores the application roles 
CREATE TABLE roles (
    id serial PRIMARY KEY, 
    name text, 
    CONSTRAINT uk_roles_name UNIQUE (name) 
); 

--stores the application object types 
CREATE TABLE app_object_types (
    id serial PRIMARY KEY, 
    name text, 
    CONSTRAINT uk_app_object_types_name UNIQUE (name) 
); 

INSERT INTO app_object_types (name) VALUES ('USERS'); 
INSERT INTO app_object_types (name) VALUES ('GROUPS'); 
INSERT INTO app_object_types (name) VALUES ('ROLES'); 


CREATE TABLE app_permissions (
    id serial PRIMARY KEY, 
    object_type_id integer REFERENCES app_object_types(id), -- To represent the object type 
    object_id integer, -- Objecct_id refers users -> id, groups -> id, roles - id 
    permission_name text, 
    CONSTRAINT uk_permissions UNIQUE (object_type_id, object_id, permission_name) 
); 

實體類:

@Entity 
@Table(name = "users") 
public class Users { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 

    private int name; 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public int getName() { 
     return name; 
    } 

    public void setName(int name) { 
     this.name = name; 
    } 
} 

@Entity 
@Table(name = "groups") 
public class Groups { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 

    private int name; 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public int getName() { 
     return name; 
    } 

    public void setName(int name) { 
     this.name = name; 
    } 
} 

@Entity 
@Table(name = "roles") 
public class Roles { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 

    private int name; 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public int getName() { 
     return name; 
    } 

    public void setName(int name) { 
     this.name = name; 
    } 
} 

@Entity 
@Table(name = "app_object_types") 
public class AppObjectTypes { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 

    private int name; 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public int getName() { 
     return name; 
    } 

    public void setName(int name) { 
     this.name = name; 
    } 

} 

@Entity 
@Table(name = "app_permissions") 
public class AppPermissions { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 

    @ManyToOne 
    private String permissionName; 

    @ManyToOne 
    private AppObjectTypes appObjectTypes; 

    private int objectId; 

    private Class<?> dependentObject; 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public String getPermissionName() { 
     return permissionName; 
    } 

    public void setPermissionName(String permissionName) { 
     this.permissionName = permissionName; 
    } 

    public AppObjectTypes getAppObjectTypes() { 
     return appObjectTypes; 
    } 

    public void setAppObjectTypes(AppObjectTypes appObjectTypes) { 
     this.appObjectTypes = appObjectTypes; 
    } 

    public int getObjectId() { 
     return objectId; 
    } 

    public void setObjectId(int objectId) { 
     this.objectId = objectId; 
    } 

    public Class<?> getDependentObject() { 
     return dependentObject; 
    } 

    public void setDependentObject(Class<?> dependentObject) { 
     this.dependentObject = dependentObject; 
    } 
} 

我要地圖的用戶(或)組(或)作用的bean對象AppPermissions - 使用Hibernate> dependentObject。我不知道這是否可能,請幫助我。

回答

0

我建議您考慮在AppPermission實體上使用@Inheritance以便根據依賴對象類型對每個子類進行特殊化。

@Entity 
@Inheritance(strategy = InheritanceType.JOINED) 
@DiscriminatorColumn(name = "OBJECT_TYPE") 
public class AppPermission { 
    @Id 
    @GeneratedValue 
    private Long permissionId; 
    private String name; 
    @Column(name = "OBJECT_TYPE", insertable = false, updatable = false) 
    private String objectType; 
} 

@Entity 
@DiscriminatorValue("USER") 
public class UserAppPermission extends AppPermission { 
    @ManyToOne(optional = false) 
    private User user; 
} 

@Entity 
@DiscriminatorValue("ROLE") 
public class RoleAppPermission extends AppPermission { 
    @ManyToOne(optional = false) 
    private Role role; 
} 

@Entity 
@DiscriminatorValue("GROUP") 
public class GroupAppPermission extends AppPermission { 
    @ManyToOne(optional = false) 
    private Group group; 
} 

與你的這些映射在這裏的第一個區別是你AppPermission表將被從當前的模式不同的構造和看起來像下面的(注4個表):

 
Table: AppPermission 
    id NOT NULL IDENTITY(1,1) 
    name VARCHAR(255) 
    OBJECT_TYPE VARCHAR(31) 

Table: UserAppPermission 
    id NOT NULL BIGINT (FK -> AppPermission) 
    user_id NOT NULL BIGINT (FK -> User) 

Table: RoleAppPermission 
    id NOT NULL BIGINT (FK -> AppPermission) 
    role_id NOT NULL BIGINT (FK -> Role) 

Table: GroupAppPermission 
    id NOT NULL BIGINT (FK -> AppPermission) 
    group_id NOT NULL BIGINT (FK -> Group) 

全數據庫的一點是幫助我們保持參照完整性。這就是爲什麼當一個表依賴於另一個表中的一行時,應該首先刪除與您希望刪除的行相關的從屬錶行,以避免違反約束條件。這正是我將關係拆分爲單獨表格的原因,在這裏我將每個關係定義爲「可選= false」,以便它基本上代表連接表。

另一個附加的好處是,如果你的AppPermission有你需要的存儲特定於依賴對象的類型的屬性,你可以自由的屬性添加到子類,這些屬性在特定子類的表分開存放。

該設置還會消除您的AppObjectType表,因爲該表現在作爲Hibernate的鑑別器模式的一部分進行驅動。請注意,如果您有其他「對象類型」,則需要使用此設置介紹其具體實現。

最後,我將OBJECT_TYPE作爲一個不可插入和不可更新的字段公開(因爲您不必),因爲Hibernate會爲您管理它。但是我已經公開了它,允許您進行多態查詢並確定結果對象的對象類型,而無需執行instanceof檢查。

相關問題