简体   繁体   English

Hibernate在外键字段中插入空值

[英]Hibernate is inserting null values in foreign key field

I have 2 simple domain objects as follows..with MYSQL DB. 我有2个简单的域对象,如下所示。

@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>();

and second object 和第二个对象

@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;

and my main method. 和我的主要方法。

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());
        }

    }

}

For some reason hibernate is inserting null values in foreign key field of productoptions. 出于某种原因,hibernate在productoptions的外键字段中插入了空值。 I tried changing cascading styles, generation strategies, but nothing worked. 我尝试更改级联样式,生成策略,但没有任何效果。 Making nullable=false throws error . 使nullable = false引发error。 Data gets inserted but in the productoptions table foriegn key field is null. 插入了数据,但在productoptions表中,foreign键字段为null。 Please help 请帮忙

In Product change Product变更中

@OneToMany(mappedBy="product")
List<ProductOption> productoption;

In ProductOption change ProductOption更改

@ManyToOne
@JoinColumn(name="productId")
private Product product;

And finally in Createschema 最后在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();

I do agree with @Sindarth Ramesh. 我确实同意@Sindarth Ramesh。 The idea of giving CascadeType.All is that the insert, delete, etc concerning relational operations can be handled by Hibernate itself. 给出CascadeType.All的想法是,与关系操作有关的插入,删除等可以由Hibernate本身处理。

You didn't setProduct(product) in ProductOption Object. 您没有在ProductOption对象中设置Product(product)。

You don't need to create new List Object in your main method 您不需要在主要方法中创建新的列表对象

    List<ProductOption> productoptions = new ArrayList<ProductOption>();

    productoptions.add(po1);
    productoptions.add(po2);
    productoptions.add(po);

You have already created a List Object in 您已经在中创建了一个列表对象

@OneToMany(cascade = javax.persistence.CascadeType.ALL,mappedBy="product")
protected List<ProductOption> productoption = new ArrayList<ProductOption>();

No need to use like this, 不需要这样使用

product.setProductoption(productoptions);

You have created another ArrayList in main method which is using memory allocation unnecessarily. 您已经在main方法中创建了另一个ArrayList,该数组不必要地使用了内存分配。 Of course, if you didn't created new object in Product(Entity), it needs to do like above. 当然,如果您没有在Product(Entity)中创建新对象,则需要执行上述操作。 But now, you can save like this, 但是现在,您可以像这样保存

//getProductionoption() is getter List type getter method in your Product Entity
product.getProductionoption().add(po1);
product.getProductionoption().add(po2);
product.getProductionoption().add(po);

Here's your code I tried to fixed in main method; 这是您尝试在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());

No need to save two objects like the above answer. 无需保存两个对象,如上述答案。 It's working BUT saving two objects is working in @OneToMany. 它正在工作,但是保存两个对象正在@OneToMany中工作。 But will it work in @ManyToMany? 但是它可以在@ManyToMany中工作吗? I don't think so. 我不这么认为。 Think about it. 想一想。 We don't want to create the association table. 我们不想创建关联表。 We're not gonna create another Entity named Product_ProductOptions or ProductOptions_Product. 我们不会创建另一个名为Product_ProductOptions或ProductOptions_Product的实体。 Let Hibernate do the rest. 让Hibernate完成其余的工作。 That's why we use Hibernate, isn't it? 这就是为什么我们使用Hibernate,不是吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM