I'm stuck on how to implement this and I think my issue must be very common, but my searches have turned up empty. Basically I'm using the standard schema for web security:
Code:
CREATE TABLE Users (Username VARCHAR(255) NOT NULL PRIMARY KEY, Password VARCHAR(255) NOT NULL, Enabled BIT NOT NULL);
CREATE TABLE Authorities (Username VARCHAR(255) NOT NULL, Authority VARCHAR(255) NOT NULL, FOREIGN KEY (Username) REFERENCES Users);
CREATE TABLE Person (Id INT, Name VARCHAR(255), Email VARCHAR(255), UNIQUE (Email), FOREIGN KEY (Email) REFERENCES Users (Username));
I've setup one-to-one mappings between Person and Users and a one-to-many mapping between Users and Authorities. Everything works great. I use those mappings extensively to lazily load or cascadingly save objects.
As you can tell, my usernames are email addresses. So sometimes users need to change their email addresses. I tried the following within a hibernate transaction:
Code:
User user = (User)sessionFactory.getCurrentSession().load(User.class, oldUsername);
user.setUsername(newUsername);
but I get the following exception:
Code:
org.hibernate.HibernateException: identifier of an instance of account.User was altered from scott@test.com to scott@example.com
I even tried playing tricks with hibernate, but nothing works:
Code:
Person person = ((User)sessionFactory.getCurrentSession().load(User.class, oldUsername)).getPerson();
person.getUser().setUsername(newUsername);
This makes sense, I can't just change the primary key and let the corresponding Person and Authorities rows reference a non-existing primary key. I was hoping the cascade="save-update" attributes in my hbm.xml files would magically take care of all this for me, but they don't :(. So what's the solution here? How do I change a user's email address (which is his username)?