如何自定义 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
一些属性。
我想将 属性 作为 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
一些属性。