0

I have an unidirectional OneToMany JPA entity mapping in my (Spring Framework + Spring Data + Hibernate JPA) project. Entity classes are like in the following code.(I have removed irrelevant class members for brevity).

@Entity
@Table(name = "employees")
class Employee{
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "id")
   private Integer id;

   @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
   @JoinColumn(name = "employee_id")
   private List<DepartmentAssignment> departmentAssignments = new ArrayList<>();
}

@Entity
@Table(name = "department_assignments")
class DepartmentAssignment{
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "id")
   private Integer id;

   @NotNull
   @Column(name = "employee_id")
   private Integer employeeId;

   @NotNull
   @Column(name = "department_id")
   private Integer departmentId;
}

@Entity
@Table(name = "departments")
class Department{
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "id")
   private Integer id;       
}

And, in one of my service classes have a method to remove a DepartmentAssignment from an Employee like below.

public Employee deleteDepartmentAssignment(Integer empId, Integer deptAssignmentId) {
        Employee employee = employeeRepository.findOne(empId);
        if(employee != null) {
            for ( DepartmentAssignment da : employee.getDepartmentAssignments()) {
                if(da.getId().equals(deptAssignmentId)) {
                    employee.getDepartmentAssignments().remove(da);
                    employee = employeeRepository.save(employee);
                    break;
                }
            }
        }

        return employee;
    }

However, calling above methods gives me an error: org.hibernate.exception.ConstraintViolationException ,and in the SQL log, I can see Column 'employee_id' cannot be null error for the last SQL statement of the transaction.

Can anybody tell me what I'm doing wrong here and how to get it fixed?

Johna
  • 1,836
  • 2
  • 18
  • 29

4 Answers4

1

You don't need to add

@NotNull
@Column(name = "employee_id")
private Integer employeeId;

to the Employee, if you use @JoinColumn(name = "employee_id"). Try to remove it.

v.ladynev
  • 19,275
  • 8
  • 46
  • 67
  • Trying your suggestion gives me the following error and it fails to load the spring context too. ` org.hibernate.DuplicateMappingException: Table [departments_assignments] contains physical column name [employee_id] represented by different logical column names: [employeeId], [employee_id] ` – Johna Mar 04 '16 at 09:22
  • @Tharanga You should remove all `employeeId` and `employee_id` from `DepartmentAssignment` and update a schema. – v.ladynev Mar 04 '16 at 09:27
  • I want to thank you. Removing employeeId altogether worked like a charm. – Johna Mar 04 '16 at 13:35
  • 1
    @Tharanga You are welcome. Thanks for up vote. `private Integer departmentId;` looks strange too. Please, never use such associations. You should to use associations to objects (using lazy, for an example). – v.ladynev Mar 04 '16 at 13:38
1

You can try the following, not sure why you use the plain id in the object. Thats not object relational mapping. For more details see Hibernate triggering constraint violations using orphanRemoval

@Entity
@Table(name = "employees")
class Employee{
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Integer id;

   @OneToMany(cascade = CascadeType.ALL, mappedBy = "employee", orphanRemoval = true)
   private List<DepartmentAssignment> departmentAssignments = new ArrayList<>();
}

@Entity
@Table(name = "department_assignments")
class DepartmentAssignment{
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Integer id;

   @ManyToOne(optional=false)
   private Employee employee;

   @ManyToOne(optional=false)
   private Department department;
}

@Entity
@Table(name = "departments")
class Department{
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Integer id;       
}
Community
  • 1
  • 1
mh-dev
  • 5,264
  • 4
  • 25
  • 23
  • Thank you for coming to help me. The reason I didn't make it bidirectional is that, according to my business model, it is not intended to access Employee from DepartmentAssignment. Your suggestion to make it bidirectional should work. I removed employeeId altogether from DepartmentAssignment entity, and it works as intended now. – Johna Mar 04 '16 at 13:46
0

You must look .hbm.xml file and you should mapping your Entity in this file and you can look this example

http://www.mkyong.com/hibernate/hibernate-one-to-many-relationship-example/

I hope it will be useful for you.

java.nazif
  • 713
  • 1
  • 9
  • 18
-1

try removing

cascade = CascadeType.ALL

but im not 100% sure..

Keaz
  • 955
  • 1
  • 11
  • 21