JPA / Hibernate: выберите курс для несуществующей последовательности / отношения - PullRequest
0 голосов
/ 23 мая 2018

У меня несколько запутанная проблема с JPA / Hibernate: select currval() выполняется для несуществующего отношения / последовательности после того, как значение вставлено в таблицу.У меня есть два подобных случая, один работает, другой нет.

Вот первая, нерабочая версия.

Объект:

@Entity
@Table(name = "meter")
@Data
@EqualsAndHashCode(callSuper = true)
public class Meter extends AbstractTimestampEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "meter_id")
    private Long meterId;

    @Column(name = "meter_id_str")
    private String meterIdStr;

    @Column(name = "contract_id")
    private Long contractId;

    @Column(name = "user_id")
    private Long userId;

    @Column(name = "com_id")
    private String comId;

    @Column(name = "is_active")
    private Boolean isActive;   
}

Скрипт Flyway:

CREATE SEQUENCE meter_seq;
CREATE TABLE IF NOT EXISTS meter (
  id           BIGINT NOT NULL DEFAULT nextval('meter_seq'),
  meter_id     BIGINT,
  meter_id_str VARCHAR(20),
  contract_id  BIGINT,
  user_id      BIGINT,
  com_id       VARCHAR(50),
  is_active    BOOLEAN,
  created_at   BIGINT,
  modified_at  BIGINT,
  CONSTRAINT pk_meter PRIMARY KEY (id)
);
ALTER SEQUENCE meter_seq OWNED BY meter.id;

Сервис:

@Override
@Transactional
public void updateUser(UserDTO userDTO, ContractDTO contractDTO, MeterDTO meterDTO) {
    String meterIdStr = meterDTO.getMeterId();
    long uid = userDTO.getId();
    long cid = contractDTO.getId();
    long mid = meterDTO.getId();
    boolean isActive = meterDTO.isActive();

    log.debug("Updating meter state: {}, isActive: {}, contractId: {}, userId: {}", mid, isActive, cid, uid);

    Meter meter = this.meterRepository.find(uid, cid, meterIdStr);
    if (meter == null) {
        log.debug("No meter found, creating new meter.");
        meter = new Meter();
        meter.setMeterId(mid);
        meter.setMeterIdStr(meterIdStr);
        meter.setContractId(cid);
        meter.setUserId(uid);
        meter.setIsActive(true);
        this.meterRepository.save(meter);
    } else {
        if (isActive != meter.getIsActive()) {
            meter.setIsActive(isActive);
            this.meterRepository.save(meter);
            this.cacheService.evict(CacheNames.METER,
                    new SimpleKey(meter.getMeterIdStr(), meter.getComId()).toString());

            // remove meter from monitoring if it is not active any longer
            if (!isActive) {
                String key = String.format("%d-%d-%d", uid, cid, mid);
                this.boundHashOperations.delete(key);
            }
        }
    }

    log.debug("Done");
}

При вставке нового Meter (в строке this.meterRepository.save() в классе обслуживания) всегда появляется ошибка:

2018-05-23 06:42:21.303 TRACE - [-enerContainer-4]            o.h.e.j.i.JdbcCoordinatorImpl : Starting after statement execution processing [ON_CLOSE]
2018-05-23 06:42:21.303 DEBUG - [-enerContainer-4]                          o.hibernate.SQL : select currval('meter_data_receiver.meter_id_seq')
2018-05-23 06:42:21.303 TRACE - [-enerContainer-4]   o.h.r.j.i.ResourceRegistryStandardImpl : Registering statement [HikariProxyPreparedStatement@75642772 wrapping select currval('meter_data_receiver.meter_id_seq')]
2018-05-23 06:42:21.304 ERROR - [-enerContainer-4]             o.h.e.j.s.SqlExceptionHelper : FEHLER: Relation „meter_data_receiver.meter_id_seq“ existiert nicht

Позиция: 16

Нет последовательности / отношения `meter_data_receiver.meter_id_seq '.

Другой случай аналогичен, но здесь я вижу в журнале следующее сообщение:

2018-05-23 06:42:21.345 DEBUG - [RedisMessageLis]          o.h.i.IdentifierGeneratorHelper : Natively generated identity: 2

Таким образом, в этом случае кажется, что идентификатор извлекается из базы данных после операции вставки, тогда как в первом случае дополнительная select выполняется для несуществующей последовательности / отношения.

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

1 Ответ

0 голосов
/ 23 мая 2018

Хорошо, я удалил опцию properties.hibernate.temp.use_jdbc_metadata_defaults: false из моей конфигурации, и теперь она, кажется, работает.

Я не уверен, почему я добавил эту опцию в первую очередь, я думаю, что было предупреждение, которое предложило мне добавить ее ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...