JPA/Hibernate:在不存在的序列/关系上选择 currval

mat*_*jes 5 hibernate jpa spring-data-jpa

我对 JPA/Hibernate 有一个令人困惑的问题:select currval()将值插入表后,对不存在的关系/序列执行 a 。我有两个类似的案例,一个有效,另一个无效。

\n\n

这是第一个非工作版本。

\n\n

实体:

\n\n
@Entity\n@Table(name = "meter")\n@Data\n@EqualsAndHashCode(callSuper = true)\npublic class Meter extends AbstractTimestampEntity {\n\n    @Id\n    @GeneratedValue(strategy = GenerationType.IDENTITY)\n    private Long id;\n\n    @Column(name = "meter_id")\n    private Long meterId;\n\n    @Column(name = "meter_id_str")\n    private String meterIdStr;\n\n    @Column(name = "contract_id")\n    private Long contractId;\n\n    @Column(name = "user_id")\n    private Long userId;\n\n    @Column(name = "com_id")\n    private String comId;\n\n    @Column(name = "is_active")\n    private Boolean isActive;   \n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

飞行路线脚本:

\n\n
CREATE SEQUENCE meter_seq;\nCREATE TABLE IF NOT EXISTS meter (\n  id           BIGINT NOT NULL DEFAULT nextval(\'meter_seq\'),\n  meter_id     BIGINT,\n  meter_id_str VARCHAR(20),\n  contract_id  BIGINT,\n  user_id      BIGINT,\n  com_id       VARCHAR(50),\n  is_active    BOOLEAN,\n  created_at   BIGINT,\n  modified_at  BIGINT,\n  CONSTRAINT pk_meter PRIMARY KEY (id)\n);\nALTER SEQUENCE meter_seq OWNED BY meter.id;\n
Run Code Online (Sandbox Code Playgroud)\n\n

服务:

\n\n
@Override\n@Transactional\npublic void updateUser(UserDTO userDTO, ContractDTO contractDTO, MeterDTO meterDTO) {\n    String meterIdStr = meterDTO.getMeterId();\n    long uid = userDTO.getId();\n    long cid = contractDTO.getId();\n    long mid = meterDTO.getId();\n    boolean isActive = meterDTO.isActive();\n\n    log.debug("Updating meter state: {}, isActive: {}, contractId: {}, userId: {}", mid, isActive, cid, uid);\n\n    Meter meter = this.meterRepository.find(uid, cid, meterIdStr);\n    if (meter == null) {\n        log.debug("No meter found, creating new meter.");\n        meter = new Meter();\n        meter.setMeterId(mid);\n        meter.setMeterIdStr(meterIdStr);\n        meter.setContractId(cid);\n        meter.setUserId(uid);\n        meter.setIsActive(true);\n        this.meterRepository.save(meter);\n    } else {\n        if (isActive != meter.getIsActive()) {\n            meter.setIsActive(isActive);\n            this.meterRepository.save(meter);\n            this.cacheService.evict(CacheNames.METER,\n                    new SimpleKey(meter.getMeterIdStr(), meter.getComId()).toString());\n\n            // remove meter from monitoring if it is not active any longer\n            if (!isActive) {\n                String key = String.format("%d-%d-%d", uid, cid, mid);\n                this.boundHashOperations.delete(key);\n            }\n        }\n    }\n\n    log.debug("Done");\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

Meter插入新的(在行中)时我总是收到错误this.meterRepository.save()服务类中)

\n\n
2018-05-23 06:42:21.303 TRACE - [-enerContainer-4]            o.h.e.j.i.JdbcCoordinatorImpl : Starting after statement execution processing [ON_CLOSE]\n2018-05-23 06:42:21.303 DEBUG - [-enerContainer-4]                          o.hibernate.SQL : select currval(\'meter_data_receiver.meter_id_seq\')\n2018-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\')]\n2018-05-23 06:42:21.304 ERROR - [-enerContainer-4]             o.h.e.j.s.SqlExceptionHelper : FEHLER: Relation \xe2\x80\x9emeter_data_receiver.meter_id_seq\xe2\x80\x9c existiert nicht\n
Run Code Online (Sandbox Code Playgroud)\n\n

位置:16

\n\n

没有序列/关系“meter_data_receiver.meter_id_seq”。

\n\n

另一种情况类似,但在这里我可以在日志中看到以下消息:

\n\n
2018-05-23 06:42:21.345 DEBUG - [RedisMessageLis]          o.h.i.IdentifierGeneratorHelper : Natively generated identity: 2\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,在这种情况下,ID 似乎是在插入操作后从数据库中获取的,而在第一种情况下,需要额外的 IDselect对不存在的序列/关系执行了额外操作。

\n\n

我不知道为什么 Hibernate 认为它可以通过查询序列来获取第一个案例的 ID...

\n

mat*_*jes 5

properties.hibernate.temp.use_jdbc_metadata_defaults: false好的,我已从配置中删除了该选项,现在它似乎可以工作。

我不确定为什么我首先添加这个选项,我认为有一个警告建议我应该添加它......

  • 我面临着与你完全相同的问题(非常随机)。但我没有使用这个选项。您后来有没有意识到问题有所不同? (2认同)