Массовая / пакетная генерация с помощью Spring JPA Hibernate - PullRequest
0 голосов
/ 05 июня 2019

У меня есть класс сущности UserContent

@Entity
@SequenceGenerator(allocationSize = 1, name = "USER_CONTENT_ID_GENERATOR", sequenceName = "USER_CONTENT_ID_SEQ")
public class UserContent {

    @Id
    @Column(name = "USER_CONTENT_ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_CONTENT_ID_GENERATOR")
    private Long id;

...more fields
}

За один раз мне нужно сохранить максимум от 7k до 9k UserContents

@Repository
public interface UserContentRepositoryV2 extends CrudRepository<UserContent, Long> {
}

Вот как я сохраняю содержимое пользователя

//assume it has 8K records
List<UserContent> userContents
userContentRepository.save(userContents);

Вот мое приложение YAML

spring:
  profiles: default
  application:
     name: content
  jpa:
    hibernate:
      jdbc:
        fetch_size: 200
        batch_size: 200
        batch_versioned_data: true
      order_inserts: true
      order_updates: true
      ddl-auto: validate
    show-sql: false
    properties:
      hibernate:
        dialect: "org.hibernate.dialect.Oracle12cDialect"
        jdbc:
          fetch_size: 200
          batch_size: 200
          batch_versioned_data: true
        order_inserts: true
        order_updates: true

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

select USER_CONTENT_ID_SEQ.nextval from dual

Сначала для 8k записей, 8K звонков делается для получения последовательности. Следовательно, весь процесс очень медленный. Как только секвенции есть, сохранения выполняются очень быстро, поскольку batch_size равен 200

.

Я не могу получить все последовательности быстрее, я пытался использовать новую стратегию последовательности согласно рекомендациям, пункт 20 и Блог Влада Михалчеа

@GenericGenerator(
            name = "USER_CONTENT_ID_GENERATOR",
            strategy = "enhanced-sequence",
            parameters = {
                    @org.hibernate.annotations.Parameter(
                            name = "optimizer",
                            value = "pooled-lo"
                    ),
                    @org.hibernate.annotations.Parameter(
                            name = "initial_value",
                            value = "1"
                    ),
                    @org.hibernate.annotations.Parameter(
                            name = "increment_size",
                            value = "1"
                    ),
                    @org.hibernate.annotations.Parameter(
                            name = "sequence_name",
                            value = "COMMS_USER_CONTENT_ID_SEQ"
                    )
            }
    )
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_CONTENT_ID_GENERATOR")
    private Long id;

Даже это не решило проблему.

Мы используем Oracle 12C, и hibernate версия 5.0.12

Будет ли это лучше обслуживаться с JDBC Batch вместо Hibernate?

Спасибо за любую помощь, Татх

...