Duplicate entry for primary key - registration form - java

I have one simple registraton form with jsp, servlet and mysql. But, I can register only one user, then i got this error:
Severe: Message: Duplicate entry '1' for key 'PRIMARY'. Of course, when I delete that user from database I can create again but just one user. Also, I put auto increment on that column:
CREATE TABLE user (id int(3) NOT NULL AUTO_INCREMENT ...
This is also my method for insert in db:
public class UserDAO {
public int registerUser(User User) throws ClassNotFoundException, SQLException {
String INSERT_USERS_SQL = "INSERT INTO user"
+ " (id, firstName, lastName, username, password, email) VALUES "
+ " (?, ?, ?, ?, ?, ?)";
int result = 0;
Class.forName("com.mysql.jdbc.Driver");
try (Connection connection = DriverManager
.getConnection("jdbc:mysql://localhost:3306/cs230projekat","root","");
// Step 2:Create a statement using connection object
PreparedStatement preparedStatement = connection.prepareStatement(INSERT_USERS_SQL)) {
preparedStatement.setInt(1, 1);
preparedStatement.setString(2, User.getFirstName());
preparedStatement.setString(3, User.getLastName());
preparedStatement.setString(4, User.getUsername());
preparedStatement.setString(5, User.getPassword());
preparedStatement.setString(6, User.getEmail());
System.out.println(preparedStatement);
// Step 3: Execute the query or update query
result = preparedStatement.executeUpdate();
} catch (SQLException e) {
// process sql exception
printSQLException(e);
}
return result;
}
Thank you.

You are always setting the value of your id column to 1 via preparedStatement.setInt(1, 1). Since you say you have an auto-increment on the id column, remove id from your SQL, remove the aforementioned line and adjust the column indexes (first arguments) for all the other setString() method calls.

With auto increment set you don’t have to specify the ‘id’ column in your sql insert statements.
Here’s some information on the auto increment from MySQL’s website: https://dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html

From your code it looks like you are inserting the value 1 always for the id column, try implementing the autoGenerate properly. For more help, you can have a look on similar implementation

Related

Prepared statement and serial data type

This is my PostgreSQL code:
CREATE TABLE "user" (
id serial UNIQUE,
username varchar,
password varchar,
email varchar,
);
I want to create Java method, which adds new user to my table user:
public static void addUser(Connection con) throws SQLException {
String sql = "INSERT INTO user VALUES (?, ?, ?)";
try(PreparedStatement ps = c.prepareStatement(sql)) {
ps.setString(1, "test");
ps.setString(2, "test");
ps.setString(3, "test#email.com");
ps.executeUpdate();
}
}
}
Because column id is serial, I don't create prepared statement for this column (even without java, I would make insert only with remaining values, since id would be generated automatically). Hovewer, when I run this code, I get the following error:
ERROR: column "id" is of type integer but expression is of type character varying
What am I doing wrong?
Always specify the target columns in an INSERT statement. And as user is a reserved keyword, you have to quote it (but it would be better if you found a different name)
String sql = "INSERT INTO \"user\" (username, password, email) VALUES (?, ?, ?)";

How to get generated ID after inserting new record in database table using Spring JDBCTemplate?

I know that this is an duplicated question but the other solutions on the other pages isn't working for me.
I have a Oracle database and I want to fetch inserted record ID (primary key) but I'm unable to do so. Below is the error and my code.
org.springframework.dao.DataRetrievalFailureException: The generated
key is not of a supported numeric type. Unable to cast
[oracle.sql.ROWID] to [java.lang.Number]
String query = "INSERT INTO JOBS (USERNAME, CREATED_ON, STATUS, JOBTYPE, DATA) " + "VALUES (?, ?, ?, ?, ?)";
try {
KeyHolder holder = new GeneratedKeyHolder();
jdbcTemplate.update(new PreparedStatementCreator() {
#Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement ps = con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, "username");
ps.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
ps.setString(3, "status");
ps.setString(4, "jobtype");
ps.setString(5, "job-data");
return ps;
}
}, holder);
System.out.println("Holder tostring: " + holder.toString());
System.out.println("Ran an update statement and got generated key. Key = " + holder.getKey().intValue());
System.out.println("Key: " + holder.getKey().longValue());
return true;
} catch (DataAccessException e) {
System.err.println("Exception thrown inserting record into table. Error: " + e.getMessage());
e.printStackTrace();
}
When I run the app in debug mode I'm seeing holder variable keyList value is: [{ROWID=AAAKy2AAAAALRgdAAD}] I'm not getting the inserted record Id.
Create table script is:
CREATE TABLE JOBS (
ID INTEGER GENERATED ALWAYS AS IDENTITY(START WITH 1 INCREMENT BY 1),
USERNAME VARCHAR2(20) NOT NULL,
CREATEDON TIMESTAMP NOT NULL,
STATUS VARCHAR2(10) NOT NULL,
JOBTYPE VARCHAR2(15) NOT NULL,
DATA VARCHAR2(1000 CHAR) NOT NULL,
PRIMARY KEY(ID)
);
When you use con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS), the Oracle JDBC driver will not return the value of the id column, but instead it will return the ROW_ID (a pseudo column that identifies a specific row), to allow you to retrieve the value yourself.
Historically the Oracle driver did it this way, because previous Oracle versions didn't have identity columns.
Instead you should use:
con.prepareStatement(query, new String[] { "ID" });
Which instructs Oracle to return the value of the specified column.

Delete query with integer variable not working

My database contains one column having data type as Integer. I want to delete record using that column value but i'm getting an error.
Here is my code
int id=Integer.parseInt(JOptionPane.showInputDialog(null,"Enter ID to serach"));
//....code
st.executeUpdate("delete from Table where ID='"+id+"'");
I'm getting following error:
Data type mismatch in criteria expression.
you pass a VARCHAR value in your query:
delete from Table where ID='"+id+"'"
just remove the ' and try it again.
I bet your ID is of type NUMBER.
Furthermore I suggest you to use an PreparedStatement to add the Integer value:
delete from Table where ID=?
Otherwise you could have some security problems.
Simple change to :
st.executeUpdate("delete from Table where ID = "+id);
OR
SQLiteDatabase _db = null;
DataBaseHelper _dbHelper = new DataBaseHelper(_context, name, null, 1);
_db = _dbHelper.getWritableDatabase();
_db.delete(TABLE, _ID + "=?", new String[]{id});
So you are inserting integer and not character.Thus no need of single quote around value you are inserting ie int value.It should be
st.executeUpdate("DELETE FROM Table WHERE ID="+id);
It is good practice to have main key words/clauses in Uppercase.And one more, always try to use PreparedStatement rather simple Statement.
EDIT
PreparedStatement Example to insert into database
String insertTableSQL = "INSERT INTO DBUSER"
+ "(USER_ID, USERNAME, CREATED_BY, CREATED_DATE) VALUES"
+ "(?,?,?,?)";
PreparedStatement preparedStatement = dbConnection.prepareStatement(insertTableSQL);
preparedStatement.setInt(1, 11);
preparedStatement.setString(2, "mkyong");
preparedStatement.setString(3, "system");
preparedStatement.setTimestamp(4, getCurrentTimeStamp());
// execute insert SQL stetement
preparedStatement .executeUpdate();

Using Oracle sequence to insert log id into 2 tables from jdbc?

I am using oracle sequence for inserting log id into tableA as follows,
String SQL_PREP_INSERT = "INSERT INTO tableA (LOG_ID,USER_ID,EXEC_TIME) VALUES"
+ " (logid_seq.nextval, ?, ?)";
Then getting the recently inserted value,
String SQL_PREP_SEL = "SELECT max(LOG_ID) FROM tableA ";
stmt = con.prepareStatement(SQL_PREP_SEL);
stmt.execute();
ResultSet rs = stmt.getResultSet();
if (rs.next()) {
logid = rs.getInt(1);
}
And inserting it into tableB,
String SQL_PREP_INSERT_DETAIL = "INSERT INTO tableB (LOG_ID, RESPONSE_CODE, RESPONSE_MSG) VALUES"
+ " (?, ?)";
stmt = con.prepareStatement(SQL_PREP_INSERT_DETAIL);
stmt.setInt(1, logid);
stmt.setString(2, respCode);
stmt.setString(3, respMsg);
stmt.execute();
Is there a way to generate sequence in Java instead of Oracle and insert into both tables at once, instead of selecting from tableA and inserting into tableB?
In general, selecting the MAX(log_id) is not going to give you the same value that logid_seq.nextval provided. Assuming that this is a multi-user system, some other user could have inserted another row with a larger log_id value than the row you just inserted before your query is executed.
Assuming that both INSERT statements are run in the same session, the simplest option is probably to use the logid_seq.currval in the second INSERT statement. currval will return the last value of the sequence that was returned to the current session so it will always return the same value that was generated by the nextval call in the first statement.
INSERT INTO tableB (LOG_ID, RESPONSE_CODE, RESPONSE_MSG)
VALUES( logid_seq.currval, ?, ? )
Alternatively, you could use the RETURNING clause in your first statement to fetch the sequence value into a local variable and use that in the second INSERT statement. But that is probably more work than simply using the currval.
String QUERY = "INSERT INTO students "+
" VALUES (student_seq.NEXTVAL,"+
" 'Harry', 'harry#hogwarts.edu', '31-July-1980')";
// load oracle driver
Class.forName("oracle.jdbc.driver.OracleDriver");
// get database connection from connection string
Connection connection = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:sample", "scott", "tiger");
// prepare statement to execute insert query
// note the 2nd argument passed to prepareStatement() method
// pass name of primary key column, in this case student_id is
// generated from sequence
PreparedStatement ps = connection.prepareStatement(QUERY,
new String[] { "student_id" });
// local variable to hold auto generated student id
Long studentId = null;
// execute the insert statement, if success get the primary key value
if (ps.executeUpdate() > 0) {
// getGeneratedKeys() returns result set of keys that were auto
// generated
// in our case student_id column
ResultSet generatedKeys = ps.getGeneratedKeys();
// if resultset has data, get the primary key value
// of last inserted record
if (null != generatedKeys && generatedKeys.next()) {
// voila! we got student id which was generated from sequence
studentId = generatedKeys.getLong(1);
}
}

Error setting mysql primary key field with preparedStatement

This is my code for inserting a row. The columns are: primary id, name, and artist.
Am I passing the primary id correctly because it keeps on giving me an error? It is set to one and it increments every time a row is added.
try {
//Database
String query = "INSERT INTO lyrics1(lyrics1_id, name, artist) values(?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(2, nameOfSong.getText()); // set input parameter 2
statement.setString(3, artist.getText());
statement.setLong(i, i);
ResultSet rs = statement.executeQuery("SELECT * FROM lyrics1");
while (rs.next()){
System.out.println(rs.getString(1));
}
statement.execute();
rs.close();
statement.close();
connection.close();
i++;
} catch (SQLException insertException) {
displaySQLError(insertException);
}
The error is:
SQLException: No value specified for parameter 1 SQLState: 07001 VendorError: 0
If your primary key is AUTO_INCREMENT, which it sounds like it is, you do not pass it with the INSERT statement, it is handled automatically for you. This would be what you want to do:
INSERT INTO lyrics1(name, artist)
VALUES(?, ?)
(This assumes your primary key isn't AUTO_INCREMENT and that you're passing it for a reason.)
I think you have a simple typo:
statement.setLong(i, i);
should probably be
statement.setLong(1, i);
// ^-- 1, not i
Being an old fuddy-duddy, I'd also probably move that statement above the other two so you're doing them in order.
If you have auto_increment in primary key:
String query = "INSERT INTO lyrics1(name, artist) values(?, ?)";
Don't forget to add the quotes when inserting a TEXT or VARCHAR value, like "INSERT INTO lyrics1(lyrics1_id, name, artist) VALUES ("id","name","artist").
Also, if the key is auto-incremental, do not pass it, the SQL will do it by itself. The query should then be "INSERT INTO lyrics1(name, artist) VALUES ("name","artist")."
As far as I know, you should have a ; in the string at the end like so:
String query = "INSERT INTO lyrics1(lyrics1_id, name, artist) values(?, ?, ?)";
however, it may work anyway.
You have a typo on the line you setting a value for primary key:
statement.setLong(i, i);
Here, did you see the first argument, it is i instead of 1. So it has to be changed to
statement.setLong(1, i);
But, if you ran the program for a second time, if the value of your i is initialized to a constant, you will get a primary key violation exception. Since, you are using MySQL, and if you used AUTO_INCREMENT for primary key column, then you can avoid that field in INSERT query. MySQL will automatically assign a value for the field. So you may use something like this:
INSERT INTO lyrics1(name, artist) values(?, ?)

Categories