3

我的 JPA 测试应用程序会跟踪用户在我所在城镇访问过的酒吧数量。我在用户对象上有这个

@ManyToMany(mappedBy = "users")
private List<Pub> visited;

而另一边的 pub 对象

@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(
    joinColumns =
@JoinColumn(name = "pubid"),
inverseJoinColumns =
@JoinColumn(name = "userid"))
protected Set<User> users;

但是,我已经更新了 pub 表,其中有一列指示 pub 已关闭。我只希望用户的访问列表包含活动的酒吧,所以问题是

我怎样才能有条件地加入这些对象,以便只有通过测试(例如 table.closed=false)的 pub 才会被放入用户的访问列表中?

我在下面使用hibernate和postgres。

4

3 回答 3

6

我暂时使用 Hibernate 特定的 @Where 注释解决了这个问题。我只需要在用户的 pub 集合上添加一个额外的注释,如下所示:

@ManyToMany(mappedBy = "users")
@Where(clause="closed='false'")
private List<Pub> visited;

当然,我现在被锁定在 Hibernate 中,这对这个项目来说不是一个大问题,但如果有人有通用的 JPA 解决方案,我很想听听。

于 2012-10-25T09:09:11.100 回答
1

有几种方法可以实现,或者更确切地说模拟你想要的,但不幸的是没有真正干净的方法。

您可以@PostLoad在 User 实体本身或专用侦听器中使用方法(使用注释您的实体@EntityListeners(YourFilter.class)以配置侦听器。)。在这种方法中,您可以按照您想要的方式过滤实体。

这种方法的主要问题是,当您持久化/合并时,过滤器所做的更改也将被持久化。

这是可以避免的——除了原始的持久列表之外,您还可以有一个单独的临时列表来保存过滤后的 pub。或者您可以保留 PostLoad 过滤并简单地在 getter 中过滤。这听起来可能很肮脏,但听者的方法是变相的肮脏。

于 2012-10-24T15:42:59.927 回答
0

您可以使用子类化来创建纯 JPA 解决方案:

  • 在 Pub 上使用“封闭”字段作为 @DiscriminatorColumn。
  • 创建一个新类“OpenPubs”并使用“false”作为@DiscriminatorValue
  • 将“已访问”映射到子类“OpenPubs”
于 2013-08-16T09:09:06.797 回答