如何自定义 EJB/JPA 映射类型?

How to do a custom EJB/JPA mapping type?

我想将 属性 作为 Long 存储到数据库中,但在代码中使用带有辅助方法的对象。

但是对象类型是我拥有的自定义类型,它有一个我想存储到数据库的内部值(长整型)。

public final class MyBean extends Number implements Serializable, Comparable<MyBean>
{
    private long myValue;

    public MyBean(Long value) { this.myValue = value; }

    // Other helper methods and overrides

    public MyBean valueOf(Long data)
    {
        return new MyBean(data);
    }

    @Override
    public String toString()
    {
        return String.valueOf(myValue);
    }
}

我是这样使用它的:

@Entity
@Table(name = "mybeans")
public class MyBean implements Serializable
{
    private static final long serialVersionUID = 1L;

    MyBean myBean;

    @Id
    @Column(name = "mybean", nullable = false)
    public MyBean getMyBean() { return myBean; }
    public void setMyBean(MyBean value) { this.myBean = value; }
}

反序列化此对象调用 toString 并且工作正常 (jax-rs/jersey)。但是当我尝试使用我的 EJB 将它从数据库中拉出时,我得到的错误是:

The object [1,427,148,028,955], of class [class java.lang.Long], could not be converted to [class com.MyBean]

保存它产生了错误

Can't infer the SQL type to use for an instance of com.MyBean. Use setObject() with an explicit Types value to specify the type to use.

有道理。

但是我可以添加什么方法来让EJB获取long作为值并使用long来建立一个新的对象呢?

答案:

制作 class @Embeddable 并添加以下属性。

@Embedded
@AttributeOverrides({
    @AttributeOverride(name="value", column=@Column(name="mybean"))
})

(我没有添加 EmbeddedId,因为我添加了一个串行主键 ID,只是将其作为一列)

需要注意的是它不适用于动态编织。我必须添加

<property name="eclipselink.weaving" value="static"/>

我的 persistence.xml

您可以尝试将 MyBean 设为 Embeddable to use that as an EmbeddedId,如下所示:

@Embeddable
public final class MyBean extends Number implements Serializable, Comparable<MyBean> {

    private Long myValue;

    public MyBean(Long myValue) {
        this.myValue = myValue;
    }

    // Other helper methods and overrides

    public MyBean valueOf(Long data) {
        return new MyBean(data);
    }

    @Override
    public String toString() {
        return String.valueOf(myValue);
    }

}

在您的实体中,MyBean 将是一个 EmbeddedId,看起来像这样:

@Entity
@Table(name = "mybeans")
public class MyEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    private MyBean myBean;

    @EmbeddedId
    @AttributeOverride(name="myValue", @Column(name="mybean_id"))
    public MyBean getMyBean() {
        return myBean;
    }

    public void setMyBean(MyBean myBean) {
        this.myBean = myBean;
    }

}

根据需要调整MyBean,比如制作Transient一些属性。