Hibernate выбирает значения столбца идентичности перед каждой вставкой - PullRequest
0 голосов
/ 21 января 2019

Я пытаюсь вставить 30 строк в базу данных, стратегия генерации идентификатора - IDENTITY, и моя база данных (Exasol) поддерживает ее. Перед каждой вставкой Hibernate выбирает значение идентификатора из базы данных, например так (из журналов Hibernate):

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
        (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

... и еще 28. В конце у меня уходит 9 секунд, чтобы вставить 30 строк.

Вот как я настраиваю свой источник данных:

        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);

Это из моего класса DAO:

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();
}

А это класс поддержки пользовательских идентификаторов моей БД:

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;
    }

}

Проблема в том, что используемая БД не поддерживает InsertSelectIdentity? Разве Hibernate не может отправлять 30 запросов в БД без проверки значения идентификатора перед каждой вставкой? Разве я не могу добиться в этом случае лучшей производительности с Hibernate, чем 30 строк в 9 секунд?

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Не рекомендуется использовать колоночную аналитическую DMBS для рабочей нагрузки OLTP: выбирать, вставлять или обновлять отдельные строки.

Вы можете использовать MySQL / PostgreSQL / и т. Д. Для хранения статусов заданий и общей грусти ORM. И используйте Exasol только для больших объемов данных и большого импорта.

0 голосов
/ 21 января 2019

Идентификатор необходим, поскольку сущность сохраняется в сеансе с использованием идентификатора в качестве ключа.

Единственный способ обойти это - использовать последовательность базы данных, если БД поддерживает использование последовательностей.

...