Integrity constraint violation: unique constraint or index violation HSQLDB - java

For example if I add new Department(new BigInteger("50"), "ODD", "SPB"), all work, it values are insert into database. But if I want again insert for example new Department(new BigInteger("50"), "ODDMOD", "SPBMOD"), appear java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: unique constraint or index violation; SYS_PK_10092 table: DEPARTMENT. I know that can not insert values with the same primary key, but how can update values if primary key exists or other solutions?
public Department save(Department department) throws SQLException {
Connection connection = ConnectionSource.instance().createConnection();
String sql = "insert into department values (?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setLong(1, Long.parseLong(String.valueOf(department.getId())));
statement.setString(2, department.getName());
statement.setString(3, department.getLocation());
statement.executeUpdate();
PreparedStatement st = connection.prepareStatement("select * from department where id = ? ");
st.setLong(1, Long.parseLong(String.valueOf(department.getId())));
ResultSet resultSet = st.executeQuery();
resultSet.next();
Department demper = new Department(
new BigInteger(String.valueOf(resultSet.getInt("id"))),
resultSet.getString("name"),
resultSet.getString("location")
);
return demper;
}

You want an upsert here:
public Department save(Department department) throws SQLException {
Connection connection = ConnectionSource.instance().createConnection();
String sql = "MERGE INTO department d1 " +
"USING (VALUES ?, ?, ?) d2 (id, name, location) " +
" ON (d1.id = d2.id) " +
" WHEN MATCHED THEN UPDATE SET " +
" d1.name = d2.name, d1.location = d2.location " +
" WHEN NOT MATCHED THEN INSERT (id, name, location) VALUES (d2.id, d2.name, d2.location)";
PreparedStatement statement = connection.prepareStatement(sql);
// execute merge here as before
statement.setLong(1, Long.parseLong(String.valueOf(department.getId())));
statement.setString(2, department.getName());
statement.setString(3, department.getLocation());
statement.executeUpdate();
// ...
}
A MERGE behaves by doing an insert if the department id does not already exist in the table. Otherwise it will do an update. Note that if you shift to JPA/Hibernate from pure JDBC, the JPA save() method can upsert automatically for you under the hood.

Related

Populate child table with primary key from parent table

I have a customer table and an address table. I'm trying to automatically insert the primary key value into the address table. Initially, I had it the other way around and it worked, however, the relationship was wrong since I wasn't able to delete cascade when a customer was deleted. Information inserts into the customer table but not the address table. This is what I have. Any insight would be appreciated.
/**
* Add a new customer.
* #param customer The customer to be added.
* #return customerId.
* #throws SQLException If an error happens.
*/
public int addCustomer(Customer customer) throws SQLException {
// first insert the address of the customer
//int addressId = addAddress(customer.getAddress());
// next insert the customer
var sql = "INSERT INTO customer (customerId, customerName, active, createdBy)" +
" VALUES (?, ?, ?, ?)";
var statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
statement.setInt(1, 0);
statement.setString(2, customer.getName());
//statement.setInt(3, addressId);
statement.setBoolean(3, customer.isActive());
statement.setString(4, customer.getCreatedBy());
statement.execute();
var generatedKeys = statement.getGeneratedKeys();
generatedKeys.next();
return (int) generatedKeys.getLong(1);
}
/**
* Add a new address to the database.
* #param address The address to be added.
* #throws SQLException if an error happens.
*/
public void addAddress(Address address) throws SQLException {
int customerId = addCustomer(address.getCustomer());
var sql = "INSERT INTO address (addressId, customerId, address, address2, cityId, countryId, postalCode, phone, createdBy) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
var statement = connection.prepareStatement(sql);
statement.setInt(1, 0);
statement.setInt(2, customerId);
statement.setString(3, address.getAddress());
statement.setString(4, address.getAddress2());
statement.setInt(5, address.getCity().getId());
statement.setInt(6, address.getCountry().getId());
statement.setString(7, address.getPostalCode());
statement.setString(8, address.getPhone());
statement.setString(9, address.getCreatedBy());
statement.execute();
}
Got some help with just updating the delete customer method so it deletes the associated address along with the customer.
enter code here
public void deleteCustomer(Customer customer) throws Exception {
var appointments =
appointmentRepository.findCustomerAppointments(customer.getId());
if(!appointments.isEmpty()){
throw new RuntimeException("Constraint Violation");
}
var deleteAddress = "DELETE FROM address WHERE addressId = ?";
var statementDeleteAddress = connection.prepareStatement(deleteAddress);
statementDeleteAddress.setInt(1, customer.getAddress().getId());
statementDeleteAddress.execute();
var sql = "DELETE FROM customer WHERE customerId = ?";
var statement = connection.prepareStatement(sql);
statement.setInt(1, customer.getId());
statement.execute();

Insert int value of Resultset in SQL-Database

I'm working with a MySQL-Server and I'm trying to select an ID from another table and insert that ID in a table but it doesn't work all the time.
Code:
public void submit() throws Exception {
Connection connection = getConnection();
Statement stmt = connection.createStatement();
Statement stmt1 = connection.createStatement();
ResultSet asset_id = stmt.executeQuery("SELECT id FROM cars.asset_type WHERE asset_type.name =" + "'" + sellables.getValue()+ "'");
while (asset_id.next()) {
System.out.println(asset_id.getInt("id"));
}
double value = parseDouble(purchased.getText());
System.out.println(value);
LocalDate localDate = purchased_at.getValue();
String insert = "INSERT INTO asset (type_id, purchase_price, purchased_at) VALUES ('"+ asset_id + "','" + value +"','" + localDate +"')";
stmt1.executeUpdate(insert);
}
I keep getting the same error message.
Caused by: java.sql.SQLException: Incorrect integer value: 'com.mysql.cj.jdbc.result.ResultSetImpl#1779d92' for column 'type_id' at row 1
There's no value in doing two client/server roundtrips in your case, so use a single statement instead:
INSERT INTO asset (type_id, purchase_price, purchased_at)
SELECT id, ?, ?
FROM cars.asset_type
WHERE asset_type.name = ?
If you really want to insert only the last ID from your SELECT query (as you were iterating the SELECT result and throwing away all the other IDs), then use this query instead:
INSERT INTO asset (type_id, purchase_price, purchased_at)
SELECT id, ?, ?
FROM cars.asset_type
WHERE asset_type.name = ?
ORDER BY id DESC -- I guess? Specify your preferred ordering here
LIMIT 1
Or with the JDBC code around it:
try (PreparedStatement s = connection.prepareStatement(
"INSERT INTO asset (type_id, purchase_price, purchased_at) " +
"SELECT id, ?, ? " +
"FROM cars.asset_type " +
"WHERE asset_type.name = ?")) {
s.setDouble(1, parseDouble(purchased.getText()));
s.setDate(2, Date.valueOf(purchased_at.getValue()));
s.setString(3, sellables.getValue());
}
This is using a PreparedStatement, which will prevent SQL injection and syntax errors like the one you're getting. At this point, I really really recommend you read about these topics!

jdbcTemplate.update for auto incremented and unique ID field

I have an EMPLOYEE table that has 4 fields; ID, NAME, AGE, SALARY. ID is unique and auto-increment.
Below is the code to insert a row in the table, using Spring's JDBCTemplate. Please suggest, how can I auto increment ID field.
String sql = "insert into employee values (?,?,?,?)"
jdbcTemplate.update( sql, ID, bean.getName(), bean.getAge(), bean.getSalary())
I see, you tag your question Oracle, use Oracle sequence then.
String sql = "insert into Employee values (id_seq.nextval, ?, ?, ?)";
jdbcTemplate.update(sql, bean.getName(), bean.getAge(), bean.getSalary());
Ref: How to create Sequence in Oracle.
Just add following code to your domain:
Ref: http://docs.spring.io/spring/docs/2.5.x/reference/jdbc.html#jdbc-auto-genereted-keys
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
final String INSERT_SQL = "insert into my_test (name) values(?)";
final String name = "Rob";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(
new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps =
connection.prepareStatement(INSERT_SQL, new String[] {"id"});
ps.setString(1, name);
return ps;
}
},
keyHolder);

How to get id_user (primary key ()) in JDBC

I want to insert two rows into master and detail table.
Master and detail table with autoincremented id.
CREATE TABLE MI_User (
id_user NUMBER(11) NOT NULL,
age NUMBER(3),
name_user varchar2(128),
constraint USER_PK PRIMARY KEY (id_user));
CREATE TABLE Friends (
id_friend NUMBER(11) not null,
name VARCHAR2(64),
id_user NUMBER(11) NOT NULL,
constraint FRIEND_PK PRIMARY KEY (id_friend)
);
Model classes are:
public class User {
private String id;
private Integer age;
private String name;
private ArrayList<Friend> friends;
}
public class Friend {
private Long id_user;
private String name;
}
There is example from Hibernate:
tx = session.beginTransaction();
User user = new User(name, age);
employeeID = (Integer) session.save(employee);
tx.commit();
I try to insert with JDBS:
conn = DriverManager
.getConnection("jdbc:oracle:thin:#localhost:1521:xe", "hr", "hr");
ps = conn
.prepareStatement("INSERT INTO MI_USER (BALANCE, AGE, NAME_USER, GENDER, COMPANY, EMAIL, ADDRESS)\n" +
" VALUES (?, ?, ?, ?, ?, ?, ?)");
ps.setDouble(1, user.getDoubleBallans());
ps.setInt(2, user.getAge());
ps.setString(3, user.getName());
ps.executeUpdate();
How to get id_user and insert row into detail table?
I think you can use ps.getGeneratedKeys() method and send Statement.RETURN_GENERATED_KEYS as second parameter in conn.prepareStatement() method.

[Java]Error when Inserting SQL, auto increment in the table - userId

So I am making a registration page and when I enter all the fields and click signup to submit, enterNewUser(,,,) is called and the fields userId, username,password and role are inserted into the table User. I confirm this by running select * from user; into MYSQL workbench.
Then enterUsername(,,,) is called and I get this error:
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 '(3,'Barry','Allen')' at line 1
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
'(3,'Barry','Allen')' at line 1
public static int enterNewUser(String username,String password, String role){
//int userId = -1;
int ID = 0;
//int ID=-1;
try{
if(checkUserNameAvailable(username)==true){
Class.forName("com.mysql.jdbc.Driver");
cn = DriverManager.getConnection("jdbc:mysql://localhost/log", "root", "root");
String q0 = "Select userId from user ORDER BY userId DESC LIMIT 1"; //get ID of last
Statement st = cn.createStatement();
ResultSet rs = st.executeQuery(q0);
if(rs.next()){
ID = rs.getInt("userId");
ID++;
}
else
ID=1; // Empty Table, so start with ID 1
rs.close();
st.close();
String q1="insert into user values(?,?,?)";
PreparedStatement ps = cn.prepareStatement(q1);
//ps.setInt(1,ID);
ps.setString(1,username);
ps.setString(2,password);
ps.setString(3,role);
ps.executeUpdate();
ps.close();
}
}catch(Exception e){
System.err.println(e.getMessage());
e.printStackTrace();
}
DB_close();
//if(userId!=-1)
// return userId;
return -1;
}
public static boolean enterUsername(int userId, String firstname, String lastname){
try{
Class.forName("com.mysql.jdbc.Driver");
cn = DriverManager.getConnection("jdbc:mysql://localhost/log", "root", "root");
//String q1="INSERT INTO user_profile values(?,?,?)";
String q1 = "INSERT into user_profile (userId, firstname, lastname) VALUES (?,?,?)";
PreparedStatement ps = cn.prepareStatement(q1);
ps.setInt(1, userId);
ps.setString (1, firstname);
ps.setString (2, lastname);
ps.executeUpdate();
ps.close();
return true;
}catch(Exception e){
System.err.println(e.getMessage());
e.printStackTrace();
}
DB_close();
return false;
}
Here is my database structure.
Edit: found the issue, database was not structured properly.
CREATE TABLE user ( userId int(3) NOT NULL AUTO_INCREMENT,
username varchar(20) DEFAULT NULL, password varchar(20) DEFAULT
NULL, role varchar(20) DEFAULT NULL, PRIMARY KEY (userId),
UNIQUE KEY username (username) );
CREATE TABLE user_profile ( userId int(3) NOT NULL DEFAULT '0',
firstName varchar(20) DEFAULT NULL, lastName varchar(20) DEFAULT
NULL, PRIMARY KEY (userId), CONSTRAINT FK FOREIGN KEY
(userId) REFERENCES user (userId) );
Shouldn't following section in method enterUsername
ps.setInt(1, userId);
ps.setString (1, firstname);
ps.setString (2, lastname);
be like this
ps.setInt(1, userId);
ps.setString (2, firstname);
ps.setString (3, lastname);
I don't see the reason for the error message that you posted.
But I see some other things that look like a problem:
ps.setInt(1, userId);
ps.setString (1, firstname);
ps.setString (2, lastname);
The indexes are wrong: instead of 1, 1, 2, it should be 1, 2, 3.
(Frankly, I don't see how the code could possibly work as posted.)
Btw, this also looks wrong in the other method:
insert into user values(?,?,?)
As the table has more than 3 columns, you need to specify their names,
like you did in enterUsername.
Use
String q1 = "INSERT into user_profile (firstname, lastname) VALUES (?,?)";
because your first field is auto increment..So it automatically increment values while inserting values.
I recommended this way,
Delete your current table and create a new one like this
id-->int(30) (AUTO INCREMENT) NOTNULL //Dont need to take care of this field
USER_ID-->int(30) NOT NULL //you should create your own ID and increment it before adding a new person
username-->varchar(100)
password-->varchar(100)
role-->varchar(100)
and usually, call userId exactly same like your code,
String q0 = "Select userId from user ORDER BY USER_ID DESC LIMIT 1"; //get ID of last
Statement st = cn.createStatement();
ResultSet rs = st.executeQuery(q0);
if(rs.next()){
ID = rs.getInt("USER_ID ");
ID++;
}

Categories

Resources