次の3つのクラスがあります。
import java.sql.Timestamp;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.hibernate.annotations.Type;
@Entity
public class EventTO {
...
private List<EventAssignedResourceTO> eventAssignedResourceTOList;
/**
* @return the eventAssignedResourceTOList
*/
@OneToMany(fetch = FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name = "EAR_EVN_ID")
public List<EventAssignedResourceTO> getEventAssignedResourceTOList() {
return eventAssignedResourceTOList;
}
/**
* @param eventAssignedResourceTOList
* the eventAssignedResourceTOList to set
*/
public void setEventAssignedResourceTOList(List<EventAssignedResourceTO> eventAssignedResourceTOList) {
this.eventAssignedResourceTOList = eventAssignedResourceTOList;
}
public void setPrivate(boolean aPrivate) {
setPrivateEvent(aPrivate);
}
}
2 番目のクラス:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
@Entity
public class EventAssignedResourceTO {
private EventTO eventTO;
private EventResourceTO eventResourceTO;
private int resourceCount;
/**
* @return the eventTO
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "EAR_EVN_ID", updatable = false, insertable=false, nullable = false)
public EventTO getEventTO() {
return eventTO;
}
/**
* @param eventTO
* the eventTO to set
*/
public void setEventTO(EventTO eventTO) {
this.eventTO = eventTO;
}
/**
* @return the eventResourceId
*/
@Transient
public Long getEventResourceId() {
return eventResourceId;
}
/**
* @param eventResourceId
* the eventResourceId to set
*/
public void setEventResourceId(Long eventResourceId) {
this.eventResourceId = eventResourceId;
}
/**
* @return the resourceCount
*/
@Column(name = "EAR_COUNT")
public int getResourceCount() {
return resourceCount;
}
/**
* @param resourceCount
* the resourceCount to set
*/
public void setResourceCount(int resourceCount) {
this.resourceCount = resourceCount;
}
/**
* @return the eventResourceTO
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "EAR_ERS_ID")
public EventResourceTO getEventResourceTO() {
return eventResourceTO;
}
/**
* @param eventResourceTO
* the eventResourceTO to set
*/
public void setEventResourceTO(EventResourceTO eventResourceTO) {
this.eventResourceTO = eventResourceTO;
}
}
3 番目のクラス:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.Type;
@Entity
public class EventResourceTO {
private String name;
private int count;
private boolean active;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
@Column(name = "ERS_ID")
public Long getId() {
return super.getId();
}
/**
* @return the name
*/
@Column(name="ERS_NAME")
public String getName() {
return name;
}
/**
* @param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the count
*/
@Column(name="ERS_COUNT")
public int getCount() {
return count;
}
/**
* @param count
* the count to set
*/
public void setCount(int count) {
this.count = count;
}
/**
* @return the active
*/
@Type(type="yes_no")
@Column(name="ERS_IS_ACTIVE")
public boolean isActive() {
return active;
}
/**
* @param active
* the active to set
*/
public void setActive(boolean active) {
this.active = active;
}
}
ここで公式の休止状態のドキュメントに従っています: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#collections-bidirectional
この例はこちら: http://viralpatel.net/blogs/hibernate-one-to-many-annotation-tutorial/
問題は、DB に EventTO を挿入しているときに、eventId で制約違反が発生することです。これは、hibernate が EventAssignedResourceTO の eventTO に新しく作成されたイベントの ID を設定できず、ID が null であるためです。
そこで、EventAssignedResourceTO の JoinColumn アノテーションにある更新可能で挿入可能なタグを削除することにしました。
挿入は適切に機能しますが、イベントを削除したい場合、hibernate は最初に AssignedResourceTO を削除してからイベントを削除し、最後にテーブル内の AssignedResourceTO のレコードを更新しようとする理由がわかりません。ここで、eventTO の ID を NULL に設定しようとすると、制約違反が発生します。更新の場合も同様です。
公式ドキュメントに書かれていることが機能せず、ウェブ上で解決策を見つけることができなかったため、本当に混乱しています。
何か案が??
乾杯