私はこれをいじって約4日間グーグルで検索していて、HibernateアノテーションがJPAアノテーションとどのように連携するかについて夢中になっています。私には2つの非常に単純なエンティティがあります。
学生
package com.vaannila.student;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
@Entity
public class Student {
@Id
@GeneratedValue
private long studentId;
private String studentName;
@OneToMany(orphanRemoval = true)
@Cascade(CascadeType.ALL)
@JoinTable(name = "STUDENT_PHONE", joinColumns = { @JoinColumn(name = "STUDENT_ID") }, inverseJoinColumns = { @JoinColumn(name = "PHONE_ID") })
private Set<Phone> studentPhoneNumbers = new HashSet<Phone>(0);
public Student() {
}
public Student(String studentName, Set<Phone> studentPhoneNumbers) {
this.studentName = studentName;
this.studentPhoneNumbers = studentPhoneNumbers;
}
public long getStudentId() {
return this.studentId;
}
public void setStudentId(long studentId) {
this.studentId = studentId;
}
public String getStudentName() {
return this.studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public Set<Phone> getStudentPhoneNumbers() {
return this.studentPhoneNumbers;
}
public void setStudentPhoneNumbers(Set<Phone> studentPhoneNumbers) {
this.studentPhoneNumbers = studentPhoneNumbers;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (studentId ^ (studentId >>> 32));
result = prime * result + ((studentName == null) ? 0 : studentName.hashCode());
result = prime * result + ((studentPhoneNumbers == null) ? 0 : studentPhoneNumbers.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Student other = (Student) obj;
if (studentId != other.studentId) return false;
if (studentName == null) {
if (other.studentName != null) return false;
}
else if (!studentName.equals(other.studentName)) return false;
if (studentPhoneNumbers == null) {
if (other.studentPhoneNumbers != null) return false;
}
else if (!studentPhoneNumbers.equals(other.studentPhoneNumbers)) return false;
return true;
}
}
電話
package com.vaannila.student;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Phone {
@Id
@GeneratedValue
private long phoneId;
private String phoneType;
private String phoneNumber;
public Phone() {
}
public Phone(String phoneType, String phoneNumber) {
this.phoneType = phoneType;
this.phoneNumber = phoneNumber;
}
public long getPhoneId() {
return this.phoneId;
}
public void setPhoneId(long phoneId) {
this.phoneId = phoneId;
}
public String getPhoneType() {
return this.phoneType;
}
public void setPhoneType(String phoneType) {
this.phoneType = phoneType;
}
public String getPhoneNumber() {
return this.phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (phoneId ^ (phoneId >>> 32));
result = prime * result + ((phoneNumber == null) ? 0 : phoneNumber.hashCode());
result = prime * result + ((phoneType == null) ? 0 : phoneType.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Phone other = (Phone) obj;
if (phoneId != other.phoneId) return false;
if (phoneNumber == null) {
if (other.phoneNumber != null) return false;
}
else if (!phoneNumber.equals(other.phoneNumber)) return false;
if (phoneType == null) {
if (other.phoneType != null) return false;
}
else if (!phoneType.equals(other.phoneType)) return false;
return true;
}
}
コード全体をここに貼り付けたので、インポートがどこから来たのかを確認できます。問題はそこにあると思います。重要:JoinTable
HibernateDocsが推奨するようにを使用しています
Ok!Student
次に、2つの電話番号を使用してを作成し、データベースに正しく保存します。これにより、以下が作成されます。
学生
studentid | studentname
-----------+-------------
2 | foo
(1 rows)
student_phone
student_id | phone_id
------------+---------
2 | 3
2 | 4
(2 rows)
電話
phoneid | phonenumber | phonetyp
---------+-------------+---------
4 | 9889343423 | mobile
3 | 32354353 | house
(2 rows)
ここに問題があります。クライアント側の電話番号(携帯電話)の1つを削除し、切り離された学生エンティティをサーバーに送信して更新を実行すると、次のようにHibernateします。
Hibernate: update Student set studentName=? where studentId=?
Hibernate: update Phone set phoneNumber=?, phoneType=? where phoneId=?
Hibernate: delete from STUDENT_PHONE where STUDENT_ID=?
Hibernate: insert into STUDENT_PHONE (STUDENT_ID, PHONE_ID) values (?, ?)
ご覧のとおり、結合テーブルのエントリを削除するだけで、電話テーブルの電話エントリ自体は削除されません。したがって、テーブルは次のようになります。
学生
studentid | studentname
-----------+-------------
2 | foo
(1 rows)
student_phone
student_id | phone_id
------------+---------
2 | 3
(1 rows)
電話
phoneid | phonenumber | phonetyp
---------+-------------+---------
4 | 9889343423 | mobile
3 | 32354353 | house
(2 rows)
質問:それは通常の動作ですか?カスケード削除と孤立削除がtrueに設定されている場合でも?Hibernateが電話テーブルの電話番号も削除するようにするにはどうすればよいですか?
更新私はPostgreSQLを使用しています