hibernate(jpa)继承

pprl5pva  于 2021-06-26  发布在  Java
关注(0)|答案(2)|浏览(374)

我正在构建一个规则引擎系统,我希望允许用户获取他们请求的规则以及他们作为通知接收者订阅的规则
我正在努力编写一个查询,通过给定一个用户名获取用户名请求的所有规则,或者他在通知中列出
因为我是hibernate+springjpa的新手,所以我很难判断这是一个糟糕的设计还是仅仅缺乏构建复杂查询的知识
我的计划描述如下。
规则.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();
    }

谢谢你的帮助。

fdbelqdn

fdbelqdn1#

我可以通过修改类的继承类型来解决这个问题 Action.javaSINGLE_TABLE 使用下面的查询

"select r from Rule r left join fetch r.actions action " +
            "left join action.notifications n where r.requester = :name or (type(action) = Alert and n.login = :login)"
3j86kqsm

3j86kqsm2#

你的设计看起来不错。我假设查询错误是因为操作和通知之间没有关系,所以

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);

相关问题