我很难尝试将最佳数据库设计(使用BCNF)映射到JPA实体。
我有3个实体:地点,人物和行动 在给定的地方,您有人在执行操作,我们也有他们在那里执行操作的次数。
请注意,每个实体都可以独立存在:您可以拥有一个没有执行任何操作的地方,一个没有执行任何操作的人和没有被任何人执行的操作。
为了存储该信息,我将数据库模式建模为:
现在我正在尝试创建JPA实体来映射它,这就是我遇到问题的地方。
我想遍历从这个地方开始的对象,从提取的地方遍历,以便遍历执行其中所有操作的所有人,最后让每个人能够看到他们在那个地方执行了哪些操作 他们做了多少次。
从纯SQL的角度来看,这很容易:
获取该地点的人员列表:
然后,对于每个回来的人:
我想使用那种向下钻取行为在JPA实体中映射它:
这可能与JPA有关吗?或者我的想法是错误的?
这是我对实体的尝试:
从地点开始,引用人物:
public class Place implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(
name="ActionPerformed"
, joinColumns={
@JoinColumn(name="place_id", nullable=false)
}
, inverseJoinColumns={
@JoinColumn(name="person_id", nullable=false)
}
)
private List<Person> people;
<getters, setters, etc...>
}
然后是人们,引用已执行的操作(带计数):
public class Person implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
@OneToMany(mappedBy="person", fetch=FetchType.EAGER)
private List<ActionPerformed> actionsPerformed;
<getters, setters, etc...>
}
这些行动主要是为了他们的名字:
public class Action implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
<getters, setters, etc...>
}
连接表和PK对象关联所有这些:
@Entity
public class ActionPerformed implements Serializable {
@EmbeddedId
private ActionPerformedPK pk;
@Column(nullable=false)
private Integer count;
@ManyToOne
@JoinColumn(name="place_id")
private Place place;
@ManyToOne
@JoinColumn(name="person_id")
private Person person;
@ManyToOne
@JoinColumn(name="action_id")
private Action action;
<getters, setters, etc...>
}
@Embeddable
public class ActionPerformedPK implements Serializable {
private static final long serialVersionUID = 1L;
@Column(name="place_id")
private Integer placeId;
@Column(name="person_id")
private Integer personId;
@Column(name="action_id")
private Integer actionId;
<getters, setters, etc...>
}
我看到的一个问题是,当我查询某个地点时,我为每个执行操作的人获取了多个条目 - 在连接表中每个条目一个。 此外,在检查每个人中列出的操作时,我会获得该人在每个地方执行的所有操作(无视发起查询的地点)。
有没有办法在JPA映射或实体设计中解决这个问题?或者我是否必须更改数据库设计?
P.S。:我已经检查了至少十几个与此类似的问题的帖子,但没有一个完全符合我正在尝试的设计,所以在那里提出的解决方案在我的案例中是行不通的。
P.S.2:我正在使用Spring Data和CrudRepositories从实体创建存储库。
P.S.3:请原谅我的语法不好或“奇怪”的句子,英语不是我的母语。提前致谢!
答案 0 :(得分:0)
我没有逐行检查您的代码,因为我认为您的问题并未通过数据库设计和类注释来回答,而是通过查询来解答。
如果你想在比尔在伦敦完成所有的动作表演,那就写下像
这样的东西select ap from ActionPerformance ap where ap.person.name = "Bill" and ap.place.name = "London"
和JPQL将生成一些类似于你所描述的SQL。