Not able to handle MysqlIntegrity exception in sqlexception - java

I am trying to catch MysqlIntegrityException in catch clause of SQL exception but it does not seems to handle it in catch block of SQL exception. What might be the reason and how to solve it.
catch(SQLException e)
{
//not reaching here
}

Sorry, cannot reproduce this one.
Here's some tables I created in the MySQL monitor:
mysql> create table a (id int not null primary key auto_increment);
Query OK, 0 rows affected (0.09 sec)
mysql> create table b (b_id int not null primary key auto_increment, a_id int not null);
Query OK, 0 rows affected (0.06 sec)
mysql> alter table b add constraint a_fk foreign key (a_id) references a(id);
Query OK, 0 rows affected (0.19 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> insert into a() values();
Query OK, 1 row affected (0.04 sec)
mysql> insert into a() values();
Query OK, 1 row affected (0.03 sec)
mysql> insert into b (a_id) values (1);
Query OK, 1 row affected (0.04 sec)
Let's just test that the foreign key constraint is working:
mysql> delete from a where id = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test`.`b`, CONSTRAINT `a_fk` FOREIGN KEY (`a_id`) REFERENCES `a` (`id`))
I then wrote this Java class:
import java.sql.*;
public class MySQLExceptionTest {
public static void main(String[] args) throws Exception {
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "user", "password");
PreparedStatement stmt = c.prepareStatement("DELETE FROM a WHERE id = 1");
try {
stmt.execute();
}
catch (SQLException e) {
System.out.println("Got a " + e.getClass().getName() + " with message " + e.getMessage());
}
}
}
When I ran this class, I got the following output:
Got a com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException with message Cannot delete or update a parent row: a foreign key constraint fails (`test`.`b`, CONSTRAINT `a_fk` FOREIGN KEY (`a_id`) REFERENCES `a` (`id`))
My code can catch this exception, so why can't yours? Well, with the almost total absence of any of your code, I can only offer a couple of speculative answers:
the exception is caught somewhere inside the try block and perhaps wrapped and rethrown,
the code in the try block starts a new Thread, and the exception is thrown in the new thread.

Related

using sequence in namedparameterJDBCTemplate for insertion into two tables

how to use sequence in namedparameterJDBCTemplate for insertion into two tables ?
Database- orcale
springjdbcnamedparametertemplate .
my Dao is looking like this
#Override
public void insert(Message message) {
String SQL = "INSERT into mssg (mssg_id, mssg_text, mssg_channel)"
+ " values (mssg_sequence.nextval,:mssg_text,:mssg_channel)";
String SQLMessage_app = "INSERT into message_app(mssg_app_type,mssg_id)"
+ "values(:mssg_app_type,mssg_sequence.currval)";
namedParameterJdbcTemplate.update(SQL,
new BeanPropertySqlParameterSource(message));
namedParameterJdbcTemplate.update(SQLMessage_app,
new BeanPropertySqlParameterSource(message));
}
oracle tables are these
This is the first table
create table mssg (
mssg_id number(10) NOT NULL,
mssg_text varchar2(25)NOT NULL,
mssg_channel varchar(25)NOT NULL,
constraint pk_mssg_id PRIMARY KEY(mssg_id)
);
Create sequence mssg_sequence
start with 1
increment by 1
minvalue 1
maxvalue 100000;
This is the second table
CREATE TABLE MESSAGE_APP(
mssg_app_type VARCHAR2(25),
mssg_id NUMBER(10),
CONSTRAINT fk_mssg
FOREIGN KEY(mssg_id)
REFERENCES mssg(mssg_id)
ON DELETE CASCADE);
COMMIT;
iam getting this error :
org.springframework.jdbc.UncategorizedSQLException:
PreparedStatementCallback; uncategorized SQLException for SQL [INSERT
into
message_app(mssg_app_type,mssg_id)values(?,mssg_sequence.currval)];
SQL state [72000]; error code [8002]; ORA-08002: sequence
MSSG_SEQUENCE.CURRVAL is not yet defined in this session ; nested
exception is java.sql.SQLException: ORA-08002: sequence
MSSG_SEQUENCE.CURRVAL is not yet defined in this session
can anybody help me to insert data into two tables by using sequence???
Thanks in advance :)

Adding a new record to a database with java prepared statements

I am creating a method to load in vales from an interface to create a new record in my database.
I have tried several methods and keep getting different errors.
Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '939' for key 'PRIMARY'
public boolean newStudent(String studentId, String name, String degreeScheme) throws SQLException
{
// Use SIMPLEDATASOURCE connection
Connection conn = SimpleDataSource.getConnection();
Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'student_name = 'mark' degree_Scheme = 'cis'' at line 1
try {
conn.createStatement();
PreparedStatement stat = conn.prepareStatement( "UPDATE student SET studentId = ?");
stat.setString(1,studentId); // Use parameter
stat.executeUpdate(); // Execute prepared stat
return stat.executeUpdate() == 1 ;
}
finally
{
// Close the connection
conn.close();
}
}
Was there a question in there somewhere?
Duplicate entry '939' for key 'PRIMARY'
This indicates that you are either inserting a row or updating a row to have a PRIMARY KEY value that already exists in the table. (The value of the column(s) making up the PRIMARY KEY must be UNIQUE on each row; no two rows can have the same value.)
This query:
UPDATE student SET studentId = ?
Is going to attempt to set the studentId column to the same value on every row.
We're guessing that studentId is defined as the PRIMARY KEY of the student table, and that the table contains more than one row. We'd expect the execution of this statement to throw a "duplicate key" exception, like the one you are reporting.

Preventing from Multiple primary key error

This is my code for executing in my java program:
public static void createBooksTablesAndSetPK() {
String selectDB = "Use lib8";
String createBooksTable = "Create table IF NOT EXISTS books (ID int,Name varchar(20),ISBN varchar(10),Date date )";
String bookTablePK = "ALTER TABLE BOOKS ADD PRIMARY KEY(id)";
Statement st = null;
try (
Connection con = DriverManager.getConnection(dbUrl, "root", "2323");) {
st = con.createStatement();
st.execute(selectDB);
st.execute(createBooksTable);
st.execute(bookTablePK);
} catch (SQLException sqle) {
sqle.printStackTrace();
}
}
I cat use IF NOT EXIST for creating databasesand tables to prevent creating duplicate database and tables and corresponding errors.
But i don't know how prevent Multiple primary key error, because program may call createBooksTablesAndSetPK() multiple times.
Error:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Multiple primary key defined
The column Book_id is not existing in your case. You are creating a table with ID as the column and then updating the table with a PRIMARY KEY constraint on a column that is not existing.
Create table IF NOT EXISTS books (ID int,Name varchar(20),ISBN varchar(10),Date date )
ALTER TABLE BOOKS ADD PRIMARY KEY(BOOK_id)
Try running these statements on a MySQL command prompt (or MySql Workbench) and the see the error.
You need change the alter table command like this.
ALTER TABLE BOOKS ADD BOOK_id VARCHAR( 255 ), ADD PRIMARY KEY(BOOK_id);

Java PreparedStatement and ON DUPLICATE KEY UPDATE: how do I know whether row was inserted or updated?

Having following code, how do I know if the execute() method resulted in insert or in update?:
Connection c = DriverManager.getConnection(connectionString);
PreparedStatement st = c.prepareStatement("INSERT INTO `table`(`field1`) VALUES (?) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);");
st.setString(1,"some value");
st.execute();
Thanks in advance.
Consider the following MySQL test table:
CREATE TABLE `customers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
with existing sample data as follows:
id name email
-- -------------- ----------------
1 Loblaw, Bob bob#example.com
2 Thompson, Gord gord#example.com
With the default connection setting compensateOnDuplicateKeyUpdateCounts=false (described here) the following Java code
PreparedStatement ps = dbConnection.prepareStatement(
"INSERT INTO customers (name, email) " +
"VALUES (?, ?) " +
"ON DUPLICATE KEY UPDATE " +
"name = VALUES(name), " +
"id = LAST_INSERT_ID(id)");
ps.setString(1, "McMack, Mike");
ps.setString(2, "mike#example.com");
int euReturnValue = ps.executeUpdate();
System.out.printf("executeUpdate returned %d%n", euReturnValue);
Statement s = dbConnection.createStatement();
ResultSet rs = s.executeQuery("SELECT LAST_INSERT_ID() AS n");
rs.next();
int affectedId = rs.getInt(1);
if (euReturnValue == 1) {
System.out.printf(" => A new row was inserted: id=%d%n", affectedId);
}
else {
System.out.printf(" => An existing row was updated: id=%d%n", affectedId);
}
produces the following console output
executeUpdate returned 1
=> A new row was inserted: id=3
Now run the same code again with the parameter values
ps.setString(1, "Loblaw, Robert");
ps.setString(2, "bob#example.com");
and the console output is
executeUpdate returned 2
=> An existing row was updated: id=1
This demonstrates that .executeUpdate really can return 2 if the unique index causes an existing row to be updated. If you require further assistance with your actual test code then you should edit your question to include it.
Edit
Further testing reveals that .executeUpdate will return 1 if
the attempted INSERT is aborted because it would result in a duplicate UNIQUE key value, and
the specified ON DUPLICATE KEY UPDATE changes do not actually modify any values in the existing row.
This can be confirmed by running the above test code twice in a row with the exact same parameter values. Note that the UPDATE ... id = LAST_INSERT_ID(id) "trick" does ensure that the correct id value is returned.
That probably explains OP's test results if the only value being inserted was the UNIQUE key value.
Use executeUpdate instead as it returns an int row count.
UPDATE 1: According to the MySQL INSERT ... ON DUPLICATE KEY UPDATE documentation:
With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if
the row is inserted as a new row, and 2 if an existing row is updated.
UPDATE 2: INSERT IGNORE may also be an option:
INSERT IGNORE INTO `table`(`field1`) VALUES (?)
executeUpdate should return 1 when a new row is inserted and 0 when there is a duplicate.

MySQL Transactional delete and Java

I've got tables like this:
Table A:
`id | name`
Table B:
`id | A_id | ....`
A_id is a foreign key to Table A, the Engine is InnoDB
This is the code that fails:
String[] cleanupQueries = new String[] { "DELETE FROM B WHERE A_id = (SELECT id FROM A WHERE name = 'test')",
"DELETE FROM A WHERE name = 'test'" };
Connection connection;
try {
connection = DriverManager.getConnection(getConnectionString());
connection.setAutoCommit(false);
} catch (SQLException e) {
throw new RuntimeException("Error establishing a database connection!");
}
try {
for(String cleanupQuery : cleanupQueries) {
PreparedStatement statement = connection.prepareStatement(cleanupQuery);
statement.executeUpdate(); //FAILS WHEN EXECUTING THE SECOND QUERY
}
} catch(SQLException e) {
throw new RuntimeException("Error while executing the queries in the transactional context!");
}
try {
connection.commit();
} catch (SQLException e) {
rollback(connection);
throw new RuntimeException("Error while comitting!");
}
The Exception i get is:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails ('DATABASE/TABLE', CONSTRAINT 'FK_B_A' FOREIGN KEY ('FK_A') REFERENCES 'A' ('ID') ON DEL)
The database doesn't let me delete A while there are still B's left, but the first query deleted all B's. I want to delete all B's and the A they reference only completely.
I don't want to change the Tables to have cascading deletes. What shall i do to get the code working?
Cause for error is
The Foreign Key has referenced to the table A id so if you would like to delete the F_Key , first you should delete the Child references values of that foreign keys then only its possible to delete the parent.
Correct me if 'm wrong..
Simply add the cascade is true while deleting the foreign key constraint.The child table entry is automatically deleted when you delete the original parent entry.
Try:
"DELETE FROM B WHERE A_id = (SELECT id FROM A WHERE name IN 'test')"
Since the child rows are deleted in the same transaction, the deleted rows are still visible and thus the parent rows could not be deleted.
This may be because of the transaction isolation setting on the connection. I would try different levels and see which one allows it.

Categories