Hibernate 4.1 を使用して MYSQL で製品を管理するための構造を作成したいと考えています。一般に、SimpleProduct (説明と価格のみを含む) と ComplexProduct (製品を含む追加のリストを含む) の 2 種類の製品があります。
そこで、抽象クラスの Product と派生クラスの SimpleProduct および ComplexProduct を作成しました。TABLE_PER_CLASS InheritanceType が便利だと思いました。
製品.java
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Product {
private long id;
private String description;
private BigDecimal price;
private Product parent;
protected Product() {
}
protected Product(String description, BigDecimal price) {
this.description = description;
this.price = price;
}
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name="ID")
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Column(name="DESCRIPTION")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Column(name="PRICE", precision=2, columnDefinition="DECIMAL(10,2)")
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
@Override
public String toString() {
return getDescription()+", "+getPrice()+"€";
}
}
SimpleProduct.java
@Entity
public class SimpleProduct extends Product {
public SimpleProduct() {
super();
}
public SimpleProduct(String description, BigDecimal price) {
super(description,price);
}
}
複合製品.java
@Entity
public class ComplexProduct extends Product {
private List<Product> containedProducts;
public ComplexProduct() {
}
public ComplexProduct(String description, BigDecimal price, List<Product> containedProducts) {
super(description,price);
if (containedProducts == null) {
this.containedProducts = new ArrayList<Product>();
} else {
this.containedProducts = containedProducts;
}
}
public ComplexProduct(String description, BigDecimal price) {
super(description,price);
this.containedProducts = new ArrayList<Product>();
}
@OneToMany(targetEntity=Product.class, cascade=CascadeType.ALL, fetch=FetchType.LAZY)
public List<Product> getContainedProducts() {
return containedProducts;
}
public void setContainedProducts(List<Product> containedProducts) {
this.containedProducts = containedProducts;
}
public void addToProductList(Product p) {
this.containedProducts.add(p);
}
}
次に、テスト構造を実行しようとしました:
SimpleProduct sp1 = new SimpleProduct("SimpleProduct1",new BigDecimal("2.99"));
SimpleProduct sp2 = new SimpleProduct("SimpleProduct2",new BigDecimal("4.99"));
SimpleProduct sp3 = new SimpleProduct("SimpleProduct3",new BigDecimal("3.99"));
ComplexProduct cp1 = new ComplexProduct("ComplexProduct1",new BigDecimal("8.99"));
cp1.addToProductList(sp2);
cp1.addToProductList(sp3);
HibernateUtil.persist(sp1);
HibernateUtil.persist(sp2);
HibernateUtil.persist(sp3);
HibernateUtil.persist(cp1);
HibernateUtil.shutdown();
そして、ここに持続メソッドがあります:
public static void persist(Object o) {
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
session.persist(o);
tx.commit();
}
このテスト構造の永続化方法はあまりきれいではありませんが、テストするだけです。
問題は、プログラムがHibernateUtil.persist(cp1)を実行しているときに例外が発生することです。
スレッド "メイン" org.hibernate.PersistentObjectException での例外: 切り離されたエンティティが永続化に渡されました: 製品
それで、それの何が問題なのですか?そして、どうすればこの問題を解決できますか?
ありがとうございました