私は Hibernate にまったく慣れていないので、Hibernate が何をするのか、何をする必要があるのかを判断しようとしています。
大きな問題の 1 つは、データベースにまだ存在しない依存関係を持つオブジェクトを処理することです。たとえば、Manufacturer オブジェクトを値として受け入れる Manufacturer フィールドを含む Project オブジェクトがあります。データベースには、製造元テーブルへの参照である mfr_id 列を持つ製品テーブルがあります (かなり典型的な一方向の 1 対多の関係)。
製品オブジェクトに割り当てられたメーカーが、データベースに既に存在するメーカーに関連している場合、問題はありません。ただし、まだ永続化されていない製造元を参照するオブジェクトを保存または更新しようとすると、例外が発生して操作が失敗します。
スレッド「アプリケーション」org.hibernate.TransientObjectException での例外: オブジェクトが保存されていない一時インスタンスを参照しています - フラッシュする前に一時インスタンスを保存します
もちろん、IDフィールドがnullかどうかを確認し、nullの場合は保存することで、製品の製造元の状態を手動で確認できますが、これは面倒な解決策のようです. 問題の依存関係がまだ永続化されていない場合、Hibernate は依存関係の自動永続化をサポートしますか? もしそうなら、どうすればその動作を有効にできますか? 私は、Netbeans (3.5 だと思います) にバンドルされている Hibernate のバージョンと、マッピング動作を指定するためのインライン注釈を使用しています。以下は、依存関係を処理する部分に切り詰められた、私の製品とメーカーのクラスです。(Product は、継承戦略として JOINED を使用して、販売可能なテーブルにマップされる Sellable を拡張します。製品を識別する主キーを含むのはそのテーブルです)
@Entity
@Table (
name="products",
schema="sellable"
)
public abstract class Product extends Sellable {
private Manufacturer manufacturer;
@ManyToOne (fetch = FetchType.EAGER)
@JoinColumn (name = "mfr_id")
public Manufacturer getManufacturer () {
return this.manufacturer;
}
/**
*
* @param manufacturer
*/
public Product setManufacturer (Manufacturer manufacturer) {
this.manufacturer = manufacturer;
return this;
}
}
依存するメーカー
@Entity
@Table (
name="manufacturers",
schema="sellable",
uniqueConstraints = @UniqueConstraint(columnNames="mfr_name")
)
public class Manufacturer implements Serializable {
private Integer mfrId = null;
private String mfrName = null;
@Id
@SequenceGenerator (name = "manufacturers_mfr_id_seq", sequenceName = "sellable.manufacturers_mfr_id_seq", allocationSize = 1)
@GeneratedValue (strategy = GenerationType.SEQUENCE, generator = "manufacturers_mfr_id_seq")
@Column (name="mfr_id", unique=true, nullable=false)
public Integer getMfrId () {
return mfrId;
}
private Manufacturer setMfrId (Integer mfrId) {
this.mfrId = mfrId;
return this;
}
@Column(name="mfr_name", unique=true, nullable=false, length=127)
public String getMfrName () {
return mfrName;
}
public Manufacturer setMfrName (String mfrName) {
this.mfrName = mfrName;
return this;
}
}
更新:この質問から次のことを試しましたが、まだ一時的なオブジェクトの例外が発生します。
@ManyToOne (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
Netbeans にバンドルされている Hibernate のバージョンも確認しました。3.2.5 です。
更新 2: 以下は、私が望むように機能しているように見えることがわかりました。
@ManyToOne (fetch = FetchType.EAGER, cascade = CascadeType.ALL)
ただし、これは私が本当に望んでいるカスケード型ではないと思います。製品を削除する場合、関連する製造元を削除することは正しいアクションではないと思います。これは、現在行われていることだと思います。
利用可能なすべての型で構成されるカスケード型を作成しようとしましたが、それも機能しませんでした。保存されていない製造元が関連付けられている製品を保存しようとしたときに、同じ例外が発生しました。
@ManyToOne (fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
CascadeType.SAVE_UPDATE がいくつかの場所で言及されているのを見てきましたが、そのモードは、Netbeans に付属する Hibernate のバージョンでは使用できないようです。