Reputation: 1345
I have a bit of a complicated structure that I have listed below. Basically I have a bunch of different "role groups". Each role group contains a group of roles. A user can potentially have several different role groups, and a role group can be applied to many different users. Because of that I went with a ManyToMany relationship.
I want the RoleGroup to be part of the User, as listed below.
Everything is somewhat working. However, when I use the insert statements listed below I have a bug in my code. The RoleGroup contains only ROLE3. I am not sure why but somehow my code is only allowing one Role to be part of a RoleGroup with the current setup. Querying the database yields that all 3 Roles are present, but they are not on my Entity.
Please help!
CREATE TABLE USER (
USER_ID NUMBER(38, 0) PRIMARY KEY,
NAME VARCHAR2(50) NOT NULL
);
CREATE TABLE ROLE_GROUPS (
ROLE_GROUP_ID NUMBER(38, 0) PRIMARY KEY,
NAME VARCHAR2(50) NOT NULL
-- constraints
CONSTRAINT UQ_ROLE_GROUP_NAME UNIQUE (NAME)
);
CREATE TABLE ROLE (
ROLE_GROUP_ID NUMBER(38, 0) NOT NULL,
ROLE VARCHAR2(10) NOT NULL,
-- constraints
CONSTRAINT PK_ROLES PRIMARY KEY (ROLE_GROUP_ID, ROLE),
CONSTRAINT FK_ROLES FOREIGN KEY(ROLE_GROUP_ID) REFERENCES ROLE_GROUPS
);
CREATE TABLE ROLE_GROUP_X_USER (
ROLE_GROUP_ID NUMBER(38, 0) NOT NULL,
USER_ID NUMBER(38, 0) NOT NULL,
-- constraints
CONSTRAINT PK_1 PRIMARY KEY (ROLE_GROUP_ID, USER_ID),
CONSTRAINT FK_1 FOREIGN KEY(ROLE_GROUP_ID) REFERENCES ROLE_GROUPS,
CONSTRAINT FK_1 FOREIGN KEY(USER_ID) REFERENCES USER
);
INSERT INTO ROLE_GROUPS(ROLE_GROUP_ID, NAME) VALUES (1, 'GROUP_1');
INSERT INTO ROLE(ROLE_GROUP_ID, NAME) VALUES(1 ,'ROLE1');
INSERT INTO ROLE(ROLE_GROUP_ID, NAME) VALUES(1 ,'ROLE2');
INSERT INTO ROLE(ROLE_GROUP_ID, NAME) VALUES(1 ,'ROLE3');
INSERT INTO ROLE_GROUP_X_USER(USER_ID,ROLE_GROUP_ID) SELECT USER_ID, 1 FROM USER where USER_ID IN ('1', '2', '3', '4');
@Entity
@Table(name="USER")
public class User {
//Other code
@ManyToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
@JoinTable(name = "ROLE_GROUP_X_USER",
joinColumns = { @JoinColumn(name = "USER_ID") },
inverseJoinColumns = { @JoinColumn(name = "ROLE_GROUP_ID") })
private Set<RoleGroupEntity> roleGroupEntities;
}
@Entity
@Table(name="ROLE_GROUPS")
public class RoleGroupEntity {
//Other code
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name="ROLE", joinColumns=@JoinColumn(name="ROLE_GROUP_ID"))
@AttributeOverrides({
@AttributeOverride(name="role", column=@Column(name="ROLE")) })
private Set<Role> roles = new HashSet<Role>();
}
@Embeddable
public class Role {
private String role;
//Getter, Setter
//Hashcode, equals override
}
Upvotes: 4
Views: 452
Reputation: 3877
It looks like your joinColumn is wrong. Usually you have two columns on a ManyToMany Join, joinColumns and inverseJoinColumns, but I'd have to say you're using the wrong column.
I think you're going to need a separate mapping table for including roles in groups. Add this to your RolesGroup class:
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "GROUP_ROLE_MAP_T", joinColumns = {
@JoinColumn(name = "ROLE_GROUP_ID")
}, inverseJoinColumns = {
@JoinColumn(name = "ROLE_ID")
})
private Set<Role> role = new HashSet<Role>(0);
Make your roles a table too:
@Entity
@Table(name = "ROLES_T")
@AttributeOverride(name = "id", column = @Column(name = "ROLE_ID"))
public class Role {
@Column(name = "ROLE_ID", nullable = true)
private Long roleId = new Long(0);
@Column(name = "ROLE_NAME", nullable = false)
private String role;
}
Don't forget your getter/setters.
Upvotes: 1