users@glassfish.java.net

Re: Update on PK not allowed?

From: Marina Vatkina <Marina.Vatkina_at_Sun.COM>
Date: Thu, 09 Aug 2007 11:50:40 -0700

Well...

How easy it would be for you to officially change your name in real life? How
often would you like to do it?

PK is the identity of each entity instance, so it's used for references in
caches, relationships, change tracking, etc.. Which means that changing the
identity will require the provider to have infrastructure in place for the
before and after world.

Does MySQL allow to change PK value that is being referenced from another table?
Oracle doesn't. As in JPA there are no managed relationships, it will become
your own burden, very similar to that of remove/insert that you rejected for
being too complicated.

HTH,
-marina

Daniel Cavalcanti wrote:
> Ok...
> I'll factor that column/field out and create a "dummy" pk. Deleting and
> inserting to simulate an update is not desirable because that field is
> part of a foreign key with delete and update cascade constraints...
>
> Just out of curiosity, what was the rationale for such a decision in the
> spec since in SQL that is allowed?
>
> thanks,
> Daniel
>
> On 8/8/07, *Marina Vatkina * <Marina.Vatkina_at_sun.com
> <mailto:Marina.Vatkina_at_sun.com>> wrote:
>
> This is according to the spec is the correct behavior:
> "The application must not change the value of the primary key [8] .
> The behavior
> is undefined if this occurs. [9]"
> ...
> "[8] This includes not changing the value of a mutable type that is
> primary key
> or element of a composite primary key.
> [9] The implementation may, but is not required to, throw an
> exception. Portable
> applications must not rely on any such specific behavior."
>
> You can always delete the entity, then change its pk, and finally
> insert the new
> one.
>
> Regards,
> -marina
>
> Daniel Cavalcanti wrote:
> > I'm getting a ValidationException (see below).
> > Why is that now allowed? If I issue the SQL query (update
> `groups` set
> > name='Group C' where name='Group D') in the MySQL shell it works...
> >
> > Here is the script to create the DB schema, the related entity
> class and
> > the code to update.
> > How can I make the update work?
> >
> > drop schema if exists `security_store`;
> > create schema `security_store`;
> >
> > use `security_store`;
> >
> > create table `users` (
> >
> > `username` varchar(20) not null,
> > `password` varbinary(20) not null,
> > `name` varchar(30) not null,
> > `email` varchar(45) not null,
> >
> > primary key(`username`),
> >
> > unique `UNQ_NAME`(`name`)
> >
> > ) Engine = InnoDB;
> >
> > create table `groups` (
> >
> > `name` varchar(20) not null,
> > `container` varchar(20),
> >
> > primary key(`name`),
> >
> > constraint `FK_GROUPS_CONTAINER` foreign key
> > `FK_GROUPS_CONTAINER`(`container`)
> > references `groups`(`name`)
> >
> > ) Engine = InnoDB;
> >
> > create table `user_membership` (
> >
> > `id` serial,
> > `username` varchar(20) not null,
> > `group_name` varchar(20) not null,
> >
> > primary key(`id`),
> > unique `UNQ_RELATIONSHIP`(`username`,`group_name`),
> >
> > constraint `FK_USER_MEMBERSHIP_USERNAME` foreign key
> > `FK_USER_MEMBERSHIP_USERNAME`(`username`)
> > references `users`(`username`),
> >
> > constraint `FK_USER_MEMBERSHIP_GROUP_NAME` foreign key
> > `FK_USER_MEMBERSHIP_GROUP_NAME`(`group_name`)
> > references `groups`(`name`)
> >
> > ) Engine = InnoDB;
> >
> >
> >
> > @Entity()
> > @Table(name = "groups")
> > public class Groups implements Serializable {
> >
> > @Id()
> > @Column(name = "name", nullable = false)
> > private String name;
> >
> > @OneToMany(cascade = CascadeType.ALL, mappedBy = "groupName")
> > private Collection<UserMembership> userMembershipCollection;
> >
> > @OneToMany(cascade = CascadeType.ALL , mappedBy = "container")
> > private Collection<Groups> groupsCollection;
> >
> > @JoinColumn(name = "container", referencedColumnName = "name")
> > @ManyToOne()
> > private Groups container;
> >
> > ...
> >
> > }
> >
> >
> > public void updateGroup(String oldGroup, String newGroup)
> > throws IllegalArgumentException {
> >
> > Groups entity = em.find(Groups.class, oldGroup);
> > if (entity == null)
> > throw new IllegalArgumentException("Group does not
> exist: "
> > + oldGroup);
> >
> > entity.setName(newGroup);
> > em.merge(entity);
> >
> > }
> >
> >
> >
> >
> >
> >
> > Local Exception Stack:
> > Exception [TOPLINK-7251] (Oracle TopLink Essentials - 2.0 (Build
> b58-rc1
> > (08/04/2007))):
> oracle.toplink.essentials.exceptions.ValidationException
> > Exception Description: The attribute [name] of class
> > [com.localmatters.flexiq.security.entity.Groups] is mapped to a
> primary
> > key column in the database. Updates are not allowed.
> > at
> >
> oracle.toplink.essentials.exceptions.ValidationException.primaryKeyUpdateDisallowed(ValidationException.java:2222)
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_glassfish.dev.java.net
> <mailto:users-unsubscribe_at_glassfish.dev.java.net>
> For additional commands, e-mail: users-help_at_glassfish.dev.java.net
> <mailto:users-help_at_glassfish.dev.java.net>
>
>