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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2516329/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 08:42:34  来源:igfitidea点击:

Is it possible to build a JPA entity by extending a POJO?

javajpa

提问by Freiheit

Lets say I have the following POJO:

假设我有以下 POJO:

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

Is it now possible to extend this POJO as a JPA entity?

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

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

I want to keep the POJO separate from the JPA entity. The POJO lives in a different project and is often used without a persistence layer, my project wants to persist it in a database and do so without the overhead of mapping from a POJO to an entity and back.

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

I understand that JPA entities are POJOs, but in order to use it I would have to include a library that implements javax.persistence and the other projects using the same base object have no use for a persistence layer.

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

Is this possible? Is this a good idea?

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

采纳答案by Arthur Ronald

JPA specification states

JPA 规范规定

Entities may extend non-entity classes as well as entity classes, and non-entity classes may extend entity classes.

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

@javax.persistence.MappedSuperclass annotation allows you to define this kind of mapping

@javax.persistence.MappedSuperclass 注解允许你定义这种映射

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

    // getter's and setter's
}

And

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


}

As said by JPA specification

正如 JPA 规范所说

The MappedSuperclass annotation designates a class whose mapping information is applied to the entities that inherit from it.

MappedSuperclass 注释指定一个类,其映射信息应用于从它继承的实体

And

A class designated with the MappedSuperclass annotation can be mapped in the same way as an entity except that the mappings will apply only to its subclassessince no table exists for the mapped superclass itself.

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

If you need to override some property defined by MyThing, use @AttributeOverride (when you want to override a single property) or @AttributeOverrides (when you want to override more than one property)

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

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


}

And

@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 {

}

If you do not want to change your base class, you can use xml to define it as a @MappedSuperClass

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

Be aware: by default, the persistence provider will look in the META-INF directory for a file named orm.xml

请注意:默认情况下,持久性提供程序将在 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>

Nothing else. If you want to override a property, use @AttributeOverride as shown above

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

回答by Bozho

It is possible:

有可能的:

  • you can map it with XML - make an orm.xml(conforming to the orm schema), and map the columns of your POJO, without even extending it. It will be JPA-enabled in one environment, and a POJO in the other one
  • override just the getter methods and annotate them - (I'm not sure if this will work)
  • 您可以使用 XML 映射它 - 制作一个orm.xml(符合orm 模式),并映射您的 POJO 的列,甚至无需扩展它。它将在一种环境中启用 JPA,而在另一种环境中启用 POJO
  • 仅覆盖 getter 方法并对其进行注释 - (我不确定这是否可行)

That said, I don't think it is necessary to do this. Just annotate your POJO, and add the compile-time dependency to your projects. Then each project will decide whether it will use them as JPA entities or not.

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