我需要一些关于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获取完整的来源
非常感谢任何帮助。
感谢。