我现在使用JPA几年了。
在旧项目中,“请求”实体的ID如下所示:
R0000001
R0000002
我将oracle序列转换为表生成器:
@Id
@Column(name = "requestid", columnDefinition = "varchar(10)")
@TableGenerator(pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_NUMBER",
pkColumnValue = "REQUEST_ID", name = "REQUEST_ID", table = "APPSEQUENCES",
allocationSize = 5)
@GeneratedValue(strategy = GenerationType.TABLE, generator = "REQUEST_ID")
private String requestId;
@PrePersist
public void prependIdWithR() {
if (null == this.requestId) {
LOG.error("Could not prepend RequestId which is null!");
return;
}
if (requestId.charAt(0) != "R") {
final int parsedRequestId = Integer.parseInt(requestId);
final String formattedId = String.format("A%07d", parsedRequestId);
LOG.debug("RequestId changed: [{}] => [{}].",
requestId,
formattedId);
this.requestId = formattedId;
return;
}
}
这很好用。
现在,我想要一个RequestId对象而不是一个普通字符串,它在整个代码中使用。
如果我只是向我的ID添加@Converter
并将类型更改为RequestId,则会发生以下情况:
<RequestId, String>
失败,因为生成了java.lang.Long
JPA抛出的实际例外:
javax.persistence.PersistenceException: An exception occurred while calling convertToEntityAttribute on converter class my.self.RequestIdConverter with value 26
at org.eclipse.persistence.mappings.converters.ConverterClass.convertDataValueToObjectValue(ConverterClass.java:126) ~[na:na]
Caused by: java.lang.ClassCastException: java.lang.Long incompatible with java.lang.String
at my.self.RequestIdConverter.convertToEntityAttribute(RequestIdConverter.java:1) ~[classes/:version-SNAPSHOT]
at org.eclipse.persistence.mappings.converters.ConverterClass.convertDataValueToObjectValue(ConverterClass.java:124) ~[na:na]
这意味着:我需要在@Convert
之前调用@PrePersist,或者从表生成器(不是Long)返回一个字符串。
这种情况甚至可能吗?我想我需要使用String。
@PrePersist
之前调用转换器。转换器为<RequestId, String>
,因为现有的表ID列为varchar(10)
。String getValue()
方法。我可以用<RequestId, Object>
来实现转换器,然后查看对象是Long还是String。这可能吗?我不喜欢有任何对象转换器的想法。我怀疑它是否有效,因为它意味着转换为RequestId。