Java Tutorial/JPA/Inheritance

Материал из Java эксперт
Перейти к: навигация, поиск

Abstract Class As Mapped Superclass

File: Customer.java



import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Version;
@Entity
@Table(name = "ADDRESS")
class Address implements Serializable {
  protected String city;
  @Id
  protected Long id;

  @Version
  protected Long version;
  @Column(name = "ZIP_CODE")
  protected Long zipCode;
  public Address() {
  }
  public String getCity() {
    return city;
  }
  public void setCity(String city) {
    this.city = city;
  }
  public void setId(Long id) {
    this.id = id;
  }
  public Long getId() {
    return id;
  }
  public Long getZipCode() {
    return zipCode;
  }
  public void setZipCode(Long zipCode) {
    this.zipCode = zipCode;
  }
}
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "TYPE")
class Employee extends Person implements Serializable {
  protected String email;
  protected String dept;
  public Employee() {
  }
  public String getEmail() {
    return email;
  }
  public void setEmail(String email) {
    this.email = email;
  }
  public String getDept() {
    return dept;
  }
  public void setDept(String dept) {
    this.dept = dept;
  }
}
@MappedSuperclass
abstract class Person implements Serializable {

  @OneToOne(cascade = { CascadeType.ALL })
  @JoinColumn(name = "HOME_ADDRESS", referencedColumnName = "ID")
  private Address homeAddress;
  @Id
  @Column(nullable = false)
  @GeneratedValue(generator = "PersonIdGenerator")
  private Long id;

  @Version
  private Long version;
  public Person() {
  }
  public Address getHomeAddress() {
    return homeAddress;
  }
  public void setHomeAddress(Address homeAddress) {
    this.homeAddress = homeAddress;
  }
  public Long getId() {
    return id;
  }
  public void setId(Long id) {
    this.id = id;
  }
}





Adding Properties To SubClasses

File: Employee.java



import java.util.Date;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.MappedSuperclass;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name = "EMP")
@Inheritance
@DiscriminatorColumn(name = "EMP_TYPE")
public abstract class Employee {
  @Id
  private int id;
  private String name;
  @Temporal(TemporalType.DATE)
  @Column(name = "S_DATE")
  private Date startDate;
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public Date getStartDate() {
    return startDate;
  }
  public void setStartDate(Date startDate) {
    this.startDate = startDate;
  }
  public String toString() {
    return "Employee id: " + getId() + " name: " + getName();
  }
}
@MappedSuperclass
abstract class AbstractEmployee extends Employee {
  private int vacation;
  public int getVacation() {
    return vacation;
  }
  public void setVacation(int vacation) {
    this.vacation = vacation;
  }
}
@Entity
@DiscriminatorValue("FTEmp")
class FullTimeEmployee extends AbstractEmployee {
  private long salary;
  private long pension;
  public long getPension() {
    return pension;
  }
  public void setPension(long pension) {
    this.pension = pension;
  }
  public long getSalary() {
    return salary;
  }
  public void setSalary(long salary) {
    this.salary = salary;
  }
  public String toString() {
    return "FullTimeEmployee id: " + getId() + " name: " + getName();
  }
}
@Entity(name = "PTEmp")
@DiscriminatorValue("PTEmp")
class PartTimeEmployee extends AbstractEmployee {
  @Column(name = "H_RATE")
  private float hourlyRate;
  public float getHourlyRate() {
    return hourlyRate;
  }
  public void setHourlyRate(float hourlyRate) {
    this.hourlyRate = hourlyRate;
  }
  public String toString() {
    return "PartTimeEmployee id: " + getId() + " name: " + getName();
  }
}





Add Properties In Abstract Entity

File: Helper.java



import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
public class Helper {
  public static void checkData() throws Exception {
    Class.forName("org.hsqldb.jdbcDriver");
    Connection conn = DriverManager.getConnection("jdbc:hsqldb:data/tutorial", "sa", "");
    Statement st = conn.createStatement();
    ResultSet mrs = conn.getMetaData().getTables(null, null, null, new String[] { "TABLE" });
    while (mrs.next()) {
      String tableName = mrs.getString(3);
      System.out.println("\n\n\n\nTable Name: "+ tableName);
      ResultSet rs = st.executeQuery("select * from " + tableName);
      ResultSetMetaData metadata = rs.getMetaData();
      while (rs.next()) {
        System.out.println(" Row:");
        for (int i = 0; i < metadata.getColumnCount(); i++) {
          System.out.println("    Column Name: "+ metadata.getColumnLabel(i + 1)+ ",  ");
          System.out.println("    Column Type: "+ metadata.getColumnTypeName(i + 1)+ ":  ");
          Object value = rs.getObject(i + 1);
          System.out.println("    Column Value: "+value+"\n");
        }
      }
    }
  }
}





Change Inheritance Type

File: Employee.java



import java.util.Date;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name="EMP")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="EMP_TYPE")
public abstract class Employee {
    @Id private int id;
    private String name;
    @Temporal(TemporalType.DATE)
    @Column(name="S_DATE")
    private Date startDate;

    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    public Date getStartDate() {
        return startDate;
    }
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }
    public String toString() {
        return "Employee id: " + getId() + " name: " + getName();
    }
}
@Entity
@Table(name="COMPANY_EMP")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
 abstract class CompanyEmployee extends Employee {
    private int vacation;

    public int getVacation() {
        return vacation;
    }
    public void setVacation(int vacation) {
        this.vacation = vacation;
    }
}
@Entity 
 class FullTimeEmployee extends CompanyEmployee {
    private long salary;
    @Column(name="PENSION")
    private long pensionContribution;
    
    public long getPensionContribution() {
        return pensionContribution;
    }
    
    public void setPensionContribution(long pension) {
        this.pensionContribution = pension;
    }
    
    public long getSalary() {
        return salary;
    }
    
    public void setSalary(long salary) {
        this.salary = salary;
    }
    public String toString() {
        return "FullTimeEmployee id: " + getId() + " name: " + getName();
    }
}
@Entity
 class PartTimeEmployee extends CompanyEmployee {
    @Column(name="H_RATE")
    private float hourlyRate;

    public float getHourlyRate() {
        return hourlyRate;
    }
    public void setHourlyRate(float hourlyRate) {
        this.hourlyRate = hourlyRate;
    }
    public String toString() {
        return "PartTimeEmployee id: " + getId() + " name: " + getName();
    }
}





Discriminator Column And Discriminator Value

File: Person.java



import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
@Entity
@Table(name = "PERSON_HIERARCHY")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("PERSON")
public class Person implements java.io.Serializable {
  private int id;
  private String firstName;
  private String lastName;
  @Id
  @GeneratedValue
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getFirstName() {
    return firstName;
  }
  public void setFirstName(String first) {
    this.firstName = first;
  }
  public String getLastName() {
    return lastName;
  }
  public void setLastName(String last) {
    this.lastName = last;
  }
}
@Entity
@DiscriminatorValue("CUST")
class Customer extends Person {
  private String street;
  private String city;
  private String state;
  private String zip;
  public String getStreet() {
    return street;
  }
  public void setStreet(String street) {
    this.street = street;
  }
  public String getCity() {
    return city;
  }
  public void setCity(String city) {
    this.city = city;
  }
  public String getState() {
    return state;
  }
  public void setState(String state) {
    this.state = state;
  }
  public String getZip() {
    return zip;
  }
  public void setZip(String zip) {
    this.zip = zip;
  }
}
@Entity
class Employee extends Customer {
  private int employeeId;
  public int getEmployeeId() {
    return employeeId;
  }
  public void setEmployeeId(int id) {
    employeeId = id;
  }
}





Discriminator Type: INTEGER

File: Employee.java



import java.util.Date;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name="EMP")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="EMP_TYPE", discriminatorType=DiscriminatorType.INTEGER)
public abstract class Employee {
    @Id private int id;
    private String name;
    @Temporal(TemporalType.DATE)
    @Column(name="S_DATE")
    private Date startDate;
    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    public Date getStartDate() {
        return startDate;
    }
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }
    public String toString() {
        return "Employee id: " + getId() + " name: " + getName();
    }
}

@Entity
@Table(name="PT_EMP")
@DiscriminatorValue("3")
 class PartTimeEmployee extends Employee {
    @Column(name="H_RATE")
    private float hourlyRate;
    public float getHourlyRate() {
        return hourlyRate;
    }
    public void setHourlyRate(float hourlyRate) {
        this.hourlyRate = hourlyRate;
    }
    public String toString() {
        return "PartTimeEmployee id: " + getId() + " name: " + getName();
    }
}
@Entity
@Table(name="FT_EMP")
@DiscriminatorValue("2")
 class FullTimeEmployee extends Employee {
    private long salary;
    private long pension;
    
    public long getPension() {
        return pension;
    }
    
    public void setPension(long pension) {
        this.pension = pension;
    }
    
    public long getSalary() {
        return salary;
    }
    
    public void setSalary(long salary) {
        this.salary = salary;
    }
    public String toString() {
        return "FullTimeEmployee id: " + getId() + " name: " + getName();
    }
}





Inheritance Type JOINED

File: Employee.java



import java.util.Date;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name="EMP")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="EMP_TYPE", discriminatorType=DiscriminatorType.INTEGER)
public abstract class Employee {
    @Id private int id;
    private String name;
    @Temporal(TemporalType.DATE)
    @Column(name="S_DATE")
    private Date startDate;
    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    public Date getStartDate() {
        return startDate;
    }
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }
    public String toString() {
        return "Employee id: " + getId() + " name: " + getName();
    }
}

@Entity
@Table(name="PT_EMP")
@DiscriminatorValue("3")
 class PartTimeEmployee extends Employee {
    @Column(name="H_RATE")
    private float hourlyRate;
    public float getHourlyRate() {
        return hourlyRate;
    }
    public void setHourlyRate(float hourlyRate) {
        this.hourlyRate = hourlyRate;
    }
    public String toString() {
        return "PartTimeEmployee id: " + getId() + " name: " + getName();
    }
}
@Entity
@Table(name="FT_EMP")
@DiscriminatorValue("2")
 class FullTimeEmployee extends Employee {
    private long salary;
    private long pension;
    
    public long getPension() {
        return pension;
    }
    
    public void setPension(long pension) {
        this.pension = pension;
    }
    
    public long getSalary() {
        return salary;
    }
    
    public void setSalary(long salary) {
        this.salary = salary;
    }
    public String toString() {
        return "FullTimeEmployee id: " + getId() + " name: " + getName();
    }
}





Inheritance Type TABLE_PER_CLASS

File: Helper.java



import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
public class Helper {
  public static void checkData() throws Exception {
    Class.forName("org.hsqldb.jdbcDriver");
    Connection conn = DriverManager.getConnection("jdbc:hsqldb:data/tutorial", "sa", "");
    Statement st = conn.createStatement();
    ResultSet mrs = conn.getMetaData().getTables(null, null, null, new String[] { "TABLE" });
    while (mrs.next()) {
      String tableName = mrs.getString(3);
      System.out.println("\n\n\n\nTable Name: "+ tableName);
      ResultSet rs = st.executeQuery("select * from " + tableName);
      ResultSetMetaData metadata = rs.getMetaData();
      while (rs.next()) {
        System.out.println(" Row:");
        for (int i = 0; i < metadata.getColumnCount(); i++) {
          System.out.println("    Column Name: "+ metadata.getColumnLabel(i + 1)+ ",  ");
          System.out.println("    Column Type: "+ metadata.getColumnTypeName(i + 1)+ ":  ");
          Object value = rs.getObject(i + 1);
          System.out.println("    Column Value: "+value+"\n");
        }
      }
    }
  }
}





Mark Abstract Entity With Inheritance

File: Employee.java



import java.util.Date;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity 
@Table(name="EMP")
@Inheritance
@DiscriminatorColumn(name="EMP_TYPE")
public abstract class Employee  {
    @Id private int id;
    private String name;
    @Temporal(TemporalType.DATE)
    @Column(name="S_DATE")
    private Date startDate;
    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    public Date getStartDate() {
        return startDate;
    }
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }
    public String toString() {
        return "Employee id: " + getId() + " name: " + getName();
    }
}
@Entity
class ContractEmployee extends Employee {
    @Column(name="D_RATE")
    private int dailyRate;
    private int term;
    
    public int getDailyRate() {
        return dailyRate;
    }
    
    public void setDailyRate(int dailyRate) {
        this.dailyRate = dailyRate;
    }
    
    public int getTerm() {
        return term;
    }
    
    public void setTerm(int term) {
        this.term = term;
    }
    public String toString() {
        return "ContractEmployee id: " + getId() + " name: " + getName();
    }
}





Mark Discriminator Column For Entities In Hierarchy

File: Employee.java



import java.util.Date;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.MappedSuperclass;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name = "EMP")
@Inheritance
@DiscriminatorColumn(name = "EMP_TYPE")
public abstract class Employee {
  @Id
  private int id;
  private String name;
  @Temporal(TemporalType.DATE)
  @Column(name = "S_DATE")
  private Date startDate;
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public Date getStartDate() {
    return startDate;
  }
  public void setStartDate(Date startDate) {
    this.startDate = startDate;
  }
  public String toString() {
    return "Employee id: " + getId() + " name: " + getName();
  }
}
@MappedSuperclass
abstract class AbstractEmployee extends Employee {
  private int vacation;
  public int getVacation() {
    return vacation;
  }
  public void setVacation(int vacation) {
    this.vacation = vacation;
  }
}
@Entity
@DiscriminatorValue("FTEmp")
class FullTimeEmployee extends AbstractEmployee {
  private long salary;
  private long pension;
  public long getPension() {
    return pension;
  }
  public void setPension(long pension) {
    this.pension = pension;
  }
  public long getSalary() {
    return salary;
  }
  public void setSalary(long salary) {
    this.salary = salary;
  }
  public String toString() {
    return "FullTimeEmployee id: " + getId() + " name: " + getName();
  }
}
@Entity(name = "PTEmp")
@DiscriminatorValue("PTEmp")
class PartTimeEmployee extends AbstractEmployee {
  @Column(name = "H_RATE")
  private float hourlyRate;
  public float getHourlyRate() {
    return hourlyRate;
  }
  public void setHourlyRate(float hourlyRate) {
    this.hourlyRate = hourlyRate;
  }
  public String toString() {
    return "PartTimeEmployee id: " + getId() + " name: " + getName();
  }
}





Persist subclass

File: Employee.java



import java.util.Date;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity 
@Table(name="EMP")
@Inheritance
@DiscriminatorColumn(name="EMP_TYPE")
public abstract class Employee  {
    @Id private int id;
    private String name;
    @Temporal(TemporalType.DATE)
    @Column(name="S_DATE")
    private Date startDate;
    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    public Date getStartDate() {
        return startDate;
    }
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }
    public String toString() {
        return "Employee id: " + getId() + " name: " + getName();
    }
}
@Entity
class ContractEmployee extends Employee {
    @Column(name="D_RATE")
    private int dailyRate;
    private int term;
    
    public int getDailyRate() {
        return dailyRate;
    }
    
    public void setDailyRate(int dailyRate) {
        this.dailyRate = dailyRate;
    }
    
    public int getTerm() {
        return term;
    }
    
    public void setTerm(int term) {
        this.term = term;
    }
    public String toString() {
        return "ContractEmployee id: " + getId() + " name: " + getName();
    }
}





Set Discriminator Value In Subclass

File: Employee.java



import java.util.Date;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name="EMP")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="EMP_TYPE", discriminatorType=DiscriminatorType.INTEGER)
public abstract class Employee {
    @Id private int id;
    private String name;
    @Temporal(TemporalType.DATE)
    @Column(name="S_DATE")
    private Date startDate;
    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    public Date getStartDate() {
        return startDate;
    }
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }
    public String toString() {
        return "Employee id: " + getId() + " name: " + getName();
    }
}

@Entity
@Table(name="PT_EMP")
@DiscriminatorValue("3")
 class PartTimeEmployee extends Employee {
    @Column(name="H_RATE")
    private float hourlyRate;
    public float getHourlyRate() {
        return hourlyRate;
    }
    public void setHourlyRate(float hourlyRate) {
        this.hourlyRate = hourlyRate;
    }
    public String toString() {
        return "PartTimeEmployee id: " + getId() + " name: " + getName();
    }
}
@Entity
@Table(name="FT_EMP")
@DiscriminatorValue("2")
 class FullTimeEmployee extends Employee {
    private long salary;
    private long pension;
    
    public long getPension() {
        return pension;
    }
    
    public void setPension(long pension) {
        this.pension = pension;
    }
    
    public long getSalary() {
        return salary;
    }
    
    public void setSalary(long salary) {
        this.salary = salary;
    }
    public String toString() {
        return "FullTimeEmployee id: " + getId() + " name: " + getName();
    }
}





Three Leve Entity Hierarchy

File: Employee.java



import java.util.Date;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.MappedSuperclass;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name = "EMP")
@Inheritance
@DiscriminatorColumn(name = "EMP_TYPE")
public abstract class Employee {
  @Id
  private int id;
  private String name;
  @Temporal(TemporalType.DATE)
  @Column(name = "S_DATE")
  private Date startDate;
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public Date getStartDate() {
    return startDate;
  }
  public void setStartDate(Date startDate) {
    this.startDate = startDate;
  }
  public String toString() {
    return "Employee id: " + getId() + " name: " + getName();
  }
}
@MappedSuperclass
abstract class AbstractEmployee extends Employee {
  private int vacation;
  public int getVacation() {
    return vacation;
  }
  public void setVacation(int vacation) {
    this.vacation = vacation;
  }
}
@Entity
@DiscriminatorValue("FTEmp")
class FullTimeEmployee extends AbstractEmployee {
  private long salary;
  private long pension;
  public long getPension() {
    return pension;
  }
  public void setPension(long pension) {
    this.pension = pension;
  }
  public long getSalary() {
    return salary;
  }
  public void setSalary(long salary) {
    this.salary = salary;
  }
  public String toString() {
    return "FullTimeEmployee id: " + getId() + " name: " + getName();
  }
}
@Entity(name = "PTEmp")
@DiscriminatorValue("PTEmp")
class PartTimeEmployee extends AbstractEmployee {
  @Column(name = "H_RATE")
  private float hourlyRate;
  public float getHourlyRate() {
    return hourlyRate;
  }
  public void setHourlyRate(float hourlyRate) {
    this.hourlyRate = hourlyRate;
  }
  public String toString() {
    return "PartTimeEmployee id: " + getId() + " name: " + getName();
  }
}