I'm trying to add designation and its salary using a JDBC transaction.
The problem is this throws an exception about duplicate key.
This is the first time I put some invalid data in salary columns and after that everything is correct. It shows duplicate key exception for designation id
but the designation id is not stored already and not even for first attempt.
The first transaction that is invalid is rolled back, but storing on next time it shows duplicate key exception.
Below is my code:-
public boolean addDesignation(ObservableList nodeList) throws SQLException {
Connection demo = getConnection();
demo.setAutoCommit(false);
Savepoint savePoint = demo.setSavepoint("savePoint");
try {
PreparedStatement addDesig = demo.prepareStatement(
"INSERT INTO `designation`(`desig_id`,`dept_id`,`desig_name`,`desig_desc`) VALUES (?,?,?,?)");
PreparedStatement addSal = demo.prepareStatement("INSERT INTO `salary` "
+ "(`desig_id`, `basic`, `house_rent`, `conveyance`, `medical`, `dearness`,`others_allowances`,"
+ " `income_tax`, `pro_tax`, `emp_state_insu`, `absence_fine`, `others_deductions`, `month`)"
+ " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)");
addDesig.setString(1 , nodeList.get(0).toString());
addDesig.setString(2, nodeList.get(1).toString());
addDesig.setString(3, nodeList.get(2).toString());
addDesig.setString(4, nodeList.get(3).toString());
addDesig.executeUpdate();
addSal.setString(1, nodeList.get(0).toString());
addSal.setInt(2, Integer.parseInt(nodeList.get(4).toString()));
addSal.setInt(3, Integer.parseInt(nodeList.get(5).toString()));
addSal.setInt(4, Integer.parseInt(nodeList.get(6).toString()));
addSal.setInt(5, Integer.parseInt(nodeList.get(7).toString()));
addSal.setInt(6,Integer.parseInt(nodeList.get(8).toString()));
addSal.setInt(7,Integer.parseInt(nodeList.get(9).toString()));
addSal.setInt(8, Integer.parseInt(nodeList.get(10).toString()));
addSal.setInt(9, Integer.parseInt(nodeList.get(11).toString()));
addSal.setInt(10, Integer.parseInt(nodeList.get(12).toString()));
addSal.setInt(11, Integer.parseInt(nodeList.get(13).toString()));
addSal.setInt(12, Integer.parseInt(nodeList.get(14).toString()));
addSal.setString(13, nodeList.get(15).toString());
addSal.executeUpdate();
demo.commit();
return true;
} catch (SQLException ex) {
demo.rollback(savePoint);
Logger.getLogger(DatabaseHandler.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
these are two tables and im trying to add that data in my first attempt failed but not store due roll back
There are 2 INSERT statements in your code.
The 1st for designation table:
"INSERT INTO `designation`(`desig_id`,`dept_id`,`desig_name`,`desig_desc`) VALUES (?,?,?,?)"
here it looks like desig_id is the primary key (maybe autoincrement in which case you must not supply a value at all).
Are you sure the value that you supply for this column does not already exist in the table?
The 2nd for the salary table:
"INSERT INTO `salary` " + "(`desig_id`, `basic`, `house_rent`, `conveyance`, `medical`, `dearness`,`others_allowances`," + " `income_tax`, `pro_tax`, `emp_state_insu`, `absence_fine`, `others_deductions`, `month`)" + " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"
in this case it is not clear since you did not post the CREATE statement of the table, which is the primary key.
So you have to check, if the value (or values if it's a multi column key), violate the uniqueness of the key.
Related
Go easy on me, middle school teacher taking a CS class. I've got a Java program that asks for user name, height, weight, does some calculations and gives results to the user. I now need to store this data in a database. I can get the data to store until I start using primary and foreign keys.
Here is the error I can't figure out:
Error: java.sql.SQLIntegrityConstraintViolationException: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL180429151131780' defined on 'USERPROFILE'.
Here is my table:
drop table stayfitapp.userdata;
drop table stayfitapp.userprofile;
drop schema stayfitapp restrict;
create schema stayfitapp;
create table stayfitapp.userprofile
(
profileName varchar(255) not null primary key,
profileGender varchar(255) not null
);
create table stayfitapp.userdata
(
profileAge double not null,
profileWeight double not null,
profileHeight double not null,
profileWaistCircumference double not null,
profileHipCircumference double not null,
profileName varchar(255),
foreign key (profileName) references stayfitapp.userprofile(profileName)
);
Here is the section of the "app" that writes to the table...
public void save(){
try {
String query = "insert into stayfitapp.userprofile" + "(profileName, profileGender)" + "values" + "(?,?)";
String query2 = "insert into stayfitapp.userdata" + "(profileAge, profileWeight, profileHeight, profileWaistCircumference, profileHipCircumference)" + "values" + "(?,?,?,?,?)";
Connection myConnection = DriverManager.getConnection("jdbc:derby://localhost:1527/stayfitDB2", "username", "password");
Statement myStatement = myConnection.createStatement();
//Statement myStatement2 = myConnection.createStatement();
PreparedStatement prepared = myConnection.prepareStatement(query);
prepared.setString(1, profileName);
prepared.setString(2, profileGender);
PreparedStatement prepared2 = myConnection.prepareStatement(query2);
prepared2.setDouble(1, profileAge);
prepared2.setDouble(2, profileWeight);
prepared2.setDouble(3, profileHeight);
prepared2.setDouble(4, profileWaistCircumference);
prepared2.setDouble(5, profileHipCircumference);
int rowsAffected = prepared.executeUpdate();
int rowsAffected2 = prepared2.executeUpdate();
if(rowsAffected==0)
{
System.out.println("Warning: User data did not save!");
}
else
{
System.out.println("User info saved!");
}
}
catch(SQLException e)
{
System.out.println("Error: "+e.toString());
}
Your save() method will attempt to add the user to the stayfitapp.userprofile table. This table has a field called profileName. profileName is the "primary key" so no duplicate values are allowed.
The error that you are getting is saying that you cannot add(insert) the record to the table because the table already has a record with the same name.
Does your program work okay if you use a different name each time?
You will need to add some logic to your program to deal with the scenario where the profileName already exists in the table. This will probably involve deleting or updating the existing record.
This is the problem.
insert into stayfitapp.userprofile"
+ "(profileName, profileGender)" + "values" , etc
You have nothing to check to see if a record already exists. Something like this would work better.
insert into stayfitapp.userprofile
profileName, profileGender
select distinct ?, ?
from someSmallTable
where not exists (
select 1
from stayfitapp.userprofile
where profileName = ?
)
The someSmallTable bit depends on your database engine, which you didn't specify.
I ended up writing a method to check if the username was already in the profile table. If the username was a duplicate I only wrote to the data table. If the username was new I wrote to both tables.
Thank you for your help! I'm sure there was a more efficient method (figuratively and literally) but I'm on to my final project and nearly surviving an actual CS class.
I have table without unique index tuples, lets say table has records
A->B->Status
A->C->Status
A->B->Status
A->B->Status
A->C->Status
I am getting first and second record, processing them. After then I want to update only these two records
how can I make this process possible at java application layer?
Since there is not any unique index tupples I cannot use update SQL with proper WHERE clause
Using
Spring 3.XX
Oracle 11g
I think you may try to use ROWID pseudocolumn.
For each row in the database, the ROWID pseudocolumn returns the address of the row. Oracle Database rowid values contain information necessary to locate a row:
The data object number of the object
The data block in the datafile in which the row resides
The position of the row in the data block (first row is 0)
The datafile in which the row resides (first file is 1). The file
number is relative to the tablespace.
Usually, a rowid value uniquely identifies a row in the database. However, rows in different tables that are stored together in the same cluster can have the same rowid.
SELECT ROWID, last_name
FROM employees
WHERE department_id = 20;
The rowid for the row stays the same, even when the row migrates.
You can solve this issue by using updatable resultsets. This feature relies on rowid to perform all modifications (delete/update/insert).
This is a excerpt highlighting the feature itself:
String sqlString = "SELECT EmployeeID, Name, Office " +
" FROM employees WHERE EmployeeID=1001";
try {
stmt = con.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery(sqlString);
//Check the result set is an updatable result set
int concurrency = rs.getConcurrency();
if (concurrency == ResultSet.CONCUR_UPDATABLE) {
rs.first();
rs.updateString("Office", "HQ222");
rs.updateRow();
} else {
System.out.println("ResultSet is not an updatable result set.");
}
rs.close();
} catch(SQLException ex) {
System.err.println("SQLException: " + ex.getMessage());
}
Here is a complete example.
Mysql tables
mysqltables
This is my query to insert data to the database.
public void voegSpelerToe(Speler speler, String spelNaam)
{
PreparedStatement invoerSpeler;
Speler huidigeSpeler = null;
try
{
Connection connection = PersistentieController.getInstance().getConnection();
invoerSpeler = connection.prepareStatement("INSERT INTO Speler " + "(naam, kleur, sector, aantalZilverstukken, Spel_naam) " + "VALUES ( ?, ?,?, ?, ?)");
invoerSpeler.setString(1, speler.getNaam());
invoerSpeler.setString(2, speler.getKleur());
invoerSpeler.setInt(3, speler.getSector().getCode());
invoerSpeler.setInt(4,speler.getKrediet());
invoerSpeler.setString(5, spelNaam);
invoerSpeler.executeUpdate();
} catch (SQLException sqlException)
{
sqlException.printStackTrace();
} finally
{
// PersistentieController.getInstance().closeConnection();
}
}
Everything has a value so I don't have nullexeptions.
But when I want to save the data I get this error:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`projecteng62`.`speler`, CONSTRAINT `fk_Speler_Spel1` FOREIGN KEY (`Spel_naam`) REFERENCES `spel` (`naam`) ON DELETE CASCADE ON UPDATE CASCADE)
How can I insert data in the foreign key.
First It save data to the table Spel
and then i need to save data in the table speler but I get a problem wit the foreign Key.
Like table spel:
naam: Game12
aantalTeSPelenRondes: 2
table Speler:
naam : player1
kleur : green
sector : 2
aantalZilverStukken : 10
Spel_Naam: game12
Spel_naam must be the same as naam in table Spel
It is telling you that it is expecting the contents of Spel_Naam to exist in some row in spels naam attribute, but it does not exist.
To fully figure out the issue I would also need to see where you are inserting into spel.
But in the example input you provided
naam: Game12
Spel_Naam: game12
there is an issue because one is capitalized and the other is not. If this is actually how the data is set up, then that is likely your problem. But it seems you have the right idea, you need to insert into naam first, then into Spel_Naam.
I'm trying to insert a row into a table that has an increment id with CachedRowSet(I'm using Java wit Java DB), but I got the following SQLException:
java.sql.SQLException: Failed on insert row
at...
SQLState: null
Error Code: 0
Message: Failed on insert row
Here's my code snippet:
private static String urlString = "jdbc:derby:testdb;create=true";
private static String userName = "testUser";
private static String password = "testPassword";
...
CachedRowSet crs = new CachedRowSetImpl();
crs.setUrl(urlString);
crs.setUsername(userName);
crs.setPassword(password);
crs.setCommand("SELECT * FROM test_table");
crs.execute();
crs.moveToInsertRow();
crs.updateString("str_value", "testValue");
crs.insertRow();
crs.moveToCurrentRow();
crs.acceptChanges();
The SQLException is thrown from crs.inertRow().
The CachedRowSet works well if the table does not have an auto increment id.
How can I successfully do this?
other details:
I use the following code to create my table:
conn = DriverManager.getConnection(urlString, userName, password);
Statement stmt = conn.createStatement();
stmt.execute("CREATE TABLE test_table("
+ "id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),"
+ "str_value VARCHAR(20) NOT NULL,"
+ "CONSTRAINT primary_key PRIMARY KEY (id))");
System.out.println("Talbe test_table created.");
This is a duplicate of Failed on insert row using CachedRowSet.
Unfortunately, that happens because of the API definition:
Throws:
SQLException - if a database access error occurs; the result set concurrency is CONCUR_READ_ONLY, this method is called on a closed result set, if this method is called when the cursor is not on the insert row, or if not all of non-nullable columns in the insert row have been given a non-null value
You may be better off using JdbcRowSetImpl.
You can only stick with the CachedRowSet if you remove the NOT NULL constraint of the id column. Unfortunately, this would also mean to remove the PK constraint. I'd assume that is too big a sacrifice, but it's either that or no CachedRowSet.
try this
crs.updateNull(1);
crs.insertRow();
where 1 is your PK. Worcked for me in MySQL
I have a fragment of code in Java which inserts data into my database.
I was advised to put AUTO_INCREMENT and give each row a unique number.
But it now gives me an error:
java.sql.SQLException: Incorrect integer value: 'DEFAULT' for column
'usersID' at row 1
I assume this is because it's casting the AUTO_INCREMENT value into a string?
How do I get around this as it's not my java program that creates the unique number, but the database itself.
pst.setString(1, "DEFAULT");
String query_to_update = "INSERT INTO `evidence_db`.`mcases` ("
+ "`PID`,"
+ "`Name`) "
+ "VALUES (?,?);";
pst.setInt(1, 0);
Above was the line that I needed. Thanks to all that tried to be helpful.