如何使用 JPA 映射 Duration 类型

发布于 2024-09-02 00:04:09 字数 191 浏览 5 评论 0原文

我的类中有一个 javax.xml.datatype.Duration 类型的属性字段。它基本上代表一个时间跨度(例如4小时34分钟)。

JPA 告诉我这是一个无效类型,这并没有让我感到震惊。

这有什么好的解决办法吗?我可以实现我自己的 Duration 类,但我不知道如何让 JPA“接受”它作为数据类型。

I have a property field in a class that is of type javax.xml.datatype.Duration. It basically represents a time span (e.g. 4 hours and 34 minutes).

JPA is telling me it is an invalid type, which doesn't shock me.

Whats a good solution this? I could implement my own Duration class, but I don't know how to get JPA to "accept" it as a datatype.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

烟火散人牵绊 2024-09-09 00:04:09

这有什么好的解决方案吗?我可以实现自己的 Duration 类,但我不知道如何让 JPA“接受”它作为数据类型。

JPA 不支持自定义类型,因此如果您想采用这种方式,则必须使用提供商提供的 JPA 扩展。例如,Hibernate 允许定义 使用 声明的自定义值类型@类型。显然,这将损害提供商之间的可移植性,这可能是一个问题。如果没有,那么您就知道这是可行的。

对于标准 JPA,传统方法是添加另一个 getter/setter 对,以适应有问题的属性并在访问时执行转换。我会使用 Long 来存储持续时间:

public MyEntity implements Serializable {
    private Long id;
    private javax.xml.datatype.Duration duration;

    @Id
    @GeneratedValue
    public Long getId() {
        return this.id;
    }
    public void setId(Long id) {
        this.id = id;
    }

    @Transient
    public Duration getDuration() {
        return this.duration;
    }
    public void setDuration(Duration duration) {
        this.duration = duration;
    }

    public Long getDurationAsJpaCompatibleType() {
        return MyXmlUtil.convertDurationToLong(this.duration);
    }
    public void setDurationAsJpaCompatibleType(Long duration) {
        setDuration(MyXmlUtil.convertLongToDuration(duration));
    }
}

Whats a good solution this? I could implement my own Duration class, but I don't know how to get JPA to "accept" it as a datatype.

JPA does not support custom types so if you want to go this way you'll have to use a JPA extension from your provider. For example, Hibernate allows to define custom value types that you declare with @Type. Obviously, this will harm portability between providers which might be a concern. If not, then you know it is doable.

With standard JPA, the traditional approach would be to add another getter/setter pair which adapt the problematic property and perform conversion when accessed. I would use a Long to store a duration:

public MyEntity implements Serializable {
    private Long id;
    private javax.xml.datatype.Duration duration;

    @Id
    @GeneratedValue
    public Long getId() {
        return this.id;
    }
    public void setId(Long id) {
        this.id = id;
    }

    @Transient
    public Duration getDuration() {
        return this.duration;
    }
    public void setDuration(Duration duration) {
        this.duration = duration;
    }

    public Long getDurationAsJpaCompatibleType() {
        return MyXmlUtil.convertDurationToLong(this.duration);
    }
    public void setDurationAsJpaCompatibleType(Long duration) {
        setDuration(MyXmlUtil.convertLongToDuration(duration));
    }
}
兲鉂ぱ嘚淚 2024-09-09 00:04:09

您可以将 Duration 类中的确切字段镜像到您自己的自定义类中,但这可能有点矫枉过正...我假设您不需要这种持续时间灵活性/粒度。

因此,选择您想要的字段,将它们添加到您的类中,使用 @Embeddable 注释标记该类,然后将正确的 JPA 注释添加到字段中(我假设这将是简单的整数)。

在将存储持续时间的实体中,将 @Embedded 注释添加到字段或 getter(无论您通常使用哪个)。从这里您可以使用@AttributeOverride进一步调整列定义。

You can mirror the exact fields in the Duration class into your own custom class, but that might be overkill...I'm assuming you don't need that kind of duration flexibility/granularity.

So pick the fields you want, add them to your class, mark the class with the @Embeddable annotation, and add the proper JPA annotations to the fields (which I'm assuming will be simple ints).

In your entity that will store a duration, add the @Embedded annotation to the field or getter, whichever you typically use. From here you can further tweak the column definitions with @AttributeOverride.

小糖芽 2024-09-09 00:04:09

您可以尝试 joda-time 休眠。请参阅可以持久化的可用类型。然后,您可以在以下内容中使用 joda Duration方式:

@Type(type="org.joda.time.contrib.hibernate.PersistentDuration")
private Duration startDateTime;

You could try joda-time hibernate. Refer to the available types that can be persisted. You could then use the joda Duration in the following way:

@Type(type="org.joda.time.contrib.hibernate.PersistentDuration")
private Duration startDateTime;
草莓味的萝莉 2024-09-09 00:04:09

就我而言,我有一个 java.time.Duation 字段,该字段通过 javax.persistence.AttributeConverter 进行转换:

@Converter(autoApply = true)
public class DurationAttributeConverter implements AttributeConverter<Duration, Integer> {

  @Override
  public Integer convertToDatabaseColumn(Duration pX) {
    if (pX == null) {
      return null;
    } else {
      return (int) pX.toMinutes();
    }
  }

  @Override
  public Duration convertToEntityAttribute(Integer pY) {
    if (pY == null) {
      return null;
    } else {
      return Duration.ofMinutes(pY);
    }
  }
}

Duration 对象映射到数字列,该数字列存储以分钟为单位的持续时间。

In my case, I have a java.time.Duation field which is converted via a javax.persistence.AttributeConverter:

@Converter(autoApply = true)
public class DurationAttributeConverter implements AttributeConverter<Duration, Integer> {

  @Override
  public Integer convertToDatabaseColumn(Duration pX) {
    if (pX == null) {
      return null;
    } else {
      return (int) pX.toMinutes();
    }
  }

  @Override
  public Duration convertToEntityAttribute(Integer pY) {
    if (pY == null) {
      return null;
    } else {
      return Duration.ofMinutes(pY);
    }
  }
}

The Duration Object is mapped to a number column, which stores the duration in minutes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文