Hibernate:投影多对多关系的特定列

时间:2015-01-07 21:51:01

标签: java hibernate many-to-many projection hibernate-criteria

我需要一些关于Hibernate Projections和标准API的帮助。当我在两个实体中包含字段(具有双向多对多映射)时,我只从根实体获得结果。

我定义了Employee

@Entity
@Table(name="EMPLOYEE")
public class Employee {

    @Id
    @Column(name="EMPLOYEE_ID")
    @GeneratedValue
    private Long employeeId;

    @Column(name="FIRSTNAME")
    private String firstname;

    @Column(name="LASTNAME")
    private String lastname;

    @ManyToMany(fetch = FetchType.EAGER , cascade = {CascadeType.ALL})
    @JoinTable(name="EMPLOYEE_MEETING",
            joinColumns={@JoinColumn(name="EMPLOYEE_ID")},
            inverseJoinColumns={@JoinColumn(name="MEETING_ID")})
    private Set<Meeting> meetings = new HashSet<Meeting>();

    public Employee() {
    }

    public Employee(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }
...

Meeting

@Entity
@Table(name="MEETING")
public class Meeting {

    @Id
    @Column(name="MEETING_ID")
    @GeneratedValue
    private Long meetingId;

    @Column(name="SUBJECT")
    private String subject;

    @Column(name="MEETING_DATE")
    private Date meetingDate;

    @ManyToMany(mappedBy="meetings")
    private Set<Employee> employees = new HashSet<Employee>();

他们的schema

CREATE TABLE employee (
    employee_id serial,
    firstname VARCHAR(50) NULL DEFAULT NULL,
    lastname VARCHAR(50) NULL DEFAULT NULL,
    PRIMARY KEY (employee_id)
);


CREATE TABLE meeting (
    meeting_id serial,
    subject VARCHAR(50) NOT NULL,
    meeting_date DATE NOT NULL,
    PRIMARY KEY (meeting_id)
);


CREATE TABLE employee_meeting (
    employee_id BIGINT NOT NULL,
    meeting_id BIGINT NOT NULL,
    PRIMARY KEY (employee_id, meeting_id),
    CONSTRAINT FK_EMPLOYEE FOREIGN KEY (employee_id) REFERENCES employee (employee_id),
    CONSTRAINT FK_MEETING FOREIGN KEY (meeting_id) REFERENCES meeting (meeting_id)
);

我希望得到一份包含会议属性的员工名单。

没有where子句。

Meeting meeting1 = new Meeting("Quaterly Status meeting");
Meeting meeting2 = new Meeting("Weekly Status meeting");
Meeting meeting3 = new Meeting("daily Status meeting");

Employee employee1 = new Employee("Gingerly", "Brint");
Employee employee2 = new Employee("Mary", "Kate");

employee1.getMeetings().add(meeting1);
employee1.getMeetings().add(meeting2);
employee2.getMeetings().add(meeting1);
employee2.getMeetings().add(meeting3);

meeting1.getEmployees().add(employee1);
meeting1.getEmployees().add(employee2);
meeting2.getEmployees().add(employee1);
meeting3.getEmployees().add(employee2);

session.save(employee1);
session.save(employee2);

Criteria criteria = session.createCriteria(Employee.class, "e");
criteria.setFetchMode("e.meetings", FetchMode.JOIN);
criteria = criteria.createAlias("e.meetings", "m", JoinType.LEFT_OUTER_JOIN);
final ProjectionList projections = Projections.projectionList()
        .add(Projections.property("e.firstname"))
        .add(Projections.property("m.subject"))
        ;
criteria.setProjection(projections);
final List<Object> list = criteria.list();

如果我不包含任何投影,hibernate会返回一个填写了一组会议的员工。

如果我包含投影,则hibernate仅返回带有Employee列的结果

当我查看引擎盖时,我发现对于没有指定投影的情况,hibernate会发出以下SQL查询。

select 
    this_.EMPLOYEE_ID as EMPLOYEE1_0_1_,
    this_.FIRSTNAME as FIRSTNAM2_0_1_,
    this_.LASTNAME as LASTNAME3_0_1_,
    meetings2_.EMPLOYEE_ID as EMPLOYEE1_0_3_,
    meeting3_.MEETING_ID as MEETING_2_1_3_,
    meeting3_.MEETING_ID as MEETING_1_2_0_,
    meeting3_.MEETING_DATE as MEETING_2_2_0_,
    meeting3_.SUBJECT as SUBJECT3_2_0_
from
    EMPLOYEE this_ 
        left outer join
    EMPLOYEE_MEETING meetings2_ ON this_.EMPLOYEE_ID = meetings2_.EMPLOYEE_I
        left outer join
    MEETING meeting3_ ON meetings2_.MEETING_ID = meeting3_.MEETING_ID;

当我指定投影时,我只获得Employee表列的结果。下面的示例查询。

select 
    this_.FIRSTNAME as y0_, m1_.SUBJECT as y1_
from
    EMPLOYEE this_
        left outer join
    EMPLOYEE_MEETING meetings3_ ON this_.EMPLOYEE_ID = meetings3_.EMPLOYEE_ID
        left outer join
    MEETING m1_ ON meetings3_.MEETING_ID = m1_.MEETING_ID;

即使SQL查询包含对主题的投影,我也不会得到结果。

can clone my repo获取完整的来源

非常感谢任何帮助。

感谢。

0 个答案:

没有答案