Java Spring 填充双向关系

Java Spring populating bidirectional relationship

考虑一下我有这样的东西:

public class ClassifierGroupEntity extends AbstractEntity{
...
@OneToMany (mappedBy = "parent",
                fetch = FetchType.EAGER,
                cascade = CascadeType.PERSIST)
private List<ClassifierEntity> classifiers;
...
}

--

public class ClassifierEntity extends AbstractEntity {
...
    @ManyToOne
    private ClassifierGroupEntity parent;
...
}

如果我想给一个组添加一个新的分类器,我应该怎么做?这样可以吗?:

ClassifierGroupEntity ge = new ClassifierGroupEntity();
manager.saveClassifierGroup(ge);
ClassifierEntity e = new ClassifierEntity();
e.setParent(ge);
manager.saveClassifier(e);

您的方法将在基本级别起作用。我更喜欢以下范例(忽略 class 名称):

package org.example.project.domain;

@Entity
class Classifier {
  @ManyToOne
  private ClassifierGroup group;

  public ClassifierGroup getGroup() { return group; }

  // Package protected to prevent direct access.
  void setGroup(ClassifierGroup group) { this.group = group; }
}

@Entity
class ClassifierGroup {
  @OneToMany
  private List<Classifier> classifiers;

  public void addClassifier(Classifier classifier) {
    if(classifiers == null) {
      classifiers = new ArrayList<Classifier>();
    }

    classifiers.add(classifier);
    classifier.setGroup(this);
  }

  public List<Classifier> getClassifiers() {
    return Collections.unmodifiableList(classifiers != null ? classifiers : Collections.emptyList());
  }
}

ClassifierGroup group = new ClassifierGroup();
group.addClassifier(new Classifier());
manager.saveClassifierGroup(group);

或者更好的是,如果 group 对于 Classifier 是必需的,请在构造函数本身中设置它 (public Classifier(ClassifierGroup group))。

该策略具有以下主要特点:

  1. 关系由实体本身管理。外部各方不需要知道关系的细节。如果可以在多个地方实例化对象,这会派上用场,在这种情况下,关系管理代码可能必须在整个代码库中重复。
  2. 禁止直接访问数据(只有 getter,没有 setter)。因此,消费者不能执行 group.getClassifiers().clear()classifier.setGroup(null),可能会破坏对象图。