views:

31

answers:

2

Motivated by this question, I've tried to change the following:

 @ManyToMany(cascade={CascadeType.REMOVE, CascadeType.MERGE})
private Set<Expression> exps = new LinkedHashSet<Expression>();

to:

 @ManyToMany(cascade={CascadeType.REMOVE, CascadeType.MERGE})
    private LinkedHashSet<Expression> exps = new LinkedHashSet<Expression>();

However, such a move results in:

Exception [EclipseLink-1] (Eclipse Persistence Services - 2.1.0.v20100614-r7608): org.eclipse.persistence.exceptions.DescriptorException

Exception Description: The attribute [exps] is not declared as type ValueHolderInterface, but its mapping uses indirection. Mapping: org.eclipse.persistence.mappings.ManyToManyMapping[exps] Descriptor: RelationalDescriptor(com.mysimpatico.memoplatform.persistence.entities.Meaning --> [DatabaseTable(MEANING)])

How am I supposed in JPA2 to achieve the desired behavior?

+1  A: 

Only the standard interfaces types are allowed as attribute types in JPA. Why are you changing the type of the attribute? With the original definition the underlying collection is still your custom type.

Gordon Yorke
Because using Set type (and LinkedHashSet) results in an unordered set when retrieving from the database. The definition doesn't seem to apply, but perhaps to my methods defined in the class (but not to queries).
simpatico
@simpatico: At a guess, JPA uses the generic type to determine what kind of column it is in the database. For example, a Set would be a column with the UNIQUE attribute on it. I imagine it would assume the same for a `SortedSet`. The difference between the two would be how the application handles them (unsorted for Set, sorted for SortedSet).
R. Bemrose
If you want the order to be persisted then you will need to use the @OrderColumn annotation for index or @OrderBy annotation for sorting. Also if you have ordering you may want to implement List and use that as the attribute type. EclipseLink will still not load your Collection Type without the enhancement completed but the order will be persisted and retrieved allowing you to swap in your type when that attribute is accessed by the user.
Gordon Yorke
+1  A: 

I believe EclipseLink will allow you to use a concrete collection type if you set fetch to EAGER. When the relationship is LAZY EclipseLink requires to put its own lazy collection in place of the value. EclipseLink defines a lazy List, Set and Map, but no LinkedHashSet.

Note the JPA spec requires the usage of the Collection, Set, List or Map interface, no impls are allowed. If order is important, you should just use a List.

Technically it should be possible to maintain the collection implementation with LAZY collections, so please log a bug/enhancement for this.

James