Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] [MOXy] setting bi-directional references during unmarshalling

Hi Polly,

The current support in EclipseLink 1.2 wouldn't handle the case of a many-to-many backpointer. EclipseLink 1.2 only handles backpointers on composite mappings, and since composite mappings are privately-owned, the many to many case isn't handled here. The updated support going into EclipseLink 2.0 includes support for Reference mappings which allows for the many-to-many case. This support will be available in the nightly EclipseLink 2.0 builds this week if you'd like to try it out. I'll let you know once the code is available.

Using method access on your mapping to set the backpointer yourself as you described would be a good workaround. I did a quick test and found that private and protected getters/setters will work for method access if you don't want to make the methods public.

polly.c.chang wrote:
Hi Matt,

Thank you for the quick and informative response!  :)  I am currently using
EL 1.1.2.  It sounds like there's a good reason to upgrade to 1.2.  I do
have a few more questions though:

1.  The example that you described below would work well for 1:many
bi-directional relationships.  But what about many:many bi-directional
relationships?  For example, if class "A" has a collection of B's, and "B"
has a collection of A's, the code to set the back-reference then looks like:

	public void addB(B b) {
			this.getBs().add(b);
			b.getAs().add(this);
		}
	}

EL 1.2 can take care of this too?

2.  Would the workaround that I have described work?  Does EclipseLink need
public getters and setters if I turn on "method access"?  Or would
private/protected methods be ok?

Thanks!
--Polly



Matt MacIvor wrote:
  
Hey Polly, 

We're currently working on better support for handling bi-directional
relationship mappings in EclipseLink. Currently in EclipseLink 1.2
(which is available today) for containment relationships, you can
configure the mapping to automatically set the back-reference when it's
populating the collection. This functionality isn't currently exposed
in the MappingWorkbench but is available through the mapping APIs,
Project XML and in JAXB through a custom annotation. 

Using the mapping APIs you would do something like: 
XMLCompositeCollectionMapping childMapping = new
XMLCompositeCollectionMapping(); 
childMapping.setXPath("children/child"); 
childMapping.setReferenceClass(Child.class); 
//Specify the name of the attribute on the reference class that points
back to the container object 
childMapping.setContainerAttributeName("parent"); 
childMapping.setContainerGetMethodName("getParent"); 
childMapping.setContainerSetMethodName("setParent"); 
parentDescriptor.addMapping(childMapping); 

If you're using Project XML,  this can also be specified in the xml
version of the project using the <container-attribute> element on
the composite mapping. 

In EclipseLink 1.2 this support is only availabe for Containment based
mappings (XMLCompositeObjectMapping and XMLCompositeCollectionMapping),
but EclipseLink 2.0 will have expanded support for bi-directional
relationships to also include reference mappings. 

Hope this helps, 

-Matt 

polly.c.chang wrote:

  Hi,

I have a bi-directional relationship between Parent and Child classes like
this:

public class Parent {
    private List<Child> children;

    public List<Child> getChildren()
    public void setChildren(List<Child> children)
    public void addChild(final Child child) {
        this.getChildren().add(child);
	child.setParent(this);
    }
    public void removeChild(final Child child) {
        this.getChildren().remove(child);
	child.setParent(null);
    }
}

public class Child {
    private Parent parent;

    public void setParent(Parent parent)
    public Parent getParent()
}

When I unmarshal the Parent object, I find that the "children" collection
contains Child objects that do not have the back-reference to the Parent. 
This is probably because the Child objects were unmarshalled and set
directly into the "children" collection.  How do I change the behavior so
that EclipseLink MOXy calls the addChild() method for each Child object? 
I
looked around EclipseLink Workbench and the schema, but I can't find any
mappings that look suitable.  Does MOXy support adding objects into a
collection by calling an add() method?  

If MOXy does not support calling an add() method for unmarshalling
collections, then the only workaround that I can think of is to turn on
"method accessing" for each bi-directional collection so that MOXy uses
the
getter and setter methods for the list.  Then the setter needs to go
through
the collection and fix up the back references to the Parent.  Usually my
setter is private/protected, so I assume that I'd have to make it public
too
for EclipseLink to use it. 

What do you recommend?

Thanks!
--Polly
  




_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users


    
  

Back to the top