Showing posts with label Map. Show all posts
Showing posts with label Map. Show all posts

Wednesday, 22 August 2012

JPA @ElementCollection for Embeddables

The @ElementCollection entity is a mean to create one-to-many relationships between entities and embeddables, using Collection, List, Set and Map. This annotation must also be used for basic types.

For example:
@AutoProperty
@Entity
public class ReferringItem implements Serializable {

    @Id
    private long id;

    // Element collection is required for basic types
    // and embeddables. Such elements are stored in
    // a separate table.
    @ElementCollection
    private Collection<AnEmbeddable> myCollection
        = new ArrayList<AnEmbeddable>();

    // By default, data is fetched lazily (when
    // used for the first time). Making it eager
    // loads the data as soon as possible.
    @ElementCollection(fetch=FetchType.EAGER)
    private Set<Long> mySet = new HashSet<Long>();

    // When not using generics, one must specify
    // the collection type (i.e., target class)
    @ElementCollection(targetClass=String.class)
    private List myList = new ArrayList();

    // Element collection is required when the map
    // value is a basic type or an embeddable
    @ElementCollection
    private Map<String,AnEmbeddable> map
        = new HashMap<String,AnEmbeddable>();

    // Setter & Getter, Constructor... 

}
The following:
@AutoProperty
JPA.INSTANCE.clear();

ReferringItem ri = new ReferringItem();

ArrayList<AnEmbeddable> coll
    = new ArrayList<AnEmbeddable>();
coll.add(new AnEmbeddable("Coll1"));
coll.add(new AnEmbeddable("Coll2"));
ri.setMyCollection(coll);

Set<Long> set = new HashSet<Long>();
set.add(Long.MIN_VALUE);
set.add(33l);
ri.setMySet(set);

List list = new ArrayList();
list.add("aaa");
list.add("bbb");
ri.setMyList(list);

Map<String,AnEmbeddable> map
    = new HashMap<String,AnEmbeddable>();
map.put("prt", new AnEmbeddable("Map1"));
map.put("frd", new AnEmbeddable("Map2"));
ri.setMap(map);

JPA.INSTANCE.save(ri);
JPA.INSTANCE.clear();

ReferringItem retr = JPA.INSTANCE.get(
ReferringItem.class, ri.getId());
System.out.println("Source == Retrieved: " + (ri==retr));

System.out.println("Retrieved Collection:");
for (AnEmbeddable ae : retr.getMyCollection()) {
    System.out.println(ae);
}

System.out.println("Retrieved Set:");
for (Long l : retr.getMySet()) {
    System.out.println(l);
}

System.out.println("Retrieved List:");
for (Iterator it = retr.getMyList().iterator(); it.hasNext();) {
    System.out.println(it.next());
}

System.out.println("Retrieved Map:");
for (Map.Entry<String,AnEmbeddable> e : map.entrySet()) {
    System.out.println(e.getKey() + " - " + e.getValue());
}
Generates:
Source == Retrieved: false
Retrieved Collection:
AnEmbeddable{s: {Coll1}}
AnEmbeddable{s: {Coll2}}
Retrieved Set:
-9223372036854775808
33
Retrieved List:
aaa
bbb
Retrieved Map:
prt - AnEmbeddable{s: {Map1}}
frd - AnEmbeddable{s: {Map2}}
We make sure the retrieved object instance is not identical to the persisted source object. The retrieved object is retrieved from the database.

The above example is available from Github in the JPA directory. It relies on Pojomatic too. Some errors messages will be displayed because of a known and harmless issue.

Monday, 30 July 2012

Java: How to Iterate Through a Map?

There are multiple ways to iterate through a Java Map. Assuming the following map declaration:
Map<String,Object> m = new HashMap<String,Object>();
Here are the mutliple ways to iterate it.

Iterate on Keys and Values

// With an Iterator (with Generics)
Iterator<Entry<String, Object>> iterator
    = m.entrySet().iterator();

while ( iterator.hasNext() ) {
    Entry<String, Object> item = iterator.next();
    System.out.println(item.getKey()
      + " - " + item.getValue());
}

// Without an Iterator (without Generics)
Iterator iterator2 = m.entrySet().iterator();
while ( iterator2.hasNext() ) {
    Entry item = (Entry) iterator.next();
    System.out.println(item.getKey()
      + " - " + item.getValue());
}

// Using For Each (with Generics)
for ( Entry<String, Object> item : m.entrySet() ) {
    System.out.println(item.getKey()
      + " - " + item.getValue());
}

// Using For Each (without Generics)
for ( Entry item : m.entrySet() ) {
    System.out.println(item.getKey()
      + " - " + item.getValue());
}

// Inefficient (fetching value from key)
for ( String key : m.keySet() ) {
    System.out.println(key + " - " + m.get(key));
}

Iterate on Keys Only

for ( String key : m.keySet() ) {
    System.out.println(key);
}

Iterate on Values Only

for ( Object value : m.values() ) {
    System.out.println(value);
}