Glassfish 3.0.1, JDBCRealm with JPA2 entities

In the last post, I described how to install a JDBCRealm on Glassfish 3.0.1 and use form based authentication in JSF2. This time, I’ll discuss how to put JPA2 entities over these tables. After all, we would like to be able to manage users and user roles with our application.

The idea is obviously that the roles in the “groups” table remain constant. They are not managed by the application.

First, I slightly modified the USERS table structure taking the user name as ID. I also added an ID to the USER_GROUPS table as required by JPA.

CREATE TABLE users (
   user_name VARCHAR(100) NOT NULL CONSTRAINT USERS_PK PRIMARY KEY,
   password VARCHAR(128) NOT NULL);

CREATE TABLE groups (
   group_name VARCHAR(100) NOT NULL CONSTRAINT GROUPS_PK PRIMARY KEY,
   group_desc VARCHAR(512));

CREATE TABLE users_groups(
   id BIGINT NOT NULL CONSTRAINT USER_GROUPS_PK PRIMARY KEY ,
   group_name VARCHAR(100) NOT NULL,
   user_name VARCHAR(100) NOT NULL,
   CONSTRAINT USERS_FK FOREIGN KEY(user_name) REFERENCES users(user_name),
   CONSTRAINT GROUPS_FK FOREIGN KEY(group_name) REFERENCES groups(group_name));

INSERT INTO groups(group_name, group_desc) VALUES ('USER' ,'Application Users');
INSERT INTO groups(group_name, group_desc) VALUES ('ADMIN', 'Application Administrator');

The adapted JDBCRealm definition:

Following the tree entities required to map these tables, starting with the Group table. The entity is “read-only” for the application and only getters are exposed.

 :
 @Entity
 @Table(name="groups")
 public class Group implements Serializable {

   private static final long serialVersionUID = 1L;

   @Id
   @Column(name="group_name")
   private String groupName;

   @Column(name="group_desc")
   private String groupDesc;

   public String getGroupDesc() { return groupDesc; }
   public String getGroupName() {return groupName; }
   :

Next, the User entity:

 :
 @Entity
 @Table(name="Users")
 public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="user_name")
    private String userName;

    @Column(name="password")
    private String password;

    @OneToMany(cascade=CascadeType.ALL,orphanRemoval=true,fetch=FetchType.EAGER)
    @JoinTable(name="users_groups")
    @JoinColumn(name="user_name")
    List userGroups=new ArrayList();
    :
 }

and finally the UserGroup entity:

 :
 @Entity
 @Table(name="users_groups")
 public class UserGroup implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    // Declare your favorite generator here
    private Long id;

    @JoinColumn(name="group_name")
    @OneToOne(fetch=FetchType.EAGER,targetEntity=Group.class)
    private Group group;

    @JoinColumn(name="user_name")
    private User user;
    :
 }

Et voila, now we can manage users and play around with group memberships using JPA. Let’s test…

 User u=new User();
 u.setUserName("newuser"); // ID
 // Password must be encrypted in order to have the
 // Glassfish JDBCRealm working.
 u.setPassword(encryptUsingYourFavoriteMethod("pass"));

 UserGroup ug=new UserGroup();
 ug.setUser(u);
 ug.setGroup(entityManager.find(Group.class,"ADMIN"));
 u.getUserGroups().add(ug);


 entityManager.persist(u);

Leave a Reply

Your email address will not be published. Required fields are marked *