I found this post where it is mentioned that problem can be caused by incorrect equals & hashcode implemantation, but it looks like it isn't... Hibernate 3.6.10 doesn't cascade delete through OneToMany JoinTable
Code (javax.validation.constraints annotations removed)
Author:
import org.bulletin_board.domain.address.Address;
import lombok.*;
import lombok.experimental.FieldDefaults;
import javax.persistence.*;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Objects;
@Entity
@Getter
@Setter
@FieldDefaults(level = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PACKAGE)
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@Builder
public class Author {
@Id
@Column(name = "author_id", updatable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
int id;
@Column(name = "first_name")
String firstName;
@Column(name = "last_name")
String lastName;
int age;
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE},
fetch = FetchType.EAGER,
orphanRemoval = true)
@JoinColumn(name = "FK_Author_Address")
Address address;
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE},
orphanRemoval = true)
@JoinTable(name = "Author_Email",
joinColumns = @JoinColumn(name = "author_id"),
inverseJoinColumns = @JoinColumn(name = "email_id"),
uniqueConstraints = @UniqueConstraint(columnNames = "author_id"))
List<Email> emails;
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE},
orphanRemoval = true)
@JoinTable(name = "Author_Phone",
joinColumns = @JoinColumn(name = "author_id"),
inverseJoinColumns = @JoinColumn(name = "phone_id"),
uniqueConstraints = @UniqueConstraint(columnNames = "author_id"))
List<Phone> phones;
@Override
public String toString() {
return "Author:" +
"id = " + id +
", firstName = '" + firstName + '\'' +
", lastName = '" + lastName + '\'' +
", age = " + age +
", address = " + address +
", \nemails: " + emails +
", \nphones:" + phones;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Author author = (Author) o;
return id == author.id && age == author.age && firstName.equals(author.firstName) && lastName.equals(author.lastName) && address.equals(author.address) && emails.equals(author.emails) && phones.equals(author.phones);
}
@Override
public int hashCode() {
return Objects.hash(id, firstName, lastName, age, address, emails, phones);
}
}
import lombok.*;
import lombok.experimental.FieldDefaults;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import java.util.Objects;
@Entity
@Getter
@Setter
@FieldDefaults(level = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PACKAGE)
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@Builder
public class Email {
@Id
@Column(name = "email_id", updatable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
int id;
String name;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Email email = (Email) o;
return id == email.id && name.equals(email.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}
Phone
Phone is similar to Email
Criteria author removing:
public void deleteById(int id) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaDelete<Author> delete = cb.createCriteriaDelete(Author.class);
Root<Author> root = delete.from(Author.class);
delete.where(cb.equal(root.get(Author_.id), id));
em.createQuery(delete).executeUpdate();
}
Problem:
When i'm trying to remove author with the code above, hibernate doesn't delete rows in phone & email tables. Only:
Hibernate: delete from Author_Email where (author_id) in (select author_id from Author where author_id=1)
Hibernate: delete from Author_Phone where (author_id) in (select author_id from Author where author_id=1)
Hibernate: delete from Author where author_id=1
How I can achieve that Hibernate delete the rows in phone & email tables too? I'm using postgres