[JIRA] (HHH-16517) H6: Problems with flush when batch is ON (without @DynamicUpdate)
by Nemanja Jovanovic (JIRA)
Nemanja Jovanovic ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... ) *updated* an issue
Hibernate ORM ( https://hibernate.atlassian.net/browse/HHH?atlOrigin=eyJpIjoiNmM5OTU0Nzc2... ) / Bug ( https://hibernate.atlassian.net/browse/HHH-16517?atlOrigin=eyJpIjoiNmM5OT... ) HHH-16517 ( https://hibernate.atlassian.net/browse/HHH-16517?atlOrigin=eyJpIjoiNmM5OT... ) H6: Problems with flush when batch is ON (without @DynamicUpdate) ( https://hibernate.atlassian.net/browse/HHH-16517?atlOrigin=eyJpIjoiNmM5OT... )
Change By: Nemanja Jovanovic ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%... )
Update statement does not get generated when flushing in case we have batching on for following example:
{noformat}@Entity
@Inheritance(strategy = InheritanceType.JOINED)
class BaseEntity implements Serializable {
private static final long serialVersionUID = -5412503864464287451L;
@Id long id;
@Column(name = "VAL") int val;
}
@Entity
@PrimaryKeyJoinColumn(name = "ID")
class FooEntity extends BaseEntity {
private static final long serialVersionUID = 6681665021507587925L;
@Column(name = "NAME") String name;
FooEntity() {}
FooEntity(long id) {
this.id = id;
}
}
@Entity
class SingleTableEntity implements Serializable {
private static final long serialVersionUID = -5412503864464287451L;
@Id long id;
@Column(name = "NAME") String name;
SingleTableEntity() {}
SingleTableEntity(long id) {
this.id = id;
}
}
public class FlushTest {
@Test
public void test() {
Transaction txn = null;
try (final Session session = newSessionFactory().openSession()) {
txn = session.beginTransaction();
final FooEntity foo = new FooEntity(1L);
session.persist(foo);
session.flush();
session.clear();
FooEntity fetched = session.get(FooEntity.class, 1L);
fetched.name = "string";
session.flush();
session.clear();
fetched = session.get(FooEntity.class, 1L);
fetched.name = "string2";
// This flush does not generate update, and it should
session.flush();
session.clear();
fetched = session.get(FooEntity.class, 1L);
assertEquals("string2", fetched.name);
txn.rollback();
}
}
@Test
public void testSingleTable() {
Transaction txn = null;
try (final Session session = newSessionFactory().openSession()) {
txn = session.beginTransaction();
final SingleTableEntity foo = new SingleTableEntity(1L);
session.persist(foo);
session.flush();
session.clear();
SingleTableEntity fetched = session.get(SingleTableEntity.class, 1L);
fetched.name = "string";
session.flush();
session.clear();
fetched = session.get(SingleTableEntity.class, 1L);
fetched.name = "string2";
session.flush();
session.clear();
fetched = session.get(SingleTableEntity.class, 1L);
assertEquals("string2", fetched.name);
txn.rollback();
}
}
protected SessionFactory newSessionFactory() {
final Properties properties = new Properties();
properties.put("hibernate.hbm2ddl.auto", "create");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
properties.put("hibernate.connection.driver_class", "org.hsqldb.jdbc.JDBCDriver");
properties.put("hibernate.connection.url", "jdbc:hsqldb:mem:test");
properties.put("hibernate.connection.username", "sa");
properties.put("hibernate.connection.password", "");
// putting batch_size to 1 solves the problem
properties.put("hibernate.jdbc.batch_size", "2");
return new Configuration().addProperties(properties)
.addAnnotatedClass(BaseEntity.class)
.addAnnotatedClass(FooEntity.class)
.addAnnotatedClass(SingleTableEntity.class)
.buildSessionFactory(new StandardServiceRegistryBuilder().applySettings(properties).build());
}
}
{noformat}
After some debugging found quick workaround and potentially source of the problem, removing
{noformat} if (currentBatch.getKey().equals(key)) {
return currentBatch;
}{noformat}
from org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.getBatch solves the problem. It seems that state of {{currentBatch}} is left from previous statement execution but with all preparestatements cleared. And since {{BatchKey}} is the same as previous update , empty batch , ( without prepared statements , ) is being reused and no update statement is being generated/executed.
This issue seems to be related to [https://hibernate.atlassian.net/browse/HHH-16367|https://hibernate.atlass... that one is I think wrongfully closed as duplicate. Test case eclipse project with pom attached to issue.
( https://hibernate.atlassian.net/browse/HHH-16517#add-comment?atlOrigin=ey... ) Add Comment ( https://hibernate.atlassian.net/browse/HHH-16517#add-comment?atlOrigin=ey... )
Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.... ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailN... ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100223- sha1:cdc0af3 )