简体   繁体   中英

Hibernate is inserting null values in foreign key field

I have 2 simple domain objects as follows..with 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>();

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. I tried changing cascading styles, generation strategies, but nothing worked. Making nullable=false throws error . Data gets inserted but in the productoptions table foriegn key field is null. Please help

In Product change

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

In ProductOption change

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

And finally in 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. The idea of giving CascadeType.All is that the insert, delete, etc concerning relational operations can be handled by Hibernate itself.

You didn't setProduct(product) in ProductOption Object.

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. Of course, if you didn't created new object in Product(Entity), it needs to do like above. 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;

    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. But will it work in @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. Let Hibernate do the rest. That's why we use Hibernate, isn't it?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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