Java 是否可以将 JPA 注释添加到超类实例变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2883033/
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
Is it possible to add JPA annotation to superclass instance variables?
提问by Kristofer
I am creating entities that are the same for two different tables. In order do table mappings etc. different for the two entities but only have the rest of the code in one place - an abstract superclass. The best thing would be to be able to annotate generic stuff such as column names (since the will be identical) in the super class but that does not work because JPA annotations are not inherited by child classes. Here is an example:
我正在为两个不同的表创建相同的实体。为了对两个实体进行不同的表映射等,但仅将其余代码放在一个地方 - 一个抽象超类。最好的办法是能够在超类中注释通用的东西,例如列名(因为它们是相同的),但这不起作用,因为 JPA 注释不是由子类继承的。下面是一个例子:
public abstract class MyAbstractEntity {
@Column(name="PROPERTY") //This will not be inherited and is therefore useless here
protected String property;
public String getProperty() {
return this.property;
}
//setters, hashCode, equals etc. methods
}
Which I would like to inherit and only specify the child-specific stuff, like annotations:
我想继承并且只指定特定于孩子的东西,比如注释:
@Entity
@Table(name="MY_ENTITY_TABLE")
public class MyEntity extends MyAbstractEntity {
//This will not work since this field does not override the super class field, thus the setters and getters break.
@Column(name="PROPERTY")
protected String property;
}
Any ideas or will I have to create fields, getters and setters in the child classes?
有什么想法或者我必须在子类中创建字段、getter 和 setter 吗?
Thanks, Kris
谢谢,克里斯
采纳答案by sblundy
You might want to annotate MyAbstractEntity with @MappedSuperclassclass so that hibernate will import the configuration of MyAbstractEntity in the child and you won't have to override the field, just use the parent's. That annotation is the signal to hibernate that it has to examine the parent class too. Otherwise it assumes it can ignore it.
您可能希望使用@MappedSuperclassclass注释 MyAbstractEntity,以便 hibernate 将在子项中导入 MyAbstractEntity 的配置,并且您不必覆盖该字段,只需使用父项的。该注释是休眠的信号,它也必须检查父类。否则它认为它可以忽略它。
回答by J?rn Horstmann
Annotating your base class with @MappedSuperclassshould do exactly what you want.
注释您的基类@MappedSuperclass应该完全符合您的要求。
回答by Sean Patrick Floyd
Mark the superclass as
将超类标记为
@MappedSuperclass
and remove the property from the child class.
并从子类中删除该属性。
回答by Wayne Riesterer
Here is an example with some explanations that may help.
这是一个带有一些解释的示例,可能会有所帮助。
@MappedSuperclass:
@MappedSuperclass:
- Is a convenience class
- Is used to store shared state & behavior available to child classes
- Is not persistable
- Only child classes are persistable
- 是方便类
- 用于存储子类可用的共享状态和行为
- 不可持久化
- 只有子类是持久化的
@Inheritance specifies one of three mapping strategies:
@Inheritance 指定三种映射策略之一:
- Single-Table
- Joined
- Table per Class
- 单桌
- 加入
- 每班表
@DiscriminatorColumn is used to define which column will be used to distinguish between child objects.
@DiscriminatorColumn 用于定义将使用哪一列来区分子对象。
@DiscriminatorValue is used to specify a value that is used to distinguish a child object.
@DiscriminatorValue 用于指定用于区分子对象的值。
The following code results in the following:
以下代码产生以下结果:


You can see that the id field is in both tables, but is only specified in the AbstractEntityId @MappedSuperclass.
可以看到 id 字段在两个表中,但只在 AbstractEntityId @MappedSuperclass 中指定。
Also, the @DisciminatorColumn is shown as PARTY_TYPE in the Party table.
此外,@DisciminatorColumn 在 Party 表中显示为 PARTY_TYPE。
The @DiscriminatorValue is shown as Person as a record in the PARTY_TYPE column of the Party table.
@DiscriminatorValue 在 Party 表的 PARTY_TYPE 列中显示为 Person 作为记录。
Very importantly, the AbstractEntityId class does not get persisted at all.
非常重要的是,AbstractEntityId 类根本不会持久化。
I have not specified @Column annotations and instead are just relying on the default values.
我没有指定 @Column 注释,而是仅依赖于默认值。
If you added an Organisation entity that extended Party and if that was persisted next, then the Party table would have:
如果您添加了一个扩展 Party 的 Organization 实体,并且接下来将其保留,则 Party 表将具有:
- id = 2
- PARTY_TYPE = "Organisation"
- 编号 = 2
- PARTY_TYPE = "组织"
The Organisation table first entry would have:
组织表的第一个条目将具有:
- id = 2
- other attribute value associated specifically with organisations
- 编号 = 2
- 与组织特别相关的其他属性值
@MappedSuperclass
@SequenceGenerator(name = "sequenceGenerator",
initialValue = 1, allocationSize = 1)
public class AbstractEntityId implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(generator = "sequenceGenerator")
protected Long id;
public AbstractEntityId() {}
public Long getId() {
return id;
}
}
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "PARTY_TYPE",
discriminatorType = DiscriminatorType.STRING)
public class Party extends AbstractEntityId {
public Party() {}
}
@Entity
@DiscriminatorValue("Person")
public class Person extends Party {
private String givenName;
private String familyName;
private String preferredName;
@Temporal(TemporalType.DATE)
private Date dateOfBirth;
private String gender;
public Person() {}
// getter & setters etc.
}
Hope this helps :)
希望这可以帮助 :)

![Java Hibernate 会话刷新行为 [ 和 Spring @Transactional ]](/res/img/loading.gif)