级联插入新的和现有的实体

时间:2022-09-11 13:36:32

I have a 'tag' mechanism (kind of like Gmail's labels) with which I want to tag another entity, for the sake of the question - employees.

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

The Tag entity is simple and contains only name and looks as follows:

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

}

My Employee entity looks like this:

我的员工实体如下所示:

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

What I would like to do is to be able to add from the UI tags to an Employee entity. But the tags are plain strings in the UI. I would like that when the Employee entity is persisted to have the tags persisted as well BUT I don't want duplications in the tags table (by duplication I, of course, mean that no two tags should exist with the same name but different ids).

我想要做的是能够从UI标签添加到Employee实体。但标签是UI中的纯字符串。我希望当持久化Employee实体使标签保持不变时我也不希望在标签表中重复(通过复制我当然意味着不应该存在两个具有相同名称但不同ID的标签)。

Meaning - if the tag "Tag1" exists in the table and the tag "Tag2" doesn't and in the UI the user adds both "Tag1" and "Tag2" to Employee "Employee1" I would like to:

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

  1. Create a new row in the join-table that binds the id of "Employee1" to the id of "Tag1".
  2. 在join-table中创建一个新行,该行将“Employee1”的id绑定到id“Tag1”。

  3. Create a new row in the Tag table with "Tag2"
  4. 使用“Tag2”在Tag表中创建一个新行

  5. Create a new row in the join-table that binds the id of "Employee1" to the id of the newly created "Tag2".
  6. 在join-table中创建一个新行,该行将“Employee1”的id绑定到新创建的“Tag2”的id。

I really prefer to handle it on the code level, preferably with annotations if a solution exists. I'm trying to avoid DB triggers and things that are not obvious from reading the code.

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

1 个解决方案

#1


You should handle this on the service level, not in entities. Something along these steps:

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

  1. Create a method like findOrCreateTag(tagName), which would return existing tag from the database if it exists, or create a new one if it doesn't exist
  2. 创建一个像findOrCreateTag(tagName)这样的方法,它会从数据库中返回现有标记(如果存在),或者如果它不存在则创建一个新标记

  3. Call this method for each tag you get from UI, and add it to employee#tags (also, add the employee to tag#employees)
  4. 从UI获取的每个标记调用此方法,并将其添加到employee#tags(同样,将该员工添加到标记#employees)

  5. Save changes to employee
  6. 保存对员工的更改

One small thing, remove @Column from Employee#tags mapping.

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

#1


You should handle this on the service level, not in entities. Something along these steps:

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

  1. Create a method like findOrCreateTag(tagName), which would return existing tag from the database if it exists, or create a new one if it doesn't exist
  2. 创建一个像findOrCreateTag(tagName)这样的方法,它会从数据库中返回现有标记(如果存在),或者如果它不存在则创建一个新标记

  3. Call this method for each tag you get from UI, and add it to employee#tags (also, add the employee to tag#employees)
  4. 从UI获取的每个标记调用此方法,并将其添加到employee#tags(同样,将该员工添加到标记#employees)

  5. Save changes to employee
  6. 保存对员工的更改

One small thing, remove @Column from Employee#tags mapping.

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