Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 137581

Summary: Generate Add/Remove methods for Collections
Product: [WebTools] Dali JPA Tools Reporter: Shaun Smith <shaun.smith>
Component: JPAAssignee: Neil Hauge <neil.hauge>
Status: CLOSED DUPLICATE QA Contact:
Severity: enhancement    
Priority: P3 CC: gunnar
Version: 0.5Keywords: helpwanted
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Shaun Smith CLA 2006-04-19 15:25:11 EDT
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;
    }
Comment 1 Brian Vosburgh CLA 2006-04-19 15:36:42 EDT
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)?
Comment 2 Shaun Smith CLA 2006-04-19 15:46:26 EDT
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.
Comment 3 Brian Vosburgh CLA 2006-04-19 16:08:08 EDT
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.
Comment 4 Gunnar Wagenknecht CLA 2006-06-11 18:55:48 EDT
(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.
Comment 5 Neil Hauge CLA 2011-07-01 16:25:56 EDT
Moving JPA specific bugs to new JPA component in bugzilla.
Comment 6 Neil Hauge CLA 2012-12-07 14:38:37 EST
Migrating this bug to a new bug with a patch on it.

*** This bug has been marked as a duplicate of bug 388568 ***