Why does the flash() consider intermediate instructions after persist()? I'm talking about case case 2, where a separate update request was made for setName.
// 1
#Transactional
public void persist1(){
Post post = new Post();
post.setName("name1");
entityManager.persist(post);
}
// 2
#Transactional
public void persist2(){
Post post = new Post();
entityManager.persist(post);
post.setName("name2");
}
// 1
Hibernate: insert into post (name, id) values (?, ?)
// 2
Hibernate: insert into post (name, id) values (?, ?)
Hibernate: update post set name=? where id=?
Related
I have 200K rows to be inserted in one single database table. I tried to use jdbcTemplate.batchUpdate in spring in order to do insertion 10,000 per batch. However, this process consumes too much time (7 mins for 200K rows). So on database side, I check the number of rows inserted by select count(*) from table_X. I found the number of rows increased slightly instead of 10K expected. Can anyone explain what's reason or is it something which should be configurated on Database side ?
PS: I am using sybase ....
There are lot of approaches available on the web.
Performance directly depends on the
Code you have written
JDBC driver you are using
database server and number of connection you are using
table indexes leads to slowness for insertion
Without looking at your code anyone can guess, but no one can find the exact solution.
Approach 1
//insert batch example
public void insertBatch(final List<Customer> customers){
String sql = "INSERT INTO CUSTOMER " +
"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {
#Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
Customer customer = customers.get(i);
ps.setLong(1, customer.getCustId());
ps.setString(2, customer.getName());
ps.setInt(3, customer.getAge() );
}
#Override
public int getBatchSize() {
return customers.size();
}
});
}
reference
https://www.mkyong.com/spring/spring-jdbctemplate-batchupdate-example/
http://docs.spring.io/spring-framework/docs/3.0.0.M4/reference/html/ch12s04.html
Approach 2.1
//insert batch example
public void insertBatch(final List<Customer> customers){
String sql = "INSERT INTO CUSTOMER " +
"(CUST_ID, NAME, AGE) VALUES (?, ?, ?)";
List<Object[]> parameters = new ArrayList<Object[]>();
for (Customer cust : customers) {
parameters.add(new Object[] {cust.getCustId(),
cust.getName(), cust.getAge()}
);
}
getSimpleJdbcTemplate().batchUpdate(sql, parameters);
}
Alternatively, you can execute the SQL directly.
//insert batch example with SQL
public void insertBatchSQL(final String sql){
getJdbcTemplate().batchUpdate(new String[]{sql});
}
reference
https://www.mkyong.com/spring/spring-simplejdbctemplate-batchupdate-example/
Approach 2.2
public class JdbcActorDao implements ActorDao {
private SimpleJdbcTemplate simpleJdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
public int[] batchUpdate(final List<Actor> actors) {
SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch(actors.toArray());
int[] updateCounts = simpleJdbcTemplate.batchUpdate(
"update t_actor set first_name = :firstName, last_name = :lastName where id = :id",
batch);
return updateCounts;
}
// ... additional methods
}
Approach 2.3
public class JdbcActorDao implements ActorDao {
private SimpleJdbcTemplate simpleJdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
}
public int[] batchUpdate(final List<Actor> actors) {
List<Object[]> batch = new ArrayList<Object[]>();
for (Actor actor : actors) {
Object[] values = new Object[] {
actor.getFirstName(),
actor.getLastName(),
actor.getId()};
batch.add(values);
}
int[] updateCounts = simpleJdbcTemplate.batchUpdate(
"update t_actor set first_name = ?, last_name = ? where id = ?",
batch);
return updateCounts;
}
// ... additional methods
}
Approach 3 :JDBC
dbConnection.setAutoCommit(false);//commit trasaction manually
String insertTableSQL = "INSERT INTO DBUSER"
+ "(USER_ID, USERNAME, CREATED_BY, CREATED_DATE) VALUES"
+ "(?,?,?,?)";
PreparedStatement = dbConnection.prepareStatement(insertTableSQL);
preparedStatement.setInt(1, 101);
preparedStatement.setString(2, "mkyong101");
preparedStatement.setString(3, "system");
preparedStatement.setTimestamp(4, getCurrentTimeStamp());
preparedStatement.addBatch();
preparedStatement.setInt(1, 102);
preparedStatement.setString(2, "mkyong102");
preparedStatement.setString(3, "system");
preparedStatement.setTimestamp(4, getCurrentTimeStamp());
preparedStatement.addBatch();
preparedStatement.executeBatch();
dbConnection.commit();
reference
https://www.mkyong.com/jdbc/jdbc-preparedstatement-example-batch-update/
/*Happy Coding*/
Try setting below for connection string - useServerPrepStmts=false&rewriteBatchedStatements=true. Have not tried but its from my bookmarks. You can search on these lines..
Connection c = DriverManager.getConnection("jdbc:<db>://host:<port>/db?useServerPrepStmts=false&rewriteBatchedStatements=true", "username", "password");
For us moving the code to a wrapper class and annotating the batch insert method with #Transactional did solve the problem.
I want to select data from Workflow table using order by.How to do so?
public Workflow getDocById(String id) {
Query queryWfManager = sessionfactory.getCurrentSession().createQuery("from Workflow where id =:id");
queryWfManager.setParameter("id", id);
Workflow wfManagerList = (Workflow) queryWfManager.list();
Query queryWfDetails = sessionfactory.getCurrentSession().createQuery("from WorkflowDetails where workflowCode =:workflowCode order by wfBlockId order by stepSeq");
queryWfDetails.setParameter("workflowCode", wfManagerList.getWorkflowCode());
List<WorkflowDetails> queryWfDetailList = queryWfDetails.list();
wfManagerList.setSteps(queryWfDetailList);
return wfManagerList;
}
Which One is correct Writing oreder by order by wfBlockId , stepSeq OR order by wfBlockId order by stepSeq?
public Workflow getDocById(String id) {
Query queryWfManager = sessionfactory.getCurrentSession().createQuery("from Workflow where id =:id");
queryWfManager.setParameter("id", id);
Workflow wfManagerList = (Workflow) queryWfManager.list();
Query queryWfDetails = sessionfactory.getCurrentSession().createQuery("from WorkflowDetails where workflowCode =:workflowCode order by wfBlockId , stepSeq");
queryWfDetails.setParameter("workflowCode", wfManagerList.getWorkflowCode());
List<WorkflowDetails> queryWfDetailList = queryWfDetails.list();
wfManagerList.setSteps(queryWfDetailList);
return wfManagerList;
}
Query queryWfDetails = sessionfactory.getCurrentSession()
.createQuery("FROM WorkflowDetails where workflowCode =:workflowCode ORDER BY wfBlockId , stepSeq");
The above query is correct.
I am using Spring 3.1.2,am using PreparedStatementSetter for Select, update and insert, but how can I use for Delete query?
jdbcTemplate.update() can be used for delete's
e.g.
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.update("delete from my_table where value=? ", new PreparedStatementSetter() {
public void setValues(PreparedStatement ps) throws SQLException {
ps.setLong(1, 2L);//or setString or whatever
}
});
you can also execute a delete without the PreparedStatementSetter as shown here: http://www.java2s.com/Code/Java/Spring/UseJdbcTemplateToExecuteDeleteStatementWithParameter.htm
You can use PreparedStatement for deletion like this
String sql = "DELETE FROM MY_TABLE WHERE ID = ?";
PreparedStatement ps = yourDBConnection.prepareStatement(sql);
ps.setInt(1, 1001);
// execute delete SQL stetement
ps.executeUpdate();
Newbie programmer here. Upon doing mvn tomcat:run I get the following error:
SEVERE: Servlet.service() for servlet appServlet threw exception
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 'values (?, ?)' at line 1
The code in question is as follows:
public void create(User user) {
this.jdbcTemplate.update("INSERT INTO xyz.user(user_name, user_password values (?, ?)");
user.getUserName(); user.getId();
}
public void delete(User user) {
this.jdbcTemplate.update("DELETE FROM xyz.user WHERE id = ?");
}
public void update(User user) {
this.jdbcTemplate.update(
"UPDATE xyz.user SET UserName = ? password = ? WHERE id = ?");
Googled - couldn't find a solution for (?, ?) scenarios. Pls. help - Thx in advance :)
Here's the complete code (almost) - I am doing something wrong but can't figure out what.
public User find(String login) {
System.out.println("Trying to find the user...." + login);
User user = this.jdbcTemplate.queryForObject(
"select * from xyz where user_name = ?",
new Object[]{login},
new RowMapper<User>() {
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setId(Long.valueOf(rs.getInt(1)));
user.setUserName(rs.getString(2));
user.setPassword(rs.getString(3));
return user;
}
});
System.out.println("Found user..." + user);
return user;
}
public void create(User user) {
this.jdbcTemplate.update("INSERT INTO ibstechc_dev.user(user_name, user_password) VALUES (?,?)");
user.getUserName(); user.getId() ;
}
public void delete(User user) {
this.jdbcTemplate.update("DELETE FROM xyz WHERE id = ?");
// TODO Auto-generated method stub
}
public void update(User user) {
this.jdbcTemplate.update(
"UPDATE xyz SET user_name = ?, user_password = ? WHERE id = ?");
// TODO Auto-generated method stub
}
}
I am stuck with the same error - tomcat:run throws the following -
SEVERE: Servlet.service() for servlet appServlet threw exception
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 '?,?)' at line 1
Use this code:
this.jdbcTemplate.update("INSERT INTO xyz.user(user_name, user_password) values (?, ?)");
There was an issue with your SQL statement. To give you perspective you were trying to do:
INSERT INTO xyz.user(user_name, user_password values ('testuser','testpass'))
instead of
INSERT INTO xyz.user(user_name, user_password) values ('testuser','testpass'))
Hope this makes sense?
I think here is the sql syntax problem:
INSERT INTO xyz.user(user_name, user_password values (?, ?)
replace this by
INSERT INTO xyz.user(user_name, user_password) values (?, ?);
There is a sql syntax error in update
public void update(User user) {
this.jdbcTemplate.update(
"UPDATE xyz.user SET UserName = ? password = ? WHERE id = ?");
this is not the way to update,give a comma(,) like this
public void update(User user) {
this.jdbcTemplate.update(
"UPDATE xyz.user SET UserName = ? ,password = ? WHERE id = ?");
your error is this statement
this.jdbcTemplate.update("INSERT INTO xyz.user(user_name, user_password values (?, ?)");
It should be
this.jdbcTemplate.update("INSERT INTO xyz.user(user_name, user_password) values (?, ?)");
Hope it helps
Cheers
Try this:-
this.jdbcTemplate.update("INSERT INTO xyz.user(user_name, user_password) values (?, ?)");
instead of
this.jdbcTemplate.update("INSERT INTO xyz.user(user_name, user_password values (?, ?)");
I want to insert data into a table using the following code
public User registerUser(String usr, String pwd) {
u=em.find(User.class,usr);
if(u!=null)
{
return null;
}
String query1 = "insert into users values('" + usr + "','" + pwd +"')";
Query q = em.createQuery(query1);
u=em.find(User.class,usr);
return u;
}
here 'u' is the object of User class and em is EntityManager.
I get this following exception:
Servlet.service() for servlet action threw exception
org.hibernate.hql.ast.QuerySyntaxException: expecting OPEN, found 'values' near line 1, column 19 [insert into users values('pawan','am')]
Try
public User registerUser(String usr, String pwd) {
u=em.find(User.class,usr);
if(u!=null)
{
return null;
}
//Now saving...
em.getTransaction().begin();
em.persist(u); //em.merge(u); for updates
em.getTransaction().commit();
em.close();
return u;
}
If the PK is Identity, it will be set automatically in your persisted class, if you are using auto generation strategy (thanks to David Victor).
Edit to #aman_novice comment:
set it in your class
//Do this BEFORE getTransaction/persist/commit
//Set names are just a example, change it to your class setters
u.setUsr(usr);
u.setPwd(pwd);
//Now you can persist or merge it, as i said in the first example
em.getTransaction().begin();
(...)
About #David Victor, sorry I forgot about that.
You're not using SQL but JPAQL, there is no field-based insert. You persist object rather than inserting rows.
You should do something like this:
public User registerUser(String usr, String pwd) {
u=em.find(User.class,usr);
if(u!=null)
{
return u;
}
u = new User(usr, pwd);
em.persist(u);
return u;
}
This isn't really the way to go. You are trying to insert a row in a table but have no associated attached entity. If you're using the JPA entity manager - then create a new instance - set the properties & persist the entity.
E.g.
User u = new User();
u.setXXX(xx);
em.persist(u);
// em.flush() <<-- Not required, useful for seeing what is happening
// etc..
If you enable SQL loggging in Hibernate & flush the entity then you'll see what is sent to the database.
E.g. in persistence.xml:
<property name="hibernate.format_sql" value="true" />