As my first try at using openjpa-1.0.0-SNAPSHOT (with Postgres) I'm 
trying to create classes that will map into tables that can be used 
by tomcat realm security.  Tomcat requires the following exist for 
database security to work:

A user table with fields to hold a userid and a password.
A role table with fields to hold a userid and a role.

When doing it manually, the schema looked like:

create table users (
       userid  varchar(32) primary key not null,
       password varchar(64) not null
)

create table roles (
       userid  varchar(32) not null,
       role   varchar(32) not null,
       primary key (userid, role)
)

Then, in the context.xml file for a web application, you have to
provide do

<Realm className="org.apache.catalina.realm.DataSourceRealm"
       dataSourceName="jndi/TestDS"
       localDataStore="true"
       digest="MD5"
       roleNameCol="role"
       userCredCol="password"
       userNameCol="userid"
       userTable="users"
       userRoleTable="roles"/>

As you can see, the userid field must have the same name in both
tables for tomcat to use this structure for user authentication.

I have tried multiple ways to get a proper table structure built.  I
created a User.java class that looks like

@Table(name="users")
public class User implements Serializable {
       @Id
       String     userid;
       
       @Column(nullable=false)
       String     password;

       ArrayList<Role>  roles

       ...
}

and a Role.java class that looks like

@Table(name="roles")
public class Role implements Serializable {

       @Id
       String           roleName;
}

Then I create a single user with one role

     User u = new User("user","password");
     Role r = new Role("admin");
     u.addRole(r);      //puts it in the roles arraylist

and I do all the normal steps to apply these, first persisting the
role object, then persisting the user object.

I end up with 2 tables, users and roles. The users table has the User
object in it but it stores the array list as a byte array. Not what I need.

So I change the User class to look like:

@Table(name="users")
@SecondaryTable(name="users_roles",
                [EMAIL PROTECTED](name="userid",
referencedColumnName="userId"))
public class User implements Serializable {
       @Id
       String     userid;
       
       @Column(nullable=false)
       String     password;

       @Column(table="users_roles")       
       ArrayList<Role>  roles

       ...
}

So now I get 3 tables, the User object in users, the Role object in
roles and the users_roles table now has a single entry with the userid
field as requested, but it now has the byte array of data from the
roles attribute.

I've tried to declare the attribute @ManyToMany and it puts the data
into a table called user_role but the fields are named user_userid and
roles_rolename because it will not allow the @Column setting with the
@ManyToMany.

Any ideas how to structure the classes and/or annotations to get the
table constructs needed?

Thanks in advance

Jere



Reply via email to