【问题标题】:Cascade insert of new and existing entities新实体和现有实体的级联插入
【发布时间】:2015-05-11 13:13:33
【问题描述】:

我有一个“标记”机制(有点像 Gmail 的标签),为了这个问题,我想用它标记另一个实体 - 员工。

Tag 实体很简单,只包含名称,如下所示:

@Entity
public class Tag implements Serializable {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "tag_id", unique = true, nullable = false)
  private Long id;

  @Column(name = "name", unique = true)
  private String name;

  @ManyToMany(fetch = FetchType.LAZY, mappedBy = "tags")
  private Set<Employee> employees = new HashSet<>(0);
  public String getName() {
    return name;
  }

  public void setName(final String name) {
    this.name = name;
  }

  public Set<Employee> getEmployees() {
    return employees;
  }

}

我的 Employee 实体如下所示:

@Entity
public class Employee implements Serializable {

  private static final long serialVersionUID = -6809049173391335091L;

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "employee_id", unique = true, nullable = false)
  private Long id;

  @Column
  private String name;

  @Column
  private String description;

  @Column
  @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
  @JoinTable(name = "employee_tag", joinColumns = {
      @JoinColumn(name = "employee_id", nullable = false, updatable = false) },
      inverseJoinColumns = { @JoinColumn(name = "tag_id",
              nullable = false, updatable = false) })
  private List<Tag> tags = new ArrayList<>();

  // Rest of Getters and Setters


  public List<Tag> getTags() {
    return tags;
  }

  public void setTagsFromString(final String tags) {    
    String[] realTagsSplitted = tags.split(",");
    for(String tagString: realTagsSplitted) {
      Tag tag = new Tag();
      tag.setName(tagString);
      this.tags.add(tag);
  }
}

我想做的是能够从 UI 标记添加到 Employee 实体。但标签是 UI 中的纯字符串。我希望当 Employee 实体被持久化以使标签也被持久化时 BUT 我不希望标签表中出现重复(通过重复我,当然,意味着不应该存在两个标签名称相同但 id 不同)。

含义 - 如果表中存在标签“Tag1”而标签“Tag2”不存在,并且用户在 UI 中将“Tag1”和“Tag2”都添加到员工“Employee1”我想:

  1. 在连接表中创建一个新行,将“Employee1”的 id 绑定到“Tag1”的 id。
  2. 使用“Tag2”在 Tag 表中创建一个新行
  3. 在连接表中创建一个新行,将“Employee1”的 id 绑定到新创建的“Tag2”的 id。

我真的更喜欢在代码级别处理它,如果存在解决方案,最好使用注释。我试图避免 DB 触发器和阅读代码时不明显的事情。

【问题讨论】:

    标签: java spring entity-framework hibernate jpa


    【解决方案1】:

    您应该在服务级别而不是实体中处理此问题。这些步骤中的一些东西:

    1. 创建一个类似findOrCreateTag(tagName)的方法,如果存在则从数据库中返回现有标签,如果不存在则创建一个新标签
    2. 为您从 UI 获得的每个标签调用此方法,并将其添加到 employee#tags(另外,将员工添加到 tag#employees
    3. 保存对员工的更改

    一件小事,从Employee#tags 映射中删除@Column

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 1970-01-01
      • 2018-12-05
      • 2013-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多