I need to apply a check so that a user cannot register using an email id which already exists in the database.
Put a constraint on the email column, or select before insert.
There are indeed basically two ways to achieve this:
Test if record exists before inserting, inside the same transaction. The ResultSet#next() of the SELECT should return false. Then do INSERT.
Just do INSERT anyway and determine if SQLException#getSQLState() of any catched SQLException starts with 23 which is a constraint violation as per the SQL specification. It can namely be caused by more factors than "just" a constraint violation. You should namely not handle every SQLException as a constraint violation.
public static boolean isConstraintViolation(SQLException e) {
return e.getSQLState().startsWith("23");
}
I would opt for the first way as it is semantically more correct. It is in fact not an exceptional circumstance. You namely know that it is potentially going to happen. But it may potentially fail in heavy concurrent environment where transactions are not synchronized (either unawarely or to optimize performance). You may then want to determine the exception instead.
That said, you normally don't want to put a PK on an email field. They are namely subject to changes. Rather use a DB-managed autogenerated PK (MySQL: BIGINT UNSIGNED AUTO_INCREMENT, Oracle/PostgreSQL: SERIAL, SQLServer: IDENTITY) and give the email field an UNIQUE key.
Probably something like this DAO method :
public boolean isDuplicateEntry(String email) {
Session session = getSession();
try {
User user = (User) session.get(User.class, email);
session.close();
return (null != user);
} catch (RuntimeException e) {
log.error("get failed", e);
session.close();
throw e;
}
}
Put a unique constraint on the relevant column in the database table. For example (MySQL):
ALTER TABLE Users ADD UNIQUE (Email)
edit - If the e-mail field is already a primary key as you write in a comment above, then you don't need this, because primary keys are by definition unique. Then in Java you could catch the SQLException that you get if you'd insert a record with a primary key that already exists, or you can do a SELECT ... WHERE Email=? before you try the insert to see if there is already a record with that e-mail address.
You may:
make the email field unique, try to insert and catch the exception
or
make a select before each insert
Related
I am building a java project. I want to check if a primary key already exist in my table. For example I have the below code:
private void AddProductActionPerformed(java.awt.event.ActionEvent evt)
{
String query="INSERT INTO Products(Pro_Id ,Pro_Name,Pro_Price,Pro_Quantity,Pro_Supplier_id)VALUES ('"+Pro_Id.getText()+" ','"+Pro_Name.getText()+" ','"+Pro_Price.getText()+" ','"+Pro_Quantity.getText()+" ','"+Pro_Supplier_id.getText()+" ') ";
executeSQLQuery(query,"Inserted");
}
How can I get a message that tells me to change the entry of primary key if it already exists?
You can put your code inside try catch block.
Inside catch block check for SQLException
public static final int MYSQL_DUPLICATE_PK = 1062; // Replace 1062 with exception no. you are getting in case it is different for different database
try{
String query="INSERT INTO Products(Pro_Id ,Pro_Name,Pro_Price,Pro_Quantity,Pro_Supplier_id)VALUES ('"+Pro_Id.getText()+" ','"+Pro_Name.getText()+" ','"+Pro_Price.getText()+" ','"+Pro_Quantity.getText()+" ','"+Pro_Supplier_id.getText()+" ') ";
executeSQLQuery(query,"Inserted");
} catch(SQLException e){
if(e.getErrorCode() == MYSQL_DUPLICATE_PK ){
System.out.println("Primary key already used");
}
}
How can I get a message that tells me to change the entry of primary
key if it already exists?
Make sure you have marked Pro_Id as PRIMARY KEY while defining your table structure which will make sure this behavior and if you try to insert duplicate value it will throw error.
You would get an error if you try your code and the key already exists. Depending on this error for your program to work during a normal flow is not a good idea, as exceptions are always expensive in terms of performance. What you should do is check if the primary key exists already before trying to insert. This can be done by executing a SELECT query.
SELECT 1 FROM Products WHERE Pro_Id = :yourDesiredPk;
When the result of the query is not empty it would mean that it already exists.
A better idea is to consider using a sequence and using the next value aka auto increment, check it out on google (What is a sequence (Database)? When would we need it?). That way you can avoid having duplicate PK problems. But maybe your PK is not a number and has some business logic behind it, in that case a sequence is not an option.
Before insert record do one thing do count(*) and if count is 0 then and then insert the same otherwise show popup for duplicate query.
I have Stored bunch of insert statements in ArrayList.like below
List<String> script=new ArrayList<String>;
script.add("INSERT INTO PUBLIC.EMPLOYEE(ID, NAME) VALUES (1, 'Madhava'));
script.add(INSERT INTO PUBLIC.EMPLOYEE(ID, NAME) VALUES (2, 'Rao'));
script.add(INSERT INTO PUBLIC.ADDRESS(ID, CITY) VALUES(1, 'Bangalore'))
script.add(INSERT INTO PUBLIC.ADDRESS(ID, CITY) VALUES(2, 'Hyd'));
I created connection to the postgresql using jdbc i get executed statments using for loop like below
try{
Connection con=DBConnections.getPostgresConnection();
Statment statment=con.createStatment();
for(String query:script){
executeUpdate(query);
}
}catch(Exception e){
e.printStackTrace();
}
If i get duplication key exception(i.e.Already record exist in postgresDB).
org.postgresql.util.PSQLException: ERROR: duplicate key value
violates unique constraint "reports_uniqueness_index"
How to update the same statment(record) with update query into Postgres.
Is there any way to solve this ?
Is there any other better way to solve this?
Could you please explain...
Execute update sends a DML statement over to the database. Your database must already have a record which uses one of the primary keys either in the employees or address table.
You have to ensure you don't violate the primary key constraint. Violating the constraint is resulting in the exception.
Either change your query to an update statement, or delete the records which are causing conflict.
There is no way to get the key that caused the exception (though you can probably parse the error message, which is certainly not recommended).
Instead, you should try preventing this from ever happenning. There are at least 3 easy ways to accomplish this.
Make the database update the column
(in Postgresql you should use a serial type (which is basically an int data type)
CREATE TABLE employee
(
id serial NOT NULL,
--other columns here )
Your insert will now look like
script.add("INSERT INTO PUBLIC.EMPLOYEE(NAME) VALUES ('Madhava'));//no ID here
Create a sequence and have your JDBC code call the sequence' nexval method.
script.add("INSERT INTO PUBLIC.EMPLOYEE(ID, NAME) VALUES (YOUR_SEQ_NAME.NEXTVAL(), 'Madhava'));
Create a unique ID in Java (least recommended)
script.add("INSERT INTO PUBLIC.EMPLOYEE(ID, NAME) VALUES (UUID.random(), 'Madhava'));//or Math.random() etc
I understand that if I try to insert a record using JPA and if it violates unique constrain, it throws an exception which contains cause MySQLIntegrityConstraintViolationException.
I want to show user friendly message to the user. So I would like to get the field name for which violation occured. I can get the message using cause which gives message something like Duplicate entry '1' for key 'DOCUMENT_NUMBER'.
But I feel relying on message(e.getCause().getCause().getMessage()) is not a good idea.
The entity may contain several other unique constraints like emailid, vat number etc.
So I would like to get the field name for which constraint violation occured.
Could some one please help how to get the field name?
Thanks in advance,
Kitty
you can try below code
try{
//here your code
...
}catch (ConstraintViolationException e) {
for(ConstraintViolation violation : e.getConstraintViolations()) {
System.out.println(violation.getMessage());
}
}
Also for detail explanation of ConstraintViolationException see Java doc.
This question already has answers here:
check for duplicate data before insert
(3 answers)
Closed 7 years ago.
I have a registration table. I want to insert data into that table, but before insertion I want to check if any data like email already exists. It will insert, if the data is not same then it will insert.
Well, I think it would be enough to configure a UNIQUE restriction in those columns you don't want to be duplicated. Then you only have to deal with the exception thrown if any unique field already exists in the table.
Another option (worse in performance) may be to execute an SQL statement to ensure your data is unique, but I recommend you the first option for its simplicity and performance.
UNIQUE KEY will help you:
Write your query like this:
CREATE TABLE Registration
(
email varchar(255) UNIQUE,
// comment: other fields here
)
Catch exception in your java code:
try {
ps = con.prepareStatement("insert into registration(email,....) values (?,....)");
//other fields go here
ps.setString(1, email);
ps.execute();
} catch (SQLException e) {
e.printStackTrace();
}
I have 2 tables named T1 and T2. Where T1 is parent and T2 is child.
The scenario is, I started a jdbc transaction and then insert a row in T1 and then try to insert a row in T2. Inserting row in T2 gies me "Integrity Constraint-Parent key not found" exception.
How i handle this scenario ?
Connection con;
try{
con = ConnectionPool.getConnection();
con.setAutoCommit(false);
int T1Id = getNewId("T1"); // from sequence;
int T2Id = getNewId("T2"); // from sequence;
Insert in to table T1(t1Id,tName) values (T1Id,'A')
Insert in to table T2(t2Id, t1Id,tName) values (T2Id,T1Id,'A')//Here, Exception raises
con.commit();
}catch(Exception e){
try {con.rollback();} catch (SQLException e) {}
}finally{
try {con.setAutoCommit(true);} catch (SQLException e) {}
ConnectionPool.returnConnection(con);
}
Using JDBC API, struts1.2, Oracle10 G Database
You are probably doing something wrong. If both inserts are within the same transaction what you've just mentioned can't happen. Please share some code and more information (DB server, table structures) to see if we can help you.
You need a three step process:
INSERT row into parent
SELECT the generated key from the parent
Use the generated key and the child information to INSERT into the child
It should be a single unit of work, so make it transactional.
It's impossible to tell from your pseudo code. It'd also be helpful to know whether or not you're using auto generated keys.
I'm guessing that the primary key you're assuming for T1 doesn't actually appear. If T2 says the foreign key cannot be null or is required, and it doesn't appear in T1, then the RDBMS system should complain and throw an exception.