openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Simone Gianni <simo...@apache.org>
Subject Re: Many-to-many relationship
Date Fri, 16 Jan 2009 12:49:52 GMT
Hi Håkon,
Yes, the latter code you posted (getting the Role entity back from the 
DB and then using it for the new User entity) should be the right way 
and solve your problem. Please also take care of checking that 
CascadeType.ALL, it could delete rows from the Role table even if other 
users are actually linked to that Role. CascadeType.PERSIST is safer 
when entities in relations are shared (basically, use CascadeType.ALL 
with confidence on OneToOne relationship).

You could specify the role column with @Column(unique=true), that is 
intended to prevent insertion of more than one line having the same role 
value, but actually it would not solve your problem, but only throw an 
exception if it detects that you are saving a duplicate row.

The reason why OpenJPA (and any JPA provider) is acting this way is that 
you could use the Role class to add more properties to the 
User->Roles(enum) relationship. Suppose for example that a user can have 
a "state" of his role assignment, something like "requested", "pending 
approval", "approved", or a date stating when the user gained that role, 
or any other metadata about the using having that role :) . This way, 
you can have a user having an approved role of Admin since the 10th 
March 2008, another one having the same Admin role since a different 
date, and yet another one pending approval for the same Asdmin role 
etc..etc.. Obviously in this case, every row in the database must be 
unique.

You are using this technique, which is great, but probably a bit 
overkill if you only need to map "user A has one or more of this, fixed, 
static, roles in an enum, without any other attribute". Unfortunately 
however, JPA currently does not support (AFAIK) a way to express a 
collection of enum values if not wrapping them in an entity class (which 
is what you did), bringing the "metadata" advantage but also the "it's 
an entity, so you must fetch it from the database" disadvantage.

Hope this helps,
Simone

Håkon Sagehaug wrote:
> hi,
>
> thanks for the replay
>
> see in line
>
>
>
> 2009/1/16 Simone Gianni <simoneg@apache.org>
>
>   
>> Hi Håkon,
>> is the role_id property in the Role entity annotated with @Id or in any
>> other way considered an ID by OpenJPA?
>>     
>
> role_id id annotated with @Id
>
>   
>> Are you adding roles to new users creating new instances of the Role
>> classes (like User u = new User(); u.addRole(new Role(Roles.ADMIN)); .. ) or
>> getting preexisting Role entities from the database?
>>
>>     
>
> yes
>
>
>
>
>   
>> If you are creating new Role(..) every time, OpenJPA properly supposes that
>> is a new row to add to the table.
>>
>>     
>
> So I've got get a role from the db and assign this to the users role
>
> Role r1 = roledao.find("Admin")
>
> user.addRole.(r1)
>
> something like this?
>
> Or is it possible to annotate this in a way?
>
>
>   
>> Hope this helps,
>> Simone
>>
>>
>> Håkon Sagehaug wrote:
>>
>>     
>>> Hi
>>>
>>> I've got the following setup. A user entity and a role entity. The user
>>> has
>>> a collection of Role, annotated like this
>>>
>>>
>>> public class User{
>>>
>>>        ....
>>>       @ManyToMany(cascade = CascadeType.ALL)
>>>         private Collection<Role> roles = new HashSet<Role>();
>>>
>>> }
>>>
>>> public Role {
>>>       private int role_id;
>>>
>>>    @Column(name = "role")
>>>    private Roles role;
>>> }
>>>
>>> Where Roles is a enum, with the possible roles. So first of all is this
>>> the
>>> correct setup if I also want to have many users been able to have the same
>>> role?
>>>
>>> e.g User 1, Role:Admin,User,Tester
>>>       User2, Role:Admin,Tester
>>>
>>> So when persisting a new user the role is also persists the Role object
>>> even
>>> if there is one from before. so in the example above the Admin and tester
>>> role would be inserted twice, and I of course want them to be inserted
>>> just
>>> once. Is there a way to do this? Should  annotate the Role entity with
>>> something more?
>>>
>>> cheers, Håkon
>>>
>>>
>>>
>>>
>>>       
>> --
>> Simone Gianni            CEO Semeru s.r.l.           Apache Committer
>> http://www.simonegianni.it/
>>
>>
>>     
>
>
>   


-- 
Simone Gianni            CEO Semeru s.r.l.           Apache Committer
http://www.simonegianni.it/


Mime
View raw message