tags:

views:

57

answers:

1

I want to persist the following class, including 'bar'

Class Foo
{
  Map<String, List<String>> bar;
  // ...
  // other stuff.....
}

How do I do this in Hibernate? If possible, how to do this in Hibernate with annotations?

Oh, the nature of the Map key String is that there are a small number of them (5-40), and they are the same across Foo instances. The Strings in the List are unique both within the List and between Foo instances.

Thanks.

A: 

Neither String nor List is a Entity, you should create an wrapper class which encapsulates your List

Do not forget setter's

@Entity
public class Foo {

    private MutableInt id = new MutableInt();

    private Map<String, CustomList> customListMap = new HashSet<String, CustomList>();

    @Id
    @GeneratedValue
    public Integer getId() {
        return this.id.intValue();
    }

    public void setId(Integer id) {
        return this.id.setValue(id);
    }

    @OneToMany
    @MapKey(name="key")
    public Map<String, CustomList> getCustomListMap() {
        return customListMap;
    }

    // add convenience method
    public void addBar(String key, String bar) {
        if(customListMap.get(key) == null)
            customListMap.put(key, new CustomList(new CustomListId(id, key)));

        customListMap.get(key).getBar().add(bar);
    }

}

And your custom CustomList (Do not forget setter's)

@Entity
public class CustomList {

    private CustomListId customListId;

    private List<String> bar;

    private String key;

    @EmbeddedId
    public CustomListId getCustomListId() {
        return customListId;
    }

    @Column(insertable=false, updatable=false)
    public String getKey() {
        return this.key;
    }

    @CollectionOfElements
    @JoinTable(name="BAR")
    public List<String> getBar() {
        return this.bar;
    }

    @Embeddable
    public static class CustomListId implements Serializable {

        private MutableInt fooId = new MutableInt();
        private String key;

        // required no-arg construtor
        public CustomList() {}
        public CustomList(MutableInt fooId, String key) {
            this.fooId = fooId;
            this.key   = key;
        }

        public Integer getFooId() {
            return fooId.intValue();
        }

        public void setFooId(Integer fooId) {
            this.fooId.setValue(fooId);
        }

        // getter's and setter's

        public boolean equals(Object o)  {
            if(!(o instanceof CustomListId))
                return false;

            CustomListId other = (CustomList) o;
            return new EqualsBuilder()
                       .append(getFooId(), other.getFooId())
                       .append(getKey(), other.getKey())
                       .isEquals();
        }

        // implements hashCode

    }

} 

You can even create a custom method called getBar which encapsulates your customListMap transparently as follows

@Entity
public class Foo {

    ...

    public Map<String, List<String>> getBar() {
        Map<String, List<String>> bar = new HashMap<String, List<String>>();

        for(Entry<String, CustomList> e: customListMap())
            bar.put(e.getKey(), e.getValue().getBar());

        return bar;
    }

}
Arthur Ronald F D Garcia
The CustomList class is inside the CustomList class, giving me a compilation error:
ggg
CustomList.java:33: CustomList is already defined in unnamed package public static class CustomList implements Serializable {
ggg