我有以下两个POJO:
@Entity
@Table
@Data
@EqualsAndHashCode(of={"identifier"})
@ToString(of={"identifier"})
public class Project {
@Column
@Id
@GeneratedValue
private Integer identifier;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "primaryKey.project")
private Set<MemberToProject> members = new HashSet<MemberToProject>();
}
@Entity
@Data
@Table
@EqualsAndHashCode(of={"identifier"})
@ToString(of={"identifier"})
public class Member {
@Column
@Id
@GeneratedValue
private Integer identifier;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "primaryKey.member")
private Set<MemberToProject> projects = new HashSet<MemberToProject>();
}
联接表的POJO如下:
@Entity
@Table
@Data
public class MemberToProject {
@Embeddable
@Data
public static class PrimaryKey implements Serializable {
@ManyToOne
private Member member;
@ManyToOne
private Project project;
}
@Column
@EmbeddedId
private PrimaryKey primaryKey;
}
我想为连接表添加一个单独的POJO,所以我可以添加属性,例如成员加入项目的日期,成员的权限等等。为了简洁,我把它留了出来。
我在数据库中填入了一些数据并执行以下代码:
final Session s = ...;
final Member m = (Member) s.load(Member.class, 3);
System.out.println(m.getProjects());
Hibernate会生成以下三个查询:
Hibernate:
select
member0_.identifier as identifi1_1_0_,
member0_.name as name2_1_0_
from
Member member0_
where
member0_.identifier=?
Hibernate:
select
projects0_.member_identifier as member1_1_1_,
projects0_.member_identifier as member1_4_1_,
projects0_.project_identifier as project2_4_1_,
projects0_.member_identifier as member1_4_0_,
projects0_.project_identifier as project2_4_0_
from
MemberToProject projects0_
where
projects0_.member_identifier=?
Hibernate:
select
project0_.identifier as identifi1_6_0_,
project0_.name as name2_6_0_
from
Project project0_
where
project0_.identifier=?
Hibernate在这里生成低效的查询。 membertoproject 中的项目和成员之间没有联接。我相信第二次和第三次查询可以/应该结合起来。我怎样才能做到这一点?
此外,第二个查询多次检索同一列,由于某些原因我不明白。
答案 0 :(得分:0)
我认为,'会员'和'项目'之间的关系是ManyToMany。
试试吧
@Entity
@Table
@Data
@EqualsAndHashCode(of={"identifier"})
@ToString(of={"identifier"})
public class Project {
@Column(name="PROJECT_ID")
@Id
@GeneratedValue
private Integer projectId;
@ManyToMany(cascade = CascadeType.ALL, mappedBy = "projects")
private Set<MemberToProject> members = new HashSet<MemberToProject>();
}
@Entity
@Data
@Table
@EqualsAndHashCode(of={"identifier"})
@ToString(of={"identifier"})
public class Member {
@Column(name="MEMBER_ID")
@Id
@GeneratedValue
private Integer memberId;
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name="MEMBER_PROJECT",
joinColumns={@JoinColumn(name="PROJECT_ID")},
inverseJoinColumns={@JoinColumn(name="MEMBER_ID")})
private Set<MemberToProject> projects = new HashSet<MemberToProject>();
}