我有一个spring启动2.6.7应用程序,使用Liquibase, Gradle和Spock。我有一个使用guid格式字符串作为ID的类:
@Entity
@Table(name = "devices")
public class Device {
@Id
@NotNull
@Pattern(regexp = "^[{]?[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}[}]?$",
message = "Invalid id received")
private String deviceId;
@NotNull
private DeviceType deviceType;
@JsonFormat(shape = Shape.STRING, pattern = "yyyy-MM-dd")
private LocalDate manufactureDate;
@JsonFormat(shape = Shape.STRING, pattern = "yyyy-MM-dd")
private LocalDate activationDate;
@JsonFormat(shape = Shape.STRING, pattern = "yyyy-MM-dd")
private LocalDate deactivationDate;
private Status deviceStatus;
我有几个端点接受这个实体并持久化/查找/更新它。当我查看数据库时,我看到列已正确填充。所以它看起来是有效的。
这是我的这个表的液体库:
- changeSet:
id: 7
preConditions:
- onFail: MARK_RAN
not:
tableExists:
tableName:
devices
changes:
- createTable:
tableName: devices
columns:
nullable: false
- column:
name: device_id
type: varchar(255)
constraints:
primaryKey: true
nullable: false
- column:
name: device_type
type: varchar(255)
constraints:
nullable: true
- column:
name: manufacture_date
type: date
constraints:
nullable: true
- column:
name: activation_date
type: date
constraints:
nullable: true
- column:
name: deactivation_date
type: date
constraints:
nullable: true
- column:
name: internal_id
type: varchar(255)
constraints:
nullable: true
- column:
name: device_status
type: varchar(255)
constraints:
nullable: true
然而,我现在试图在测试中包装我的代码,并且我不断遇到字符串不能转换为UUID的问题。下面是测试:
given:
def device = new Device(internalId: internalId, deviceId: deviceId,
deviceType: deviceType, deviceStatus: deviceStatus, role: role, activationDate: activationDate, deactivationDate: deactivationDate, manufactureDate: manufactureDate)
def result = deviceRepository.save(device)
when:
def isValid = deviceServices.validateDevice(result)
then:
isValid == testResult
where:
deviceId | deviceType | deviceStatus | manufactureDate | activationDate | deactivationDate | || testResult
UUID.randomUUID() | DeviceType.EQUIPMENT | Status.ACTIVATED | LocalDate.now() | LocalDate.now() | null || true
这里是测试开始时试图插入到H2时的错误。字段被声明为varchar,但由于某种原因,堆栈跟踪提到了NumberFormat和Long值。
SQL Error: 22018, SQLState: 22018
2022-05-12 06:24:34.083 ERROR 42198 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : Data conversion error converting "faf837fa-8584-4dff-a8d1-bd4d9a8af74c"; SQL statement:
select identity0_.device_id as scanned_1_6_, identity0_.internal_id as internal2_6_ from identities identity0_ where identity0_.device_id=? [22018-212]
…
Caused by: org.h2.message.DbException: Data conversion error converting "9bbb114a-bb99-443c-9106-dd28210c4e7b" [22018-212]
at org.h2.message.DbException.get(DbException.java:212)
at org.h2.value.ValueStringBase.getLong(ValueStringBase.java:142)
at org.h2.value.Value.convertToBigint(Value.java:1645)
at org.h2.value.Value.convertTo(Value.java:1137)
at org.h2.value.Value.convertForAssignTo(Value.java:1092)
at org.h2.table.Column.validateConvertUpdateSequence(Column.java:369)
... 53 more
Caused by: org.h2.jdbc.JdbcSQLDataException: Data conversion error converting "9bbb114a-bb99-443c-9106-dd28210c4e7b" [22018-212]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:506)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
... 59 more
Caused by: java.lang.NumberFormatException: For input string: "9bbb114a-bb99-443c-9106-dd28210c4e7b"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Long.parseLong(Long.java:692)
at java.base/java.lang.Long.parseLong(Long.java:817)
at org.h2.value.ValueStringBase.getLong(ValueStringBase.java:140)
... 57 more
我觉得我已经把自己编码到一个角落,没有使主键UUID,或者没有一个常规的ID,然后使用deviceId作为UUID。然而,这是生产代码,我犹豫是否通过Liquibase改变表结构。
是否有办法使Liquibase或Spock围绕这个问题工作?同样,它在生产中工作得很好,我只是不能对它进行集成测试(这可能是H2限制?)
:我有另一个具有相同行为的测试—无法在持久化时将UUID转换为类的字符串属性。如果我改变uuid。randomuuid ()"123";
因为我看到这只与我的测试和例外是SqlExceptionHelper我想知道测试H2只是不能处理生产Postgres的转换?我改变H2为HSQL,并得到相同类型的错误。
您的Spock规格中Device.deviceID
的类型是String
,但deviceId
的类型是UUID
。所以你要么用
def device = new Device(internalId: internalId, deviceId: deviceId.toString(), ...
或
where:
deviceId | ...
UUID.randomUUID().toString() | ...
真的是那么微不足道。