Reputation: 1431
is there any possibility to let Hibernate (3.6) populate a database table with values for a given enum ? I have the following class:
@Entity
public enum Role
{
ROLE_USER_FREE("ROLE_USER_FREE"),
ROLE_USER_STANDARD("ROLE_USER_STANDARD"),
ROLE_USER_PREMIUM("ROLE_USER_PREMIUM"),
ROLE_ADMIN("ROLE_ADMIN");
... constructor / setter / getter etc.
}
I can use this enum without any problems from another entity class using
@Enumerated(EnumType.STRING)
public Role getRole()
My question is, how can I populate the corresponding table ROLE automatically ? All the underlying logic and definiations resides in an XML specification. Of course, I can generate a sql file from this spec by XSL and let Hibernate import this by the import.sql sematic at startup... But is there a more elegant way ?
The table should look like this:
|RoleID|RoleName |
| 0 |ROLE_USER_FREE|
....
Upvotes: 5
Views: 8013
Reputation: 1827
You can achieve having "numeric id" in role column in database with mapping to "enum table". To consider postgresql native enum type and its comparison to other approaches, be sure to read https://vladmihalcea.com/the-best-way-to-map-an-enum-type-with-jpa-and-hibernate/
I would suggest to go ordinal way with inserting convient "possible enum values table":
public enum Role
{
ROLE_USER_FREE("ROLE_USER_FREE"),
ROLE_USER_STANDARD("ROLE_USER_STANDARD"),
ROLE_USER_PREMIUM("ROLE_USER_PREMIUM"),
ROLE_ADMIN("ROLE_ADMIN");
... constructor / setter / getter etc.
}
Desired entity using enum:
@Entity
public class OtherClass {
@Enumerated(EnumType.ORDINAL)
@Column(columnDefinition = "smallint")
public Role getRole()
}
Than in unit test ensure that ordinals are always same and also in schema migration part of you project insert enums to database to make them use by database guy to have nice joins possible:
CREATE TABLE otherClass_role_info (
id SMALLINT NOT NULL,
description VARCHAR(255),
name VARCHAR(255),
PRIMARY KEY (id)
)
INSERT INTO otherClass_role_info (
description,
name,
id
)
VALUES (
'Role for admins. Usually means that they can do things without further checking :/',
'ROLE_ADMIN',
3
)
Benefits over STRING approach:
@Column(columnDefinition = "smallint")
to controll data type used)Downsides:
Upvotes: 1
Reputation: 35
This populates my database fine
public class Person implements UserAccount
{
public static enum Role
{
anon(6), admin(1), standard(4), manager(3), user(5), director(2);
private int weight;
Role(int weight)
{
this.weight = weight;
}
public int weight()
{
return weight;
}
}
@ElementCollection(targetClass = Role.class, fetch=FetchType.EAGER)
@Enumerated(EnumType.STRING) // Possibly optional (I'm not sure) but defaults to ORDINAL.
@CollectionTable(name="person_roles")
@Column(name="role")
public Set<Role> getRoles()
{
return roles;
}
...
Upvotes: 4
Reputation: 100706
You have to pick a side - either you're going to use Role
as enum or as entity. You're trying to do both and that's only going to lead to trouble along the road.
If you want to use enum
@Entity
annotation from Role
. It's not an entity, it doesn't have a primary key. It also shouldn't be mutable, so there's little point in persisting it.Roles
(or whatever it's called) table from the database. Hibernate persists enums by name (if you're using @Enumerated(EnumType.STRING)
mapping) or by index in values()
array (if you're using @Enumerated(EnumType.ORDINAL)
annotation). Either way, it will never reference your additional table. With you mapping (@Enumerated(EnumType.STRING)
) it's pointless to have RoleID
to begin with.If you want to use an entity
Role
a true entity - POJO with getters / setters and identifier. It may or may not be mutable depending on what you want.@ManyToOne
from your other tables.Upvotes: 9