Akshay
Akshay

Reputation: 2497

storing key value pairs in hibernate | can we use map?

I have a xml file and within which i have some key value pairs.I want to store them in form of key value pairs

<parent>
  <key1> value </1key>
  <key1> value </1key>
  <key1> value </1key>
  <key1> value </1key>
   ...
  <key1> value </1key>
</parent>

Now i dont know how many key value will be coming from xml in advance.How can i map it to hibernate object? i can stor it in table in

primaryKey parentId    key   value
   1          1         k1     val
   2          1         k2     val
   3          1         k3     val
   4          2         k1     val
   5          2         k2     val
   6          3         k3     val

How can i map it to hibernate object? I want following structure class Parent{ int parentId; String parent Name KeyValue keyval ; //How do i model it?

}

AM using netbeans IDE.

Upvotes: 8

Views: 10990

Answers (3)

charybr
charybr

Reputation: 1948

If KeyValuePair is strictly privately owned by Parent, then better approach would be:

@Entity
public class Parent {
    @Id
    @GeneratedValue
    private long id;

    @ElementCollection(fetch=FetchType.EAGER)
    @MapKeyColumn(name="key")
    @CollectionTable(name="keyvaluepair", joinColumns= @JoinColumn(name="id"))
    private Map<String, KeyValuePair> keyValuePairMap = 
            new HashMap<String, KeyValuePair>();

    //getter and setter methods 

}

@Embeddable
public class KeyValuePair {

    //no need of declaring key
    //key column will be created by MapKeyColumn

    private String value;

    //getter and setter methods
}

In this approach, KeyValuePair is always persisted, merged, removed with their parent.

Refer:

Upvotes: 5

user2047184
user2047184

Reputation: 51

You can also map directly to a table without creating a KeyValuePair class

For a map property with the key-value pairs stored in MY_MAP_TABLE and defined as a property named 'settings':

Define the property:

@ElementCollection (fetch=FetchType.EAGER)
@CollectionTable(name="MY_MAP_TABLE" , joinColumns=@JoinColumn(name="ID"))
@MapKeyColumn(name="name")
@Column(name="value")
public Map<String, String> getSettings() {
   return settings;
}

And the table to store the map:

    CREATE TABLE MY_MAP_TABLE (
    ID          NUMBER not null REFERENCES  MY_PARENT_TABLE(ID),
    NAME        VARCHAR2(256) not null,
    VALUE       VARCHAR2(256) not null,
    PRIMARY KEY (ID , NAME)
    );

Upvotes: 5

JB Nizet
JB Nizet

Reputation: 691715

You may indeed use a map:

public class Parent {
    @Id
    private Integer id;

    @OneToMany(mappedBy = "parent")
    @MapKey(name = "key")
    private Map<String, KeyValuePair> keyValuePairs;
}

public class KeyValuePair {
    @Id
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "parent_id")
    private Parent parent;

    @Column(name = "key")
    private String key;

    @Column(name = "value")
    private String value;
}

You should also have a unique constraint on [parent_id - key].

Upvotes: 7

Related Questions