I pretty much agree with everything you previously posted but the part on "never make the @Id editable from the UI". Specially since, I am strong supporter of surrogate keys for web development. However, I am supporter of never-say-never as well.
Even though I could just end in a rhetorical development exercise.
I decided to move the ball a little further and complete the implementation of database model taken from spring security 3.1.0.; previously referred.
allowing the username field annotated with @Id and being editable from the UI.
RESULTS:
It was really easy to tweak the jspx forms:create, list, show, etc. for properly handing the @Id annotated field 'username' from the UI. Presentation sourcecode seemed ready for such thing.
Following, I am showing pieces of controller/entity code on making JPA to correctly decide when to insert vs. merge
First the entity part:
Code:
@Transactional
public User User.merge(String oldUsername) {
if (this.entityManager == null)
this.entityManager = entityManager();
this.setUsername(oldUsername);
User merged = this.entityManager.merge(this);
this.entityManager.flush();
return merged;
}
@Transactional
public User User.merge(String oldUsername, String newUsername) {
User oldUser = this.entityManager.find(User.class, oldUsername);
this.entityManager.remove(oldUser);
this.entityManager.flush();
User newUser = new User();
newUser.setUsername(newUsername);
newUser.setPassword(this.getPassword());
newUser.setEnabled(this.getEnabled());
User merged = this.entityManager.merge(newUser);
this.entityManager.flush();
return merged;
}
Second: Controller part
Code:
@RequestMapping(method = RequestMethod.PUT)
public String UserController.update(@Valid User user, BindingResult result, ModelMap modelMap) {
.........................
.........................
..........................
String inComing = user.getUsername();
int val = inComing.indexOf(',');
String newUsername = inComing.substring(0, val);
String oldUsername = inComing.substring(val+1, inComing.length());
if(newUsername.equals(oldUsername))
user.merge(oldUsername);
else
user.merge(oldUsername, newUsername);
return "redirect:/users/" + user.getUsername();
Very cool experience. I'll save it. I have the feeling that I going to use it down the road.
Thx Roo People. Thx everybody
jD