为了账号安全,请及时绑定邮箱和手机立即绑定

有没有一种更清晰的方法可以在Spring JPA中构建MappedSuperclass Tree类?

有没有一种更清晰的方法可以在Spring JPA中构建MappedSuperclass Tree类?

呼如林 2022-09-07 21:31:33
我目前有几个实体作为树,需要将它们保存到数据库。因此,为了不重复代码,我构建了此类:@MappedSuperclasspublic abstract class TreeStructure<T extends TreeStructure>{    @ManyToOne(cascade = CascadeType.PERSIST)    private T  parent;    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)    protected Set<T> children = new HashSet<>();    /**     * Function that is used before deleting this entity. It joins this.children to this.parent and viceversa.     */    @Transactional    @PreRemove    public void preDelete()    {        unregisterInParentsChildren();        while (!children.isEmpty())        {            children.iterator().next().setParent(parent);        }    }    public abstract long getId();    protected void setParent(T pParent)    {        unregisterInParentsChildren();        parent = pParent;        registerInParentsChildren();    }    /**     * Register this TreeStructure in the child list of its parent if it's not null.     */    private void registerInParentsChildren()    {        getParent().ifPresent((pParent) -> pParent.children.add(this));    }    /**     * Unregister this TreeStructure in the child list of its parent if it's not null.     */    private void unregisterInParentsChildren()    {        getParent().ifPresent((pParent) -> pParent.children.remove(this));    }    /**     * Move this TreeStructure to an new parent TreeStructure.     *     * @param pNewParent the new parent     */    public void move(final T pNewParent)    {        if (pNewParent == null)        {            throw new IllegalArgumentException("New Parent required");        }        if (!isProperMoveTarget(pNewParent) /* detect circles... */)        {            throw new IllegalArgumentException(String.format("Unable to move Object %1$s to new Object Parent %2$s", getId(), pNewParent.getId()));        }        setParent(pNewParent);    }  所以,最后要说的是:有没有以更好/更干净的方式实现这一点?这个警告有意义,还是只是Intellij不够聪明?
查看完整描述

2 回答

?
慕侠2389804

TA贡献1719条经验 获得超6个赞

问题不在于JPA,而在于泛型的使用。


首先,更改抽象类签名,使其具有递归类型:


public abstract class TreeStructure<T extends TreeStructure<T>>

接下来,你不能引用'this',因为你不知道'this'的实现,所以你可以把它强制转换为'T',或者添加一个带有类似签名的抽象方法:


public abstract T getImpl();

在实现中,只需返回“this”。


public T getImpl() {

  return this;

}

在侧节点上,访问类中的父类实例变量可能不是一个好主意。向 TreeStructure 类添加一个 addChild 和 removeChild 方法可能是一个更好的主意。


查看完整回答
反对 回复 2022-09-07
?
守着一只汪

TA贡献1872条经验 获得超4个赞

我有一个非常类似的场景,我没有使用T。相反,我只有抽象类,因为我不需要类型化孩子的灵活性,而且我没有演员表。据我所知(共享代码),它可能会让你接地气,但我不知道你是否有其他要求。


在我的情况下,另一个区别是抽象类不是映射的超类,而是.@Inheritance(strategy = InheritanceType.SINGLE_TABLE)


如果可以提供帮助,您可以在此存储库中找到完整的工作示例


@Inheritance(strategy = InheritanceType.SINGLE_TABLE)

public abstract class TreeStructure {


    ...


    @ManyToOne(cascade = CascadeType.PERSIST)

    private TreeStructure  parent;


    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)

    protected Set<TreeStructure> children = new HashSet<>();


查看完整回答
反对 回复 2022-09-07
  • 2 回答
  • 0 关注
  • 113 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号