Search code examples
javaspringhibernaterestpolymorphism

How to avoid hibernate from creating object of abstract class when using findAll() method?


I have abstract class Employee, and 3 concrete class that extends from employee. Classes who extends from Employee for example OfficeEmployee are currently empty and also represents table in db. Only purpose of these concrete classes is to have fk reference to Employee. For example if OfficeEmployee is created, a data will be saved in Employee entity and only id will be saved in OfficeEmployee entity.

This is my Employee class:

@Entity
@Data
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "employee_id", nullable = false, unique = true)
private int employeeId;

@Column(name = "employee_name", nullable = false)
private String name;

@Column(name = "reason_for_deactivation", length = 255)
private String reasonForDeactivation = "";

@Column(name = "deleted", nullable = false)
private Boolean isDeleted = Boolean.FALSE;
}

I have managed to write methods for saving,updating and deleting specific employee, but when i want to fetch all Employees i can't do that because hibernate in background is trying to create object from Employee class and i get error because that class is abstract.

This is method for getting all Employees:

@Service
public class EmployeeServiceImpl {

@Autowired
private EmployeeRepository employeeRepository;

  public List<Employee> findAll() {
    return employeeRepository.findAll();

 }
}

How can i solve this problem? I am open for any advice including changing my architecture.


Solution

  • The simplest solution is to add @DiscriminatorColumn on Employee entity and @DiscriminatorValue on concrete classes. So now it looks like this:

    @Entity
    @DiscriminatorColumn(name = "employee_type") // This is added
    @Data
    @Inheritance(strategy = InheritanceType.JOINED)
    public abstract class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "employee_id", nullable = false, unique = true)
    private int employeeId;
    
    @Column(name = "employee_name", nullable = false)
    private String name;
    
    @Column(name = "reason_for_deactivation", length = 255)
    private String reasonForDeactivation = "";
    
    @Column(name = "deleted", nullable = false)
    private Boolean isDeleted = Boolean.FALSE;
    }
    

    And concrete class:

    @Entity
    @Data
    @DiscriminatorValue("Office_Employee")  // This is added
    public class OfficeEmployee extends Employee{
    
    }
    

    Basically it will add new column in Employee entity called employee_type and based on that will have information on type of each employee, therefore i can now fetch all Employees.