I have a very common business requirement related to “code table”
Business requirement
- A static list of Departments, i.e. created once and any changes are done by a completely different business process
- A dynamic list of Employees
- Employee must be assigned to a single department
- The department assignment for an Employee can change over time
- NOTHING done to an Employee can change the values inside the department, only the assignment of an Employee to a Department
Modeling this in Spring JPA as a Unidirectional ManyToOne
@Entity
public class Employee {
@Id
private Long id;
@Version
private Integer version;
@Column
private String name;
@ManyToOne(optional = false) // cascade by default is {}, i.e. NONE
@JoinColumn(name = "dept_id", nullable = false)
Department department;
// standard getters, setters and proper equals/hascode
}
@Entity
public class Department {
@Id
private Long id;
@Version
private Integer version;
@Column
private String name;
// standard getters, setters and proper equals/hascode
}
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
public class Test() {
@Autowired
EmployeeRepository empRepo;
@Transactional
@Test
void givenValidDatabase_whenUpdateUsingRepository_thenCorrectResults() {
Employee emp4 = empRepo.findById(4L).orElseThrow();
// simulates what might happen in a UI via a DTO
// Entity -> DTO -> DTO modified incorrectly in UI (e.g. letting a user type in a department manually) -> Entity
emp4.getDepartment().setDescription("asdf");
Employee saved = empRepo.saveAndFlush(emp4);
assertThat(saved.getSailingExperience().getDescription()).isNotEqualTo("asdf");
}
}
The test results in an update statement
Hibernate: update department set name=?, version=? where id=? and version=?
Granted that the UI is at fault but is there any way to have JPA configured to NEVER allow an update statement to the Department table when accessed through an Employee?