Task
类有一个TaskPayload
的实例作为成员对象。
@Data
@Builder
public class Task {
private int id;
private TaskPayload payload;
// skipping other members
}
@Data
@Builder
public class TaskPayload {
private PayloadType payloadType;
private PayloadEncoding payloadEncoding;
private String data;
}
我正在尝试将
Task
元素插入表 task_queue
并返回插入的元素。
<select id="save" parameterType="com.prod.transponder.entity.Task" resultMap="taskResultMap">
INSERT INTO task_queue(
payload_type,
payload_encoding,
payload_text
)
VALUES
(
#{payload.payloadType},
#{payload.payloadEncoding},
#{payload.data}
)
RETURNING *
</select>
<resultMap id="taskPayloadMap" type="com.prod.transponder.model.TaskPayload">
<result column="payload_encoding" property="payloadEncoding" />
<result column="payload_type" property="payloadType"/>
<result column="payload_text" property="data"/>
</resultMap>
<resultMap id="taskResultMap" type="com.prod.transponder.entity.Task">
<id column="id" property="id"/>
<association property="payload" resultMap="taskPayloadMap"/>
</resultMap>
但是当我测试这个时,我收到以下错误;
Caused by: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'id' from result set. Cause: java.lang.IllegalArgumentException: No enum constant com.prod.transponder.constants.PayloadType.2
2 是插入元素自动生成的 ID。
错误本身并不足以直观地解决这个问题。实际的问题在于Lombok的注释。 Mybatis 使用
Reflection
为字段设置值。它需要一个无参构造函数(或根本不需要构造函数)来映射成员对象的值。因此,在 @NoArgsConstructor
之上添加 TaskPayload
注释应该可以解决问题。但由于 @Builder
需要一个包含所有成员的构造函数,因此还必须添加 @AllArgsConstructor
。因此像这样修改 TaskPayload
将解决问题;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TaskPayload {
private PayloadType payloadType;
private PayloadEncoding payloadEncoding;
private String data;
}
此外,这里不需要定义
resultMap
。将 Task
设置为 resultType
应该也可以。