javahibernaterelationshipcascadejpa-annotations

Unable to get usage of CascadeTypes


I have two domain classes. Below is the rough sketch of the classes.

Company.java

public class Company{

    @OneToMany(orphanRemoval="true",cascade=CascadeType.ALL,
    mappedBy="company")
    private List<Department> departments;

}

Department.java

public class Department{

   @ManyToOne(fetch=FetchType.LAZY,cascade=CascadeType.PERSIST)
   @JoinColumn(name="company_id")
   private Company company

}

JPA @ManyToOne with CascadeType.ALL says that The meaning of CascadeType.ALL is that the persistence will propagate (cascade) all EntityManager operations (PERSIST, REMOVE, REFRESH, MERGE, DETACH) to the relating entities.

Test.java's main method

//session started and transaction begin
Company company=new Company();
company.setName("Company");

Department department=new Department();
department.setName("Testing department");

department.setCompany(company);

session.save(department);

//transaction committed and session closed

It gives my Exception

Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value: someValue

But when I use CascadeType.ALL on @ManyToOne annotation,it works fine, but not with CascadeType.PERSIST So what should I use to make this example work without using CascadeType.ALL as ALL uses (PERSIST, REMOVE, REFRESH, MERGE, DETACH). So which of following I should uses to get my work done instead of ALL and how they work?


Solution

  • You have set the CascadeType to PERSIST in Department entity so you have to use session.persist(Object) method instead of save.

    So use this:

    session.persist(department);
    

    Update:

    The Company entity has CascadeType set to ALL on Department. Also in a one-to-many relationship the Many side which is Department is the owner of the association.

    So if you save the Company instead of Department the CascadeType.ALL is applicable. As Company is not the owner of the association, you have to add the department to your Company to maintain the bi-directional relationship. The code looks like this.

        List<Department> departments = new ArrayList<Department>();
        departments.add(department);
        company.setDepartments(departments);
    
        session.persist(company); // or you can also use save here.
    

    If you do not maintain the relationship then Department will not be saved in database.