如何在同一个表

时间:2017-06-13 09:02:27

标签: java jpa many-to-many

我有一种情况,一个实体可以使用另一个实体,它可以被另一个实体使用,所以我已经定义了一个引用同一个实体的ManyToMany关系,所以我可以拥有listUse和listUsedBy,并且两者都保持在同一个表entity_usage:

@ManyToMany
@JoinTable(name = "entity_usage",
        joinColumns = {
            @JoinColumn(name = "id_use", referencedColumnName = "id")},
        inverseJoinColumns = {
            @JoinColumn(name = "id_used_by", referencedColumnName = "id")})
private List<Entity> listUse;

@ManyToMany
@JoinTable(name = "entity_usage",
        joinColumns = {
            @JoinColumn(name = "id_use_by", referencedColumnName = "id")},
        inverseJoinColumns = {
            @JoinColumn(name = "id_use", referencedColumnName = "id")})
private List<Entity> listUsedBy;

例证:实体 A 可以使用实体 B C ,因此实体 B A 使用strong>和 C 。 现在我的问题是当我将b和C添加到listUse时,它们会持久保存在entity_usage中,但是当我尝试显示listUsedBy时我必须重新部署我的项目,否则listUsedBy仍然是空的,有没有办法刷新listUsedBy,当没有拥有我的实体时重新部署我的项目。

1 个答案:

答案 0 :(得分:3)

这是一般方法:

@Entity
public class SomeEntity
{
    @ManyToMany
    @JoinTable(name = "entity_usage",
        joinColumns = @JoinColumn(name = "using_id"),
        inverseJoinColumns = @JoinColumn(name = "used_by_id"))
    private Set<SomeEntity> using = new LinkedHashSet<>();

    @ManyToMany(mappedBy = "using")
    private Set<SomeEntity> usedBy = new LinkedHashSet<>();

    public void addUsing(SomeEntity entity)
    {
        this.using.add(entity);
        entity.usedBy.add(this);
    }

    public void addUsedBy(SomeEntity entity)
    {
        this.usedBy.add(entity);
        entity.using.add(this);
    }
}

并使用它:

public void someMethod(long parentEntityId, long childEntityId)
{
    EntityManager em = getSomeEntityManager();

    SomeEntity parentEntity = em.find(SomeEntity.class, parentEntityId);
    SomeEntity childEntity = em.find(SomeEntity.class, childEntityId);

    parentEntity.addUsing(childEntity);
}

通常这是一种事务性EJB方法 请注意,由于em.merge实体已经托管,因此无需em.find任何内容。 无论如何,无论您使用哪种方法来管理您的实体(查询,查找,保留,合并),请记住重要来调用addUsing / {{1} } 仅在管理两个实体时

这是ORM逻辑无法自行处理的主要不连贯点之一:您必须告知两个实体(父母和子女)的关系
它是仅仅在一方设置关系是不够的 - 如果你只说A是B的父母,B仍然不知道谁是其父母。

但是,存在替代方法,例如仅设置关系(addUsedBy)的拥有方,刷新并刷新子项。

尽管如此(因为我的皮肤经验非常好),在现实世界的复杂应用中,替代品很难处理。

作为旁注,除非您需要某种插入顺序,否则我会使用parent.getChildren().add(child)而不是Set作为关系。