是否可以通过扩展 POJO 来构建 JPA 实体?

2022-08-31 16:12:18

假设我有以下POJO:

public class MyThing {
 private int myNumber;
 private String myData;
//assume getter/setter methods
}

现在是否可以将此 POJO 扩展为 JPA 实体?

@Entity
@Table(name = "my_thing")
public class MyThingEntity extends MyThing implements Serializable {
 @Column(name = "my_number")
 //?????????
 @Column(name = "my_data")
 //????????
}

我想将 POJO 与 JPA 实体分开。POJO存在于不同的项目中,并且通常没有持久性层使用,我的项目希望将其持久化到数据库中,并且这样做不会产生从POJO映射到实体并返回的开销。

我知道JPA实体是POJO,但是为了使用它,我必须包含一个实现javax.persistence的库,而使用相同基对象的其他项目对持久性层没有用处。

这可能吗?这是个好主意吗?


答案 1

JPA 规范状态

实体可以扩展非实体类以及实体类,非实体类可以扩展实体类。

@javax.persistence.MappedSuperclass annotation 允许您定义这种映射

@MappedSuperclass
public class MyThing implements Serializable {
    private int myNumber;
    private String myData;

    // getter's and setter's
}

@Entity
@Table(name="MY_THING")
public class MyThingEntity extends MyThing {


}

如JPA规范所述

MappedSuperclass 批注指定一个类,该类的映射信息将应用于从该类继承的实体

使用 MappedSuperclass 批注指定的类可以采用与实体相同的方式进行映射,只是映射将仅应用于其子类,因为映射的超类本身不存在表。

如果需要覆盖 MyThing 定义的某些属性,请使用@AttributeOverride(当您想要覆盖单个属性时)或@AttributeOverrides(当您想要覆盖多个属性时)

@Entity
@Table(name="MY_THING")
@AttributeOverride(name="myData", column=@Column(name="MY_DATA"))
public class MyThingEntity extends MyThing {


}

@Entity
@Table(name="MY_OTHER_THING")
@AttributeOverrides({
    @AttributeOverride(name="myData1", column=@Column(name="MY_DATA_1")),
    @AttributeOverride(name="myData2", column=@Column(name="MY_DATA_2"))
})
public class MyOtherThingEntity extends MyThing {

}

如果不想更改基类,可以使用 xml 将其定义为@MappedSuperClass

请注意:默认情况下,持久性提供程序将在 META-INF 目录中查找名为 orm 的文件.xml

<?xml version="1.0" encoding="UTF-8"?>

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" version="1.0">
    <mapped-superclass class="MyThing">

    </mapped-superclass>
</entity-mappings>

没有别的。如果要覆盖属性,请使用@AttributeOverride,如上所示


答案 2

有可能:

  • 你可以用XML映射它 - 做一个(符合orm模式),并映射你的POJO的列,甚至不需要扩展它。它将在一个环境中启用JPA,在另一个环境中启用POJOorm.xml
  • 仅覆盖 getter 方法并注释它们 - (我不确定这是否有效)

也就是说,我认为没有必要这样做。只需注释 POJO,然后将编译时依赖项添加到项目中即可。然后,每个项目将决定是否将它们用作 JPA 实体。


推荐