edmallia
edmallia

Reputation: 233

JPA 2.1 NamedSubgraph in Hibernate ignoring subclasses

I'm using Hibernate 4.3.8.FINAL and have the following model where a Department has many Employees, and an Employee can be a Manager.

The Employee entity:

@Entity
@Table(name = "employee", schema = "payroll")
@Inheritance(strategy = InheritanceType.JOINED)
public class Employee
{
    @Id
    private Long id;

    @Basic(optional = false)
    @Column(name = "name")
    private String name;

    @JoinColumn(name = "department_id", referencedColumnName = "id")
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private Department department;
}

The Manager entity:

@Entity
@Table(name = "manager", schema = "payroll")
@Inheritance(strategy = InheritanceType.JOINED)
@PrimaryKeyJoinColumn(name = "employee_id", referencedColumnName = "id")
public class Manager extends Employee
{
    @Basic(optional = false)
    @Column(name = "car_allowance")
    private boolean carAllowance;
}

The Department entity:

@NamedEntityGraph(
        name = "Graph.Department.FetchManagers",
        includeAllAttributes = false,
        attributeNodes = {
                @NamedAttributeNode(value = "name"),
                @NamedAttributeNode(value = "employees", subgraph = "FetchManagers.Subgraph.Managers")
        },
        subgraphs = {
                @NamedSubgraph(
                        name = "FetchManagers.Subgraph.Managers",
                        type = Employee.class,
                        attributeNodes = {
                                @NamedAttributeNode(value = "name")
                        }
                ),
                @NamedSubgraph(
                        name = "FetchManagers.Subgraph.Managers",
                        type = Manager.class,
                        attributeNodes = {
                                @NamedAttributeNode(value = "carAllowance"),
                        }
                )
        }
)
@Entity
@Table(name = "department", schema = "payroll")
public class Department
{

    @Id
    private Long id;

    @Basic(optional = false)
    @Column(name = "name")
    private String name;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "department", fetch = FetchType.LAZY)
    private Set<Employee> employees;
}

As shown in the Department entity, I'm trying to create an @NamedSubgraph that loads all the employees and to also fetch Manager.carAllowance. However I am getting the following error:

Unable to locate Attribute  with the the given name [carAllowance] on this ManagedType [com.nemea.hydra.model.test.Employee]

From my understanding, the @NamedSubgraph.type should be used to specify the entity subclass attributes to be fetched. Is it possible that Hibernate is ignoring the type=Manager.class attribute of the @NamedSubgraph annotation or am I missing something ?

Upvotes: 5

Views: 5448

Answers (1)

wypieprz
wypieprz

Reputation: 8219

This may be the imperfection of Hibernate 4.3.8.FINAL, as e.g. EclipseLink 2.5.1 does not throw the exception when subgraphs attribute is used.

Anyway it should work when you specify subclassSubgraphs rather than subclass in case of Manager type, that is:

@NamedEntityGraph(
    name = "Graph.Department.FetchManagers", 
    includeAllAttributes = false,
    attributeNodes = {
        @NamedAttributeNode(value = "name"),
        @NamedAttributeNode(value = "employees", subgraph = "FetchManagers.Subgraph.Managers")
    },
    subgraphs = {
        @NamedSubgraph(
            name = "FetchManagers.Subgraph.Managers",
            type = Employee.class,
            attributeNodes = {
                @NamedAttributeNode(value = "name")
            }
        )
    },
    subclassSubgraphs = {
        @NamedSubgraph(
            name = "FetchManagers.Subgraph.Managers",
            type = Manager.class,
            attributeNodes = {
                @NamedAttributeNode(value = "carAllowance"),
            }
        )
    }
)

Upvotes: 5

Related Questions