hibernate entity inheritance casting strategy and Mapped SupperClass

Mapping strategy of JPA entity inheritance entity

 

Three: SINGLE_TABLE (default), TABLE_PER_CLASS, JOINED

 

SINGLE_TABLE : The parent and child class Entity fields are written to the same table

 

@Entity  
@Table(name = "EMP")  
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)  
@DiscriminatorColumn(name = "emp_type")  
public class Employee implements Serializable {  
  
    private static final long serialVersionUID = -7674269980281525370L;  
      
    @Id  
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    protected Integer empId;  
      
    @Column  
    protected String name;  
  
    // getter/setter methods  
      
}  

@Entity  
@DiscriminatorValue("FT")  
public class FullTimeEmployee extends Employee {  

    @Column  
    private Double salary;  
    // getter/setter methods  
      
}

@Entity  
@DiscriminatorValue("PT")  
public class PartTimeEmployee extends Employee {

    @Column(name = "hourly_wage")  
    private Float hourlyWage;  
  
    // getter/setter methods  
  
}

 Conclusion: Only one table will be generated, containing the fields emp_type, empId, name, salary, hourly_wage. When saving FullTimeEmployee, the value of emp_type is "FT", and when saving PartTimeEmployee, the value of emp_type is "PT".

 

Note: DiscriminatorColumn can correspond to a column (emp_type) in the table to distinguish which subclass the record is generated by.

 

 

 Disadvantage: The column corresponding to the subclass field must allow null.

 

TABLE_PER_CLASS :  The parent class and the child class each generate a table, and the child class only inherits the primary key of the parent class as its own primary key, and does not inherit other attributes. And the data inserted by the subclass has nothing to do with the parent class.

 

 

 

@Entity  
@Table(name = "EMP")  
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)  
public class Employee implements Serializable {  
  
    private static final long serialVersionUID = -7674269980281525370L;  
      
    @Id  
    @GeneratedValue(strategy = GenerationType.TABLE)  
    protected Integer empId;  
      
    @Column  
    protected String name;  
  
    // getter/setter methods  
      
}  
  
@Entity  
@Table(name = "FT_EMP")  
public class FullTimeEmployee extends Employee {  
  
    private static final long serialVersionUID = 9115429216382631425L;  
  
    @Column  
    private Double salary;  
  
    // getter/setter methods  
      
}  
@Entity  
@Table(name = "PT_EMP")  
public class PartTimeEmployee extends Employee {  
  
    private static final long serialVersionUID = -6122347374515830424L;  
  
    @Column(name = "hourly_wage")  
    private Float hourlyWage;  
  
    // getter/setter methods  
  
}

 

 

Conclusion: This will be mapped into three specific tables, namely, Employee corresponds to EMP table, with fields including empId and name; FullTimeEmployee corresponds to FT_EMP table, with fields including empId and salary; PartTimeEmployee corresponds to PT_EMP table, with fields including empId and hourly_wage. Among them, the empId in the tables FT_EMP and PT_EMP has nothing to do with the empId of the EMP table. Each time a subclass entity saves a piece of data, no record will be inserted into the EMP table.

 

Notice:

1 The table generation strategy of table_per_class is only applicable when the abstract class will not be referenced in the code of other entities.

Such as:

@Entity  
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) //Error, can't run, if you change to JOINED strategy
public abstract class Human implements Serializable {  
    private static final long serialVersionUID = 1856374544815477685L;  
        //..........................................  
}  

@Entity  
@Table(name="EMPLOYEE_INFO")  
public class Employee extends Human {  
     //...............................  
}

@Entity  
public class Award implements Serializable {  
    @ManyToOne  
    private Human publisher;  
}  

2 The generation strategy of the primary key cannot use GenerationType.AUTO or GenerationType.IDENTITY, otherwise an exception will occur:

org.hibernate.MappingException: Cannot use identity column key generation with <union-subclass> mapping for: com.mikan.PartTimeEmployee

Because the TABLE_PER_CLASS strategy is separate for each table, and there is no relationship between the primary keys of each table, the GenerationType.AUTO or GenerationType.IDENTITY primary key generation strategy cannot be used, and GenerationType.TABLE can be used.

 

JOINED:  The subclass and the parent class generate tables respectively, the subclass only inherits the primary key of the parent class as its own primary key, and the parent class corresponds to the foreign key of the table. The data inserted by the subclass is related to the parent class

 

 

@Entity  
@Table(name = "EMP")  
@Inheritance(strategy = InheritanceType.JOINED)  
public class Employee implements Serializable {  
  
    private static final long serialVersionUID = -7674269980281525370L;  
      
    @Id  
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    protected Integer empId;  
      
    @Column  
    protected String name;  
  
    // getter/setter methods  
      
}  
  
@Entity  
@Table(name = "FT_EMP")  
public class FullTimeEmployee extends Employee {  
  
    private static final long serialVersionUID = 9115429216382631425L;  
  
    @Column  
    private Double salary;  
  
    // getter/setter methods  
      
}
@Entity  
@Table(name = "PT_EMP")  
public class PartTimeEmployee extends Employee {  
  
    private static final long serialVersionUID = -6122347374515830424L;  
  
    @Column(name = "hourly_wage")  
    private Float hourlyWage;  
  
    // getter/setter methods  
  
}  

 

 

Conclusion: This will be mapped into three specific tables, namely, Employee corresponds to EMP table, with fields including empId and name; FullTimeEmployee corresponds to FT_EMP table, with fields including empId and salary; PartTimeEmployee corresponds to PT_EMP table, with fields including empId and hourly_wage. Among them, the empId in the tables FT_EMP and PT_EMP is used as the foreign key of the table EMP, and it is also the primary key. By default, the superclass's primary key is used as the subclass's primary and foreign keys. Of course, [email protected] said, if FullTimeEmployee is annotated with @PrimaryKeyJoinColumn(name = "FT_EMPID"), then the fields of the subclass entity are FT_EMPID, name, FT_EMPID is used as the primary key of the table FT_TIME, and it is also the foreign key of the EMP table .

Each time a subclass entity saves a piece of data, a record will be inserted into the EMP table. For example, when a piece of data is inserted into the FT_EMP table, the name will be inserted into the EMP table first, empId will be generated, and then empId and salary will be inserted into the FT_EMP table. PT_EMP is the same.
Regardless of whether the superclass is an abstract class or a concrete class, the corresponding table will be generated.

 

Mapped SupperClass: The parent class does not correspond to a table, and the subclass inherits all the properties of the parent class to generate its own table. And can not query the parent class and other operations (because it does not correspond to the table)

Such as:

@MappedSuperclass
 public class Employee {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private String depart;

    // Getters and Setters
 
 }
 @Entity
 public class Manager extends Employee {
     private String office;
     private String car;

   // Getters and Setters
 }

 Conclusion: Generate the table structure corresponding to the subclass:

 CREATE TABLE `manager` ( 

  `ID` bigint(20) NOT NULL, 

  `OFFICE` varchar(255) default NULL, 

  `CAR` varchar(255) default NULL, 

  `DEPART` varchar(255) default NULL, 

  `NAME` varchar(255) default NULL, 

  PRIMARY KEY  (`ID`) 

 

 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326836624&siteId=291194637