I'm trying to insert 30 rows into the database, the ID generation strategy is IDENTITY
and my database (Exasol) supports it. Before each insert, Hibernate selects identity value from the database, like this (from Hibernate logs):
Hibernate:
SELECT
COLUMN_IDENTITY
FROM
EXA_ALL_COLUMNS
WHERE
COLUMN_NAME='ENTRY_ID'
AND COLUMN_SCHEMA='TEST'
AND COLUMN_TABLE='CAMPAIGN'
Hibernate:
insert
into
ecombi_mdm_test.CSV_ADCAMPAIGN
(bla1, bla2, bla3, bla4, bla5, bla6, bla7, bla8, bla9, bla10, bla11, bla12, bla13, bla14, bla15, bla16, bla17, bla18, bla19, bla20, bla21, bla22, bla23, bla24, bla25, bla26, bla27, bla28, bla29, bla30)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate:
SELECT
COLUMN_IDENTITY
FROM
EXA_ALL_COLUMNS
WHERE
COLUMN_NAME='ENTRY_ID'
AND COLUMN_SCHEMA='TEST'
AND COLUMN_TABLE='CAMPAIGN'
Hibernate:
insert
into
ecombi_mdm_test.CSV_ADCAMPAIGN
(bla1, bla2, bla3, bla4, bla5, bla6, bla7, bla8, bla9, bla10, bla11, bla12, bla13, bla14, bla15, bla16, bla17, bla18, bla19, bla20, bla21, bla22, bla23, bla24, bla25, bla26, bla27, bla28, bla29, bla30)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
... and 28 more. In the end, it takes me 9 seconds to insert 30 rows.
This is how I configure my data source:
configuration = new Configuration();
configuration.setProperty("hibernate.connection.driver_class", properties.getProperty(...);
configuration.setProperty("hibernate.connection.url", properties.getProperty(...);
configuration.setProperty("hibernate.connection.username", properties.getProperty(...);
configuration.setProperty("hibernate.connection.password", properties.getProperty(...);
configuration.setProperty("hibernate.dialect", properties.getProperty(com.bla.exasol.ExasolDialect);
configuration.setProperty("hibernate.show_sql", "true");
configuration.setProperty("hibernate.format_sql", "true");
configuration.setProperty("hibernate.default_schema", properties.getProperty(...);
configuration.addAnnotatedClass(Some.class);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
This is from my DAO class:
Session session = MultiTenantDBAccess.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
for (T o : oList) {
session.persist(o);
}
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
And this is my DB's custom identity support class:
public class ExasolIdentityColumnSupport extends IdentityColumnSupportImpl {
@Override
public String appendIdentitySelectToInsert(String arg0) {
return arg0;
}
@Override
public String getIdentityColumnString(int type) throws MappingException {
return type==Types.BIGINT ?
"decimal(36, 0) identity not null" :
"decimal(19, 0) identity not null";
}
@Override
public String getIdentitySelectString(String table, String column, int type) throws MappingException {
return "SELECT COLUMN_IDENTITY FROM EXA_ALL_COLUMNS WHERE COLUMN_NAME='"+column.toUpperCase()+"' AND COLUMN_SCHEMA='"+table.substring(0, table.indexOf(".")).toUpperCase()+"' AND COLUMN_TABLE='"+(table.substring(table.indexOf(".")+1)).toUpperCase()+"'";
}
@Override
public boolean hasDataTypeInIdentityColumn() {
return false;
}
@Override
public boolean supportsIdentityColumns() {
return true;
}
public boolean supportsInsertSelectIdentity() {
return false;
}
}
Is the problem in the fact that the DB I use doesn't support InsertSelectIdentity
? Can't just Hibernate send 30 queries to DB without checking the id value before every insert? Can't I achieve in this case a better performance with Hibernate than 30 rows per 9 seconds?