java - 具有一对多的 Hibernate (JPA) 继承
问题描述
我正在构建一个规则引擎系统,我希望允许用户获取他们请求的规则和他们作为通知收件人订阅的规则
我正在努力编写一个查询,通过给定用户名获取用户名请求的所有规则,或者他在通知中列出
由于我是 Hibernate + Spring JPA 的新手,我很难确定这是设计不佳还是缺乏构建复杂查询的知识
我的方案描述如下。
规则.java
@Entity
@Table(name = "rule")
public class Rule implements Serializable {
...
@Column(name = "requester")
private String requester;
@OneToMany
@JoinColumn(name = "rule_id", referencedColumnName = "id")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private Set<Action> actions = new HashSet<>();
...
// getter, setters
}
动作.java
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "action_type")
public class Action implements Serializable {
...
@Id
@GeneratedValue
private Long id;
@Column(name = "active")
private Boolean active;
...
// getter, setters
}
任务
@Entity
public class Task extends Action {
...
@Column(name = "task_name")
private String taskName;
...
// getter, setters
}
警报
@Entity
public class Alert extends Action implements Serializable {
...
@ManyToMany
@JoinTable(
name = "alert_notification",
joinColumns = @JoinColumn(name = "alert_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "notification_id", referencedColumnName = "id"))
private Set<Notification> notifications = new HashSet<>();
...
// getter, setters
}
通知
@Entity
@Table(name = "notification")
@Inheritance(strategy = InheritanceType.JOINED)
public class Notification implements Serializable {
...
@Column(name = "username")
private String username;
// getter, setters
...
}
电子邮件通知
@Entity
@Table(name = "email_notification")
public class EmailNotification extends Notification {
...
@Column(
name = "email",
nullable = false
)
private String email;
...
// getter, setters
}
松弛通知
@Entity
@Table(name = "teams_notification")
public class SlackNotification extends Notification {
...
// getter, setters
...
}
我尝试运行下面的 JPA 查询,但没有成功。
@Transactional(readOnly = true)
public List<Rule> findAllByLogin(String login) {
TypedQuery<Rule> query = em.createQuery("select r from Rule r join fetch r.actions a join fetch a.notifications n " +
"where type(a) = Alert and n.login = '" + login +"' or r.requester = '" + login +"'", Rule.class);
return query.getResultList();
}
任何帮助表示赞赏。
解决方案
你的设计看起来不错。我假设查询错误是因为动作和通知之间没有关系,所以加入
join fetch a.notifications
应该与警报实体一起制作。根据这个答案,您应该使用 TREAT 指令:
TypedQuery<Rule> query = em.createQuery("select r from Rule r "
+ "join fetch TREAT (r.actions as Alert) a "
+ "join fetch a.notifications n "
+ "where type(a) = Alert and n.login = '" + login +"' or r.requester = '" + login +"'", Rule.class);
推荐阅读
- c# - 带有 TestCaseSource 的 NUnit 在 VS2019 中发现了额外的无源测试
- nlp - 如何读取或打开 qrel 格式的文件?
- javascript - AppScript 组 getUser() 权限错误
- python - 从嵌套的 python 列表中获取 n 最小值
- typescript - 是否可以在自己的扩展约束中使用泛型类型参数?
- jquery - ACF Medical 数据比较两种药物
- python - 没有通过 Pytorch 更新线性回归中的偏差
- html - 仅显示背景图像的顶部
- python - 赋值前引用的局部变量“intent”
- python - 通过pandas为excel中的某些单元格添加颜色 - python