Issue
Let's say I have a Post and Tag entity, with ManyToMany relation. I only want to store unique Tags. The issue is, Hibernate won't let me add a Post if it contains a Tag with a name that the Tags table already has. In this case, I would like to just refer to the already existing Tag.
If I remove the unique restriction from Tags, it works fine, but then I can have identical Tag names in my Tag table, which would be redundant.
Do I need to check the POST request if any of it's tag exists already then alter the request to fit in, or is there a better way?
Post:
@Entity
@Table(name = "posts")
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "posts_tags",
joinColumns = @JoinColumn(name = "posts_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "tags_id", referencedColumnName = "id"))
private Set<Tag> tags = new HashSet<>();
// ...
Tags:
@Entity
@Table(name = "tags")
public class Tag {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Size(max = 15)
@Column(unique = true)
private String name;
@ManyToMany(mappedBy = "tags")
@JsonIgnore
private Set<Post> posts = new HashSet<>();
//...
PostController:
@PostMapping("/posts")
public Post createPost(@Valid @RequestBody Post post) {
return postRepository.save(post);
}
Solution
It's all related to the persistence context
.
In your case, you need to first check that any of its tags exists already, if yes then use that one to attach to your request.
If you check that object then it will be in persistence context
state and hibernate will know that the same tag already exists, and it will not try to insert a new tag and you will not get any error as well.
Answered By - SSK
Answer Checked By - Gilberto Lyons (JavaFixing Admin)