Verification: Verify uniqueness before saving

I am developing a web application with the Play Framework. My application has a User class, which in turn has a username and email property. Pretty standard stuff. However...

When a new user is registered through the form (signup, html), I want to check if the username and password are unique, and if not, redirect them back to the form and display a message there.

I already thought of some solutions, none of which are particularly elegant. It seems to me that there should be an easy way to check if the username / email address is unique in the database without placing restrictions on the table (which leads to runtime errors when a duplicate value is inserted).

So ... has anyone encountered this problem? And how did you fix it?

+6
source share
3 answers

I did something similar in the planning system to prevent overlapping shifts for the same person. In the model, it uses the @PrePersist method to query the database and throws a custom exception if it detects anything that could conflict.

Then in the controller I will catch an exception (which will be thrown when the object is saved) and redirected back to the form.

In the model:

 @PrePersist public void prepareToInsert() { List<AgentShift> conflicts = find("agent=?1 and (start_time between ?2 and ?3 or end_time between ?2 and ?3)", agent, sql_datetime_formatter.print(scheduled.getStart()), sql_datetime_formatter.print(scheduled.getEnd())).fetch(); if (!conflicts.isEmpty()) { throw new SchedulingException("New shift for " + agent + " overlaps existing shift which goes from " + sql_datetime_formatter.print(conflicts.get(0).scheduled.getStart()) + " to " + sql_datetime_formatter.print(conflicts.get(0).scheduled.getEnd()), conflicts); } } 

In the controller:

 public static void create(@Valid AgentShift object) { ... try { object._save(); ... } catch (SchedulingException e) { flash.error("conflict with existing shift", e.getConflicts()); redirect(request.controller + ".blank", object._key()); } } 
+2
source

You must use either a database constraint - and handle the exception accordingly, or use a lock (which can sacrifice performance). If you try to run a check at the last minute, you will never know if another request spells out a username between check and commit.

Although this is not often, it can happen (imagine that the network is slow and the user submits an application many times). IMHO, it's best for you to solve the problem correctly, and not hope that it is unlikely to ever happen.

I can develop the code if you want. Although it seems that you already know how to do it (but just looking for a more elegant solution).

+1
source

I wrote UniqueCheck-Valitdation. You can find information about this here https://play.lighthouseapp.com/projects/57987/tickets/370 You will find a test for verification here http://bazaar.launchpad.net/~opensource21/+junk/permsec/files/ head: / samples-and-tests / uniquetest /? file_id = psec-20110808104818-k8u827kllt5n62iq-1

I recommended defining an additional unique constraint in the database.

0
source

Source: https://habr.com/ru/post/896946/


All Articles