如何为JPA manyToMany连接添加防护

时间:2012-10-24 15:38:03

标签: java hibernate jpa

我的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已被关闭。我只希望用户的访问列表包含活动的pubs,所以问题是

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

我正在使用hibernate和postgres。

3 个答案:

答案 0 :(得分:6)

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

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

当然我现在已经锁定了Hibernate,这对于这个项目来说不是一个大问题,但是如果有人有一个通用的JPA解决方案,我很乐意听到它。

答案 1 :(得分:1)

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

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

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

这是可以避免的 - 您可以拥有一个单独的临时列表来保存过滤后的pubs以及原始持久化pub。或者你可以保留PostLoad过滤,只需在getter中过滤即可。这可能听起来很脏,但是听众的方法是伪装的。

答案 2 :(得分:0)

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

  • 在Pub。
  • 上使用“已关闭”字段作为@DiscriminatorColumn
  • 创建一个新类“OpenPubs”并使用“false”作为@DiscriminatorValue
  • 将“已访问”地图映射到子类“OpenPubs”