I'm trying to create a really really dummy dictionary backend using hibernate and j2ee. (Just to learn these technologies.)
I have two entities 'Word' and 'Category' and there is a many to many relation between these. What I would like to reach is that, if I delete a category then it is getting removed from all of the affected words' categories but the words still exist and if I delete a word then from the category point of view nothing happens. Even there is no more word in that category the category should be exist.
Currently I cannot delete a category if there is one word in that category at least. (Recive: org.hibernate.exception.ConstraintViolationException: could not execute statement) And when I delete a word if there is no more word in that category then the category is getting removed with the word as well.
Here is how I declared the entities:
@Entity
@Table(name = "Word")
public class Word {
@Id()
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private String uid;
@NotNull
@Column(nullable = false, length = 512)
private String hungarian;
@NotNull
@Column(nullable = false, length = 512)
private String english;
@JoinColumn(name = "categories_uid")
@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
@Valid
private Set<Category> categories;
...
}
@Entity
@Table(name = "Category")
public class Category {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private String uid;
@NotNull
@Size(min = 3, max = 512)
@Column(nullable = false, length = 512)
private String name;
...
}
I didn't create Set in the Category class because there would be a lot of word in that set which could cause performance problem. If it was possible, I wouldn't create a Set in the Category class.
I thought that CascadeType.ALL should handle this.
Thanks in advance.
Your delete operation fails because of foreign key constraint. In this case you can define an owner side in your many-to-many relationship which is Word and then when you remove a Word the relationship will be handled automatically. But if you want to remove a Category you have to remove it manually like this:
@Entity
public class Word {
@ManyToMany
Set<Category> categories;
@Entity
public class Category {
@ManyToMany(mappedBy="categories")
Set<Word> words;
// call you entity manager to remove a category
em.remove(category);
for (Word word : category.words) {
word.categories.remove(category);
}