| Summary: | Generate Add/Remove methods for Collections | ||
|---|---|---|---|
| Product: | [WebTools] Dali JPA Tools | Reporter: | Shaun Smith <shaun.smith> |
| Component: | JPA | Assignee: | Neil Hauge <neil.hauge> |
| Status: | CLOSED DUPLICATE | QA Contact: | |
| Severity: | enhancement | ||
| Priority: | P3 | CC: | gunnar |
| Version: | 0.5 | Keywords: | helpwanted |
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows XP | ||
| Whiteboard: | |||
Should the access techniques in the method match the AccessType specified (or implied) by the entity generator? That is, if AccessType is FIELD, should the add method look like this:
public Employee addEmployee(Employee employee) {
employeeList.add(employee);
employee.employee = this;
return employee;
}
What if the appropriate setters are not present (i.e. the entity generator is configured with AccessType of FIELD, but no getters and setters are to be generated)?
The generated Entity should be "self encapsulated". All field access should be through getters and setters. This is a reasonable default as it best supports subclass overrides. There is no option to not generate getters and setters--they always are generated. If we add an option then I would not generate the list management methods if getters and setters were not generated. There is also no option as to whether annotations should be placed on the fields or properties for that matter--that's another ER. The code is in place for those options (AccessType, getters/setters), we just haven't added in the UI support for configuring them; so it's more of a bug than an ER. :-) Of course that depends on one's interpretation of the requirements....
Also, do we maintain the bidi links on only one side of the relationship? For example, do we have a setter like this:
public void setEmployee(Employee employee) {
this.employee = employee;
employee.addEmployee(this);
}
If so, then we need to make "backdoor" setters and add/remove methods so we don't have infinite recursion.
Also, returning the added or removed employee from the add/remove method doesn't seem very helpful, since the client would already have the employee in hand when it called the method in the first place....
Note also that "self-encapsulation" is not *always* a Good Thing - all patterns and idioms have their trade-offs. Maybe we make this yet another user setting.
(In reply to comment #3) > Maybe we make this yet another user setting. That would satisfy more users. :) I think that it's possible to define a clear rule to avoid the loop case, i.e. always have the "parent" doing the whole magic but never the child. Or in technical terms: setters should not call add/remove but add/remove should call setters. So the following methods would call Employee#setEmployee: manager#addEmployee manager#removeEmployee employee#addToManager employee#removeFromManager Whereas Employee#setEmployee would never call any of the methods above. If you really want to be sure then you need to introduce internal (protected) setters but I think that is not necessary if the JavaDoc cleanly states what the method does and what implementors/overwriters should watch for. Moving JPA specific bugs to new JPA component in bugzilla. Migrating this bug to a new bug with a patch on it. *** This bug has been marked as a duplicate of bug 388568 *** |
Entity Generation: When generating a OneToMany relationship and the ManyToOne back between two Entities, also generate add and remove methods for the OneToMany list. E.g., class Employee { ... @ManyToOne @JoinColumn(name="MANAGER_ID", referencedColumnName="EMPLOYEE.EMP_ID") protected Employee employee; ... @OneToMany(mappedBy="employee") protected List<Employee> employeeList; ... public Employee addEmployee(Employee employee) { getEmployeeList().add(employee); employee.setEmployee(this); return employee; } public Employee removeEmployee(Employee employee) { getEmployeeList().remove(employee); employee.setEmployee(null); return employee; }