JPA ID属性和@PrePersist

时间:2017-09-11 10:06:24

标签: java jpa

我现在使用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,则会发生以下情况:

  • 从序列表中提取ID。
  • 调用转换器(在<RequestId, String>失败,因为生成了java.lang.Long
  • 然后会引用prepersist。

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。

到目前为止我发现了什么

  • 如果我使用了hibernate,那么由于自定义生成器类(可能是修改后的表生成器,返回一个字符串),这是可能的。
  • 普通JPA中没有这样的东西
  • @PrePersist之前调用转换器。转换器为<RequestId, String>,因为现有的表ID列为varchar(10)
  • RequestId是由immutables.github.io生成的普通pojo对象。它只有String getValue()方法。
  • 我无法将数据库列更改为其他类型。
  • 我无法从现有记录中删除前缀。
  • 我需要能够读取已经有“R”前缀的旧记录。

我可以用<RequestId, Object>来实现转换器,然后查看对象是Long还是String。这可能吗?我不喜欢有任何对象转换器的想法。我怀疑它是否有效,因为它意味着转换为RequestId。

0 个答案:

没有答案