@MappedSuperclass注解的使用说明

转载自:http://blog.sina.com.cn/s/blog_7085382f0100uk4p.html

基于代码复用和模型分离的思想,在项目开发中使用JPA的@MappedSuperclass注解将实体类的多个属性分别封装到不同的非实体类中。

1.@MappedSuperclass注解只能标准在类上:@Target({java.lang.annotation.ElementType.TYPE})

2.标注为@MappedSuperclass的类将不是一个完整的实体类,他将不会映射到数据库表,但是他的属性都将映射到其子类的数据库字段中。

3.标注为@MappedSuperclass的类不能再标注@Entity或@Table注解,也无需实现序列化接口。

但是如果一个标注为@MappedSuperclass的类继承了另外一个实体类或者另外一个同样标注了@MappedSuperclass的类的话,他将可以使用@AttributeOverride或@AttributeOverrides注解重定义其父类(无论是否是实体类)的属性映射到数据库表中的字段。

比如可以重定义字段名或长度等属性,使用@AttributeOverride中的子属性@Column进行具体的定义。

注意:对于其父类中标注@Lob注解的属性将不能重载,并且@AttributeOverride里的@Column设置都将不起作用。

JPA规范中对@Lob注解并没有说明不能同时标注@Column注解,但是在实际使用中Hibernate JPA不支持这中标注方式。

4.此外,这样的类还可以直接标注@EntityListeners实体监听器,他的作用范围仅在其所有继承类中,并且实体监听器同样可以保被其子类继承或重载。

5.标注为@MappedSuperclass的类其属性最好设置为protected或default类型的,以保证其同一个包下的子类可以直接调用它的属性。便于实体监听器或带参数构造函数的操作。

6.由于标注为@MappedSuperclass的类将不是一个完整的实体类,因此其不能标注@Table,并且无法使用@UniqueConstraint设置字段的Unique属性,这一点以及对属性类型重载(如重载标注为@Lob的属性)的支持JPA规范还有待改进。

7.可以同时标注@DiscriminatorValue注解,以设定实体子类的实体标识字段的值。该属性一般是在实体继承的时候使用的较多,但是在实体映射的时候可以不用设置。

8.比较实体继承与实体映射的区别

实体继承的三种策略分别是:SINGLE_TABLE(所有继承的实体都保存在同一张数据库表中),JOINED(每个实体子类都将保存在一个单独的表中),TABLE_PER_CLASS(有继承关系的所有实体类都将保存在单独的表中)。

实体映射最类似于JOINED实体继承方式,他也是将实体子类单独保存为一张表,但是两者最大的区别就在于:查询的时候JOINED使用的是多态查询,在查询父类时其所有实体子类的数据也将同时被查询出,因此查询时间和性能都将有影响。但是实体映射方式的数据库查询等同于没有实体继承关系的查询,也就是说,他仅在实体层体现出一种继承的关系却并没有在数据库中体现这样一种关系,他的操作都是独立的并且将不会影响到实体子类。

Hibernate之jpa实体映射的三种继承关系

转载自:http://www.cnblogs.com/shangxiaofei/p/5704321.html

在JPA中,实体继承关系的映射策略共有三种:单表继承策略(table per class)、Joined策略(table per subclass)和Table_PER_Class策略。

1.单表继承策略

单表继承策略,父类实体和子类实体共用一张数据库表,在表中通过一列辨别字段来区别不同类别的实体。具体做法如下:

a.在父类实体的@Entity注解下添加如下的注解:

@Inheritance(Strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name=”辨别字段列名”)
@DiscriminatorValue(父类实体辨别字段列值)

b.在子类实体的@Entity注解下添加如下的注解:

@DiscriminatorValue(子类实体辨别字段列值)

定义了一个父类

  1. @Entity
  2. @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
  3. @Table(name = "WINDOW_FILE")
  4. @DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING, length = 30)
  5. @DiscriminatorValue("WindowFile")
  6. public class WindowFile {
  7. @Id
  8. @GeneratedValue(strategy = GenerationType.AUTO)
  9. private Integer id;
  10. @Basic
  11. @Column(name = "NAME")
  12. private String name;
  13. @Basic
  14. @Column(name = "TYPE")
  15. private String type;
  16. @Basic
  17. @Column(name = "DATE")
  18. private Date date;
  19. //省略get set
  20. }

后定义2个子类

  1. @Entity
  2. @DiscriminatorValue("Folder")
  3. public class Folder extends WindowFile {
  4. @Basic
  5. @Column(name = "FILE_COUNT")
  6. private Integer fileCount;
  7. //省略get set
  8. }
  1. @Entity
  2. @DiscriminatorValue("Document")
  3. public class Document extends WindowFile {
  4. @Basic
  5. @Column(name = "SIZE")
  6. private String size;
  7. //省略get set
  8. }

以上通过列DISCRIMINATOR的不同,区分具体父子实体。

实际表结构如下:

WINDOW_FILE  DISCRIMINATOR,ID,NAME,DATE,TYPE,SIZE,FILE_COUNT

当你使用WindowFile实体时,实际表的字段为DISCRIMINATOR=‘WindowFile‘,SIZE与FILE_COUNT永远是空

当使用Folder实体时,DISCRIMINATOR=‘Folder‘,SIZE永远是空,FILE_COUNT为实际值。

Document同理,与Folder类似。

2.Joined策略

父类实体和子类实体分别对应数据库中不同的表,子类实体的表中只存在其扩展的特殊属性,父类的公共属性保存在父类实体映射表中。具体做法:

@Inheritance(Strategy=InheritanceType.JOINED)

子类实体不需要特殊说明。

  1. @Entity
  2. @Table(name = "T_ANIMAL")
  3. @Inheritance(strategy = InheritanceType.JOINED)
  4. public class Animal {
  5. @Id
  6. @Column(name = "ID")
  7. @GeneratedValue(strategy = GenerationType.AUTO)
  8. private Integer id;
  9. @Column(name = "NAME")
  10. private String name;
  11. @Column(name = "COLOR")
  12. private String color;
  13. //省略get set
  14. }
  1. @Entity
  2. @Table(name = "T_BIRD")
  3. @PrimaryKeyJoinColumn(name = "BIRD_ID")
  4. public class Bird extends Animal {
  5. @Column(name = "SPEED")
  6. private String speed;
  7. //省略get set
  8. }
  1. @Entity
  2. @Table(name = "T_DOG")
  3. @PrimaryKeyJoinColumn(name = "DOG_ID")
  4. public class Dog extends Animal {
  5. @Column(name = "LEGS")
  6. private Integer legs;
  7. //省略get set
  8. }

实际表结构如下:

T_ANIMAL  ID,COLOR,NAME

T_BIRD  SPEED,BIRD(既是外键,也是主键)

T_DOG  LEGS,DOG_ID(既是外键,也是主键)

3.Table_PER_Class策略:

Table_PER_Class策略,父类实体和子类实体每个类分别对应一张数据库中的表,子类表中保存所有属性,包括从父类实体中继承的属性。具体做法:

只需在父类实体的@Entity注解下添加如下注解:

@Inheritance(Strategy=InheritanceType.TABLE_PER_CLASS)

  1. @Entity
  2. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
  3. @Table(name = "T_VEHICLE")
  4. public class Vehicle { // 基类
  5. @Id
  6. // @GeneratedValue
  7. @Column(name = "ID")
  8. private Integer id;
  9. @Column(name = "SPEED")
  10. private Integer speed;// 速度
  11. //省略get set
  12. }
  1. @Entity
  2. @Table(name = "T_CAR")
  3. public class Car extends Vehicle {
  4. @Column(name = "ENGINE")
  5. private String engine;// 发动机
  6. //省略get set
  7. }

一旦使用这种策略就意味着你不能使用AUTO generator 和IDENTITY generator,即主键值不能采用数据库自动生成。

实际表结构如下:

T_VEHICLE  ID,SPEED

T_CAR  ID,SPEED,ENGINE

时间: 2024-10-12 21:56:09

@MappedSuperclass注解的使用说明的相关文章

Jpa实体VO使用继承的实体的做法@MappedSuperclass注解的使用

在我们开发一个项目的时候,同城定义实体的时候,都会进行一些抽象,也就是面向对象的一些思想.1比如无论是数据实体还是其他类型的实体都会有id字段2.对于数据实体一般都会有创建人,创建时间,更新人,更新时间,备注等等. 这个时候我们想的肯定是将这些公共的抽象到公共的vo中去,然后具体的不同vo再继承这些公共的vo. 在JPA中因为每一个实体对应的是一个表,这时候就有可能出现虽然继承了,但是并不能扫描到那些在公共实体中的字段,这时候我们可以使用注解@MappedSuperclass,这个注解的作用就是

注解@MappedSuperclass的作用

使用条件:当我们进行开发项目时,我们经常会用到实体映射到数据库表的操作,此时我们经常会发现在我们需要映射的几个实体类中,会有共同的属性,例如编号ID,创建者,创建时间,修改者,修改时间,备注等.遇到这种情况,我们可能会想到把这些属性抽象出来当成一个父类,然后再以不同的实体类来继承这个父类.那么,我们便可以使用@MappedSuperclass注解 通过这个注解,我们可以将该实体类当成基类实体,它不会映射到数据库表, 继承它的子类实体在映射时会自动扫描该基类实体的映射属性,添加到子类实体的对应数据

(转)Hibernate 注解详解

原博:http://blog.csdn.net/sufei58/article/details/48223731 仅作为收藏使用. 一.实体Bean 每个持久化POJO类都是一个实体Bean, 通过在类的定义中使用 @Entity 注解来进行声明. 声明实体Bean @Entitypublic class Flightimplements Serializable {  Long id;  @Id  public Long getId() { return id; }  public void

Hibernate注解详解

一.实体Bean 每个持久化POJO类都是一个实体Bean, 通过在类的定义中使用 @Entity 注解来进行声明. 声明实体Bean @Entitypublic class Flightimplements Serializable {  Long id;  @Id  public Long getId() { return id; }  public void setId(Long id) { this.id = id; }} @Entity 注解将一个类声明为实体Bean, @Id 注解声

An entity cannot be annotated with both @Entity and @MappedSuperclass: com.example1.demo1.Entity.User错误

项目问SpringDataJpa项目,在运行的过程中出现的以下错误: Caused by: org.hibernate.AnnotationException: An entity cannot be annotated with both @Entity and @MappedSuperclass: com.example1.demo1.Entity.User at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.ja

springboot报错,springboot注解

目录 SpringBoot注解 SpringBoot注解 一.注解(annotations)列表 @SpringBootApplication: ? 包含了@ComponentScan.@Configuration和@EnableAutoConfiguration注解.其中@ComponentScan让Spring Boot扫描到Configuration类并把它加入到程序上下文. @Configuration:等同于Spring的XML配置文件:使用Java代码可以检查类型安全. @Enabl

SpringBoot注解大全 转

一.注解(annotations)列表 @SpringBootApplication:包含了@ComponentScan.@Configuration和@EnableAutoConfiguration注解.其中@ComponentScan让spring Boot扫描到Configuration类并把它加入到程序上下文. @Configuration 等同于spring的XML配置文件:使用Java代码可以检查类型安全. @EnableAutoConfiguration 自动配置. @Compon

JPA实体继承的映射

注:文章中据说的实体指的是被@Entity注解的类. JPA中对象关系映射通常情况下是一个实体对应一个表,两个实体之间没有任何关系.如果两个实体之间是继承关系,那么该如何映射呢? JPA中的实体支持继承映射,多态关联,多态查询.抽象类和具体的类都可以是实体,且都可以使用@Entity来注解,映射成实体,并查询封装成一个实体.实体类可以继承非实体类,非实体类也可以继承实体类. JPA的继承映射有如下几种情况: 一.实体类继承抽象(具体)实体类 抽象类可以指定成为一个实体,抽象实体和具体实体的唯一区

hibernate的component使用

hibernate的Component,即组件,表示2个类之间的关系,即其中1个类可以作为另一个类的组件来使用. 1.先来看下annotation中关于component的API 2.2.2.3. 嵌入式对象(又名组件) 在实体中可以定义一个嵌入式组件(embedded component), 甚至覆盖该实体中原有的列映射. 组件类必须在类一级定义@Embeddable注解. 在特定的实体的关联属性上使用@Embedded和@AttributeOverride注解可以覆盖该属性对应的嵌入式对象的