How to run mysql insert without duplicates in java - java

I have a method which insert a record to mysql database as bellow,
public boolean addOrganization(OrganizationDTO organizationDTO) {
Connection con = null;
try {
String insertOrganizationSQL = "INSERT INTO organizations (org_id, org_name) VALUES(?, ?)";
con = JDBCConnectionPool.getInstance().checkOut();
PreparedStatement insertOrgPS = (PreparedStatement) con.prepareStatement(insertOrganizationSQL);
insertOrgPS.setString(1, organizationDTO.getOrg_id());
insertOrgPS.execute();
return true;
} catch (Exception e) {
JDBCConnectionPool.getInstance().checkIn(con);
logger.error(e.getLocalizedMessage());
e.printStackTrace();
return false;
} finally {
JDBCConnectionPool.getInstance().checkIn(con);
}
}
database table,
CREATE TABLE `organizations` (
`org_id` varchar(5) NOT NULL,
`org_name` varchar(100) DEFAULT NULL,
`sys_dat_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user` varchar(100) NOT NULL,
PRIMARY KEY (`org_id`)
)
what I need is, when I insert a new record if, that is a duplicate exit the method without trying to insert and inform the user that it is a duplicate record. Is it possible to do without writing another method to search the record before inserting?

I would add a UNIQUE constraint to your table. For example, if org_name needs to be unique:
ALTER TABLE organizations ADD UNIQUE (org_name);
Then observe what's returned when you try to insert a duplicate record through Java. Add code to check for this, and if it occurs, display the message to your user.
Here is the reference documentation for ALTER TABLE.

Thats right, Alter table will surely help.
In your case, let say, both org_id and org_name is there, I would add unique in both, just avoid any confusion later.

Related

Pass FK field from SQL Server to Java object class

My application uses data from a jsp form to populate the tables in the SQL Server and create the objects in java. All ids (PK) in the tables are defined as autoincrement. However, I don't know how to insert the FKs data in the tables and add it to the java objects. For example, I have the table Instructor that has FK_course and FK_department.
CREATE TABLE [dbo].[instructors](
[instructor_id] [int] IDENTITY(1,1) NOT NULL,
[instructor_lastname] [nvarchar](250) NULL,
[instructor_firstname] [nvarchar](250) NULL,
[department_id] [int] NULL,
[course_id] [int] NULL,
CONSTRAINT [PK_instructors] PRIMARY KEY CLUSTERED
ALTER TABLE [dbo].[instructors] WITH CHECK ADD CONSTRAINT [FK_course_instructor] FOREIGN KEY([course_id])
REFERENCES [dbo].[courses] ([course_id])
GO
ALTER TABLE [dbo].[instructors] WITH CHECK ADD CONSTRAINT [FK_department_instructor] FOREIGN KEY([department_id])
REFERENCES [dbo].[departments] ([department_id])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
In my code a have the class Instructor that has the gets and sets, and I use doPost to insert the data and create the object in java.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//insert instructor
String lastname = request.getParameter("lname");
String firstname = request.getParameter("fname");
// int departament_id = ??
// String course_id= ???
Instructor instructor = new Instructor(lastname, firstname);//departament_id? course_id?
formService.insertInstructor(instructor);
In another file I do all the DB connection to insert the data in the database. But the problem is with department_id and course_id. How can I get the data from the tables Course and Department to insert in the table instructors? Here is my code for Instructor table, but is missing those two fields that I do know how to insert in the table and add to the object in java. I appreacite your time and help.
public void insertInstructor(Instructor instructor) {
Connection connection = Database.getConnection();
String sql = "INSERT INTO My_app.dbo.instructors(instructor_lastname, instructor_firstname) VALUES (?,?);";
try {
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, instructor.getLastname());
statement.setString(2, instructor.getFirstname());
// statement.setInt(3, instructor.getDepartment_id());
// statement.setString(3, instructor.getCourse());
statement.execute();
} catch (SQLException e) {
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
}
}

PostgreSQL JDBC - relation already exists when creating table using PreparedStatements

So I am creating a JDBC program using a connection. This is my first time becoming familiar with this kind of programming so please excuse me if my question comes across as "dumb". But I have been stuck on this issue for a while. I am created 4 new tables. It compiles fine but when I run it, I get a "ERROR: relation "joke" already exists". When I remove the createTableJoke prepared statement, I get the same error ("ERROR: relation "gift" already exists") for my gift table. This continues for all my statements. What am I doing wrong and what is the logic behind why PostgreSQL does this? I have included my code below:
private static void createTables() throws SQLException {
PreparedStatement createTableJoke = null;
PreparedStatement createTableGift = null;
PreparedStatement createTableHat = null;
PreparedStatement createTableCracker = null;
Connection conn = null;
try {
conn = getDBConnection();
createTableJoke = conn.prepareStatement("CREATE TABLE Joke ( jid INTEGER PRIMARY KEY, joke CHAR(200) NOT NULL, royalty FLOAT NOT NULL);");
createTableJoke.executeUpdate();
createTableGift = conn.prepareStatement("CREATE TABLE Gift ( gid INTEGER PRIMARY KEY, description CHAR(100) NOT NULL, price FLOAT NOT NULL);");
createTableGift.executeUpdate();
createTableHat = conn.prepareStatement("CREATE TABLE Hat ( hid INTEGER PRIMARY KEY, description CHAR(100) NOT NULL, price FLOAT NOT NULL);");
createTableHat.executeUpdate();
createTableCracker = conn.prepareStatement("CREATE TABLE Cracker (cid INTEGER PRIMARY KEY, name CHAR(20) NOT NULL, jid INTEGER REFERENCES Joke(jid), gid INTEGER REFERENCES Gift(gid), hid INTEGER REFERENCES Hat(hid), saleprice NUMERIC CHECK (saleprice > 0), quantity INTEGER NOT NULL);");
createTableCracker.executeUpdate();
} catch (SQLException e){
System.out.println(e.getMessage());
}
finally {
if ((createTableJoke != null) && (createTableGift != null) && (createTableHat != null) && (createTableCracker != null)){
createTableJoke.close();
createTableGift.close();
createTableHat.close();
createTableCracker.close();
}
if (conn != null) {
conn.close();
}
}
}
There are two cases:
You don't care about keeping the existing table if there is one. In this case, issue "DROP TABLE IF EXISTS Joke" before creating it. This will ensure the table is deleted, it will not fail when the table is not there.
You care about the existing content of your tables. In this case, issue a "CREATE TABLE IF NOT EXISTS Joke" ... instead of your plain CREATE TABLE. This will ensure the table is there, and if it already exists, it will not be created. Also note, if you change the structure in your create statement and the table exists, the change in structure does not apply.
This kind of errors means, that all this table were already created. Use pgAdmin (on Microsoft Windows operating systems it usually goes along with PostgreSQL installation) or psql client to connect to the database and check table existence.

PostgreSQL Insertion in JAVA via JSP Incrementing Primary Key

I am writing a JSP application where the user enters a food item and it is entered in a PostgreSQL database. I had no problems implementing this when the user manually had to enter the next primary key, but I removed this ability so that the primary key would be automatically assigned when the enter button is clicked. I would like the query to fetch the current maximum FID (Food ID) and set the new food item's FID to the previous + 1.
try {
conn = ConnectionProvider.getCon();
String sql = "select fid from project.food order by fid desc limit 1";
pst = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
status = pst.getResultSetType();
f.setFood_id(status + 1);
pst = conn.prepareStatement("insert into project.food values(?,?,?,?,?,?)");
pst.setInt(1, f.getFood_id());
pst.setString(2, f.getFood_name()); //set name
pst.setInt(3, f.getCount()); //set count
pst.setInt(4, f.getPrice_per_item()); //set price
pst.setInt(5, f.getThreshold()); //set threshold
pst.setString(6, "false");
status = pst.executeUpdate();
conn.close();
pst.close();
} catch (Exception ex) {
System.out.println(ex);
}
return status;
}
The first food item is successfully inserted into the database in row 1006, instead of the 7th row, which is the first available in the database. Additionally, the second insert fails due to the failure of the primary key to the incremented by 1. The program again tries to insert the next tuple in the same row and thus violates the primary key constraint.
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "food_pkey"
Detail: Key (fid)=(1006) already exists.
Make your primary key autoincrement in the database by declaring it SERIAL datatype (basically an auto incrementing INT) so a sequence is created to automatically assign values to it.
Then convert your update statement to specify all columns except for the primary key (i.e. insert into project.food(foo, bar, baz) values (?, ?, ?), and remove one ? placeholder and the pst.setInt(1,f.getFood_id()); line. This will insert values to all the other columns, and the primary key will be generated by the database.
This way you don't need to do a select when you want to insert (which was a really bad idea anyway), and you let the database do what it does best. You don't need to care about the value of the primary key after that.

Java JDBC adding automatic value to database

I'm working with Java JDBC with Apache Derby data base.
I have a table called `company`` with the values :
id, comp_name, password, email.
This method should create a new row of company with name, password, and email received from the user but the ID should be given automatically from the database and increment itself each time a new company is added to the database.
I just can't figure out how to make this work, I obviously get a error
"column 'ID' cannot accept a NULL value."
because the update occours before the ID is setted.
Code:
public void createCompany(Company company) {
Connection con = null;
try {
con = ConnectionPool.getInstance().getConnection();
String sql = "INSERT INTO company (comp_name, password, email) VALUES (?,?,?)";
PreparedStatement pstmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
pstmt.setString(1, company.getCompName());
pstmt.setString(2, company.getPassword());
pstmt.setString(3, company.getEmail());
pstmt.executeUpdate();
ResultSet rs = pstmt.getGeneratedKeys();
rs.next();
company.setId(rs.getLong(1));
pstmt.getConnection().commit();
} catch (SQLException e) {
e.printStackTrace();
} finally {
ConnectionPool.getInstance().returnCon(con);
}
During creation of that table you have to write following DDL
CREATE TABLE MAPS
(
comp_id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
comp_name VARCHAR(24) NOT NULL,
password VARCHAR(26)
)
Ref : https://db.apache.org/derby/docs/10.0/manuals/develop/develop132.html
You're doing almost everything right, you just need to let the database assign an unique ID to each inserted row:
CREATE TABLE my_table (
id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
...
);
A problem could be that you made a mistake by creating your table.
You could create your table like this:
CREATE TABLE company
(
ID INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
comp_name VARCHAR(50),
email VARCHAR(50),
password VARCHAR (50)
)
IF you want other values to be not NULL you could add NOT NULL to their lines:
password VARCHAR (50) NOT NULL
Delte your old table and execute the the SQl above on your DB. After that you can use your code without changes.

JDBC: foreign key on PK created in same transaction

I have two tables in my MySQL database, which were created like this:
CREATE TABLE table1 (
id int auto_increment,
name varchar(10),
primary key(id)
) engine=innodb
and
CREATE TABLE table2 (
id_fk int,
stuff varchar(30),
CONSTRAINT fk_id FOREIGN KEY(id_fk) REFERENCES table1(id) ON DELETE CASCADE
) engine=innodb
(These are not the original tables. The point is that table2 has a foreign key referencing the primary key in table 1)
Now in my code, I would like to add entries to both of the tables within one transaction. So I set autoCommit to false:
Connection c = null;
PreparedStatement insertTable1 = null;
PreparedStatement insertTable2 = null;
try {
// dataSource was retreived via JNDI
c = dataSource.getConnection();
c.setAutoCommit(false);
// will return the created primary key
insertTable1 = c.prepareStatement("INSERT INTO table1(name) VALUES(?)",Statement.RETURN_GENERATED_KEYS);
insertTable2 = c.prepareStatement("INSERT INTO table2 VALUES(?,?)");
insertTable1.setString(1,"hage");
int hageId = insertTable1.executeUpdate();
insertTable2.setInt(1,hageId);
insertTable2.setString(2,"bla bla bla");
insertTable2.executeUpdate();
// commit
c.commit();
} catch(SQLException e) {
c.rollback();
} finally {
// close stuff
}
When I execute the code above, I get an Exception:
MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails
It seems like the primary key is not available in the transaction before I commit.
Am I missing something here? I really think the generated primary key should be available in the transaction.
The program runs on a Glassfish 3.0.1 using mysql-connector 5.1.14 and MySQL 5.5.8
Any help is really appreciated!
Regards,
hage
You missed something for the returned updated id , you have to do like this :
Long hageId = null;
try {
result = insertTable1.executeUpdate();
} catch (Throwable e) {
...
}
ResultSet rs = null;
try {
rs = insertTable1.getGeneratedKeys();
if (rs.next()) {
hageId = rs.getLong(1);
}
...
Instead of using executeUpdate() use execute() and then return the primary key.
http://www.coderanch.com/t/301594/JDBC/java/Difference-between-execute-executeQuery-executeUpdate
But I don't work with db...so I could do a mistake

Categories

Resources