Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have problems in mapping custom collection with JPA (Hiberante provider). For example when I am using object with attribute

List<Match> matches;

with

<one-to-many name="matches">
    <cascade>
        <cascade-all />
    </cascade>
</one-to-many>

in my ORM file, it is allright; But if I replace "List matches;" by

private Matches matches;

,where "Matches" is defined like:

public class Matches extends ArrayList<Match> {

    private static final long serialVersionUID = 1L;
}

It produces following error:

Caused by: org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: by.sokol.labs.jpa.MatchBox.matches

Thanks for your attention!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
133 views
Welcome To Ask or Share your Answers For Others

1 Answer

You can, but you have to refer to it as one of the common collections - List or Set.

so:

private List matches = new Matches();

Why? Because Hibernate makes proxies to your collections to enable lazy loading, for example. So it creates PersistentList, PersistentSet and PersistentBag, which are List but aren't Matches. So, if you want to add additional methods to that collection - well, you can't.

Check this article for more details.

You have a solution, however. Don't use inheritance, use composition. You can, for example, add a method to your entity called getMatchesCollection() (in addition to the traditional getter), which looks like:

 public Matches getMatchesCollection() {
    return new Matches(matches);
 }

And your Matches class would look like (using google-collections' ForwardingList):

public class Matches extends ForwardingList {
    private List<Match> matches;
    public Matches(List<Match> matches) { this.matches = matches; }
    public List<Match> delegate() { return matches; }
    // define your additional methods
}

If you can't use google collections, simply define the ForwardingList yourself - it's calling all the methods of the underlying List

If you don't need any additional methods to operate on the structure, then don't define a custom collection.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...