我有两个简单的域对象,如下所示......使用MYSQL DB。
@Entity
@Table(name="Product")
public class Product {
@Id
@Column(name="productId")
@GeneratedValue
protected int productId;
@Column(name="Product_Name")
protected String name;
@OneToMany(cascade = javax.persistence.CascadeType.ALL,mappedBy="product")
protected List<ProductOption> productoption = new ArrayList<ProductOption>();
和第二个对象
@Entity
@Table(name="ProductOption")
public class ProductOption{
/**
*
*/
@Id
@Column(name="product_option_id")
@GeneratedValue
protected int productOptionId;
//@JoinColumn(name="productId")
@ManyToOne()
protected Product product;
@Column(name="ProductTopping")
private String topping;
和我的主要方法。
public class Createschema {
public static void main(String[] args) {
Product product = new Product();
product.setName("Coffee");
ProductOption po2 = new ProductOption();
po2.setTopping("barbeque");
ProductOption po = new ProductOption();
po.setTopping("whipcream");
ProductOption po1 = new ProductOption();
po1.setTopping("honeymustard");
List<ProductOption> productoptions = new ArrayList<ProductOption>();
productoptions.add(po1);
productoptions.add(po2);
productoptions.add(po);
System.out.println("schema!");
Configuration configuration = new Configuration().configure();
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
SessionFactory factory = configuration.buildSessionFactory(builder.build());
Session session = factory.openSession();
session.beginTransaction();
product.setProductoption(productoptions);
session.save(product);
session.getTransaction().commit();
session.close();
System.out.println(product.getName());
for(int i=0;i<product.getProductoption().size();i++){
System.out.println(product.getProductOptionsAsListOfStrings().get(i));
System.out.println(product.getProductoption().get(i).getTopping());
}
}
}
由于某种原因,hibernate在productoptions的外键字段中插入空值。 我尝试改变级联风格,生成策略,但没有任何效果。使nullable = false抛出错误。数据被插入但在productoptions表中,foriegn key字段为null。 请帮忙
答案 0 :(得分:3)
在Product
更改
@OneToMany(mappedBy="product")
List<ProductOption> productoption;
在ProductOption
更改
@ManyToOne
@JoinColumn(name="productId")
private Product product;
最后在Createschema
session.beginTransaction();
Product product = new Product();
product.setName("Coffee");
session.save(product);
ProductOption po2 = new ProductOption();
po2.setTopping("barbeque");
po2.setProduct(product)
ProductOption po = new ProductOption();
po.setTopping("whipcream");
po2.setProduct(product)
ProductOption po1 = new ProductOption();
po1.setTopping("honeymustard");
po2.setProduct(product)
session.save(po2);
session.save(po);
session.save(po1);
session.getTransaction().commit();
session.close();
答案 1 :(得分:1)
我同意@Sindarth Ramesh的观点。提供CascadeType.All的想法是,与关系操作有关的插入,删除等可以由Hibernate本身处理。
您没有在ProductOption对象中设置Product(product)。
您不需要在主要方法中创建新的列表对象
List<ProductOption> productoptions = new ArrayList<ProductOption>();
productoptions.add(po1);
productoptions.add(po2);
productoptions.add(po);
您已经在其中创建了一个列表对象
@OneToMany(cascade = javax.persistence.CascadeType.ALL,mappedBy="product")
protected List<ProductOption> productoption = new ArrayList<ProductOption>();
不需要这样使用
product.setProductoption(productoptions);
您已经在main方法中创建了另一个ArrayList,它不必要地使用了内存分配。当然,如果您没有在Product(Entity)中创建新对象,则需要执行上述操作。但是现在,您可以像这样保存,
//getProductionoption() is getter List type getter method in your Product Entity
product.getProductionoption().add(po1);
product.getProductionoption().add(po2);
product.getProductionoption().add(po);
这是您尝试在main方法中修复的代码;
Product product = new Product(); //This must be created on top so that product(id) can be added in ProductOption(Object).
//Product Options
ProductOption po2 = new ProductOption();
po2.setTopping("barbeque");
po2.setProduct(product); //This will set your foreign key id
ProductOption po = new ProductOption();
po.setTopping("whipcream");
po.setProduct(product); //This will set your foreign key id
ProductOption po1 = new ProductOption();
po1.setTopping("honeymustard");
po1.setProduct(product); //This will set your foreign key id
//product
product.setName("Coffee");
//getProductionoption() is getter List type getter method in your Product Entity
product.getProductoption().add(po1);
product.getProductoption().add(po2);
product.getProductoption().add(po);
/*
Or you can create list and use like this.
But like I said, it is unnecessary.
product.setProductoption(productoptions);
*/
Configuration configuration = new Configuration().configure();
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
SessionFactory factory = configuration.buildSessionFactory(builder.build());
Session session = factory.openSession();
session.beginTransaction();
//product.setProductoption(productoptions);
session.save(product); //Hibernate will automatically join the relationship here.
session.getTransaction().commit();
session.close();
System.out.println(product.getName());
for(int i=0;i<product.getProductoption().size();i++){
System.out.println(product.getProductOptionsAsListOfStrings().get(i));
System.out.println(product.getProductoption().get(i).getTopping());
无需像上面的答案一样保存两个对象。它正在工作,但是保存两个对象正在@OneToMany中工作。但是它可以在@ManyToMany中工作吗?我不这么认为。想一想。我们不想创建关联表。我们不会创建另一个名为Product_ProductOptions或ProductOptions_Product的实体。让Hibernate完成其余的工作。这就是为什么我们使用Hibernate,不是吗?