Search code examples
javahibernatecomposite-primary-keynhibernate-inheritance

@IdClass with @Inheritance(strategy = InheritanceType.SINGLE_TABLE)


I use hibernate. I have an abstract class:

@Data
@Entity
@Table(schema = "timesheetdb", name = "project_property")
@IdClass(ProjectPropertyPK.class)
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
public abstract class ProjectPropertyAbstract {

    @Id
    private Integer projectId;

    @Id
    private String type;
}
@Data
@Embeddable
public class ProjectPropertyPK implements Serializable {

    private Integer projectId;
    private String type;
}

And inheritors

@Data
@Entity
@DiscriminatorValue("WAGE_FUND")
public class ProjectWageFundProperty extends ProjectPropertyAbstract {

    private Boolean isEnabled;
    private Integer percentProfit;
}
@Data
@Entity
@DiscriminatorValue("CROSS_STAFFING")
public class ProjectCrossStaffingProperty extends ProjectPropertyAbstract {
    
    private Boolean isEnabled;
}

I want it to be possible not to specify the type of the property in the descendants of the class and all the properties were stored in one table.

Also, with the current implementation, an error crashes when starting the server: Repeated column in mapping for entity: com.timesheet.entity.project.property.ProjectCrossStaffingProperty column: type (should be mapped with insert="false" update="false")

I tried to specify the @Column annotation(insert="false" update="false") above the "type" field, but then when saving and retrieving data, the "type" field was specified as null and it was impossible to return a unique property.


Solution

  • It is not possible to specify the DiscriminatorColumn as a property, as you have done here with type, hence the original error. If you add the suggested annotation, the value will be null, b/c it is no longer saved or fetched from the database.

    The solution is to either remove the type prop if it is not needed (which it normally shouldn't be), or to keep the annotation and set it manually in each child class.

    public ProjectWageFundProperty() {
        setType("WAGE_FUND");
    }