Here's a a simple example of a Map collection using annotations. The default behaviour is to lazily load the Map so no annotation is necessary for this.
Child.java
Code:
package test.collection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Child {
private Long id;
private String childName;
@Id @GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getChildName() {
return childName;
}
public void setChildName(String childName) {
this.childName = childName;
}
}
Parent.java
Code:
package test.collection;
import java.util.Map;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MapKey;
import javax.persistence.OneToMany;
@Entity
public class Parent {
private Long id;
private String name;
private Map<String, Child> children;
@Id @GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(cascade=CascadeType.ALL)
@MapKey(name="childName")
public Map<String, Child> getChildren() {
return children;
}
public void setChildren(Map<String, Child> children) {
this.children = children;
}
}
TestIt.java
Code:
package test.collection;
import java.util.HashMap;
import java.util.Map;
import junit.framework.TestCase;
import org.hibernate.LazyInitializationException;
import org.hibernate.Session;
public class TestIt extends TestCase {
public void testIt() {
Long id = createData();
Session session = HibernateUtil.getSession();
Parent parent = (Parent)session.load(Parent.class, id);
session.close();
// parent should be a proxy so its fields aren't accessible outside session
try {
parent.getName();
fail("Lazy initialzation exception expected");
} catch (LazyInitializationException e) {
}
try {
parent.getChildren().size();
fail("Lazy initialzation exception expected");
} catch (LazyInitializationException e) {
}
// ---------------------
session = HibernateUtil.getSession();
parent = (Parent)session.load(Parent.class, id);
// Access to the first _basic_ field will cause a load from
// the parent table but won't load lazy collections like children.
System.out.println("parent name: "+parent.getName());
session.close();
// This should still fail because we didn't access the
// lazy collection during the session
try {
parent.getChildren().size();
fail("Lazy initialzation exception expected");
} catch (LazyInitializationException e) {
}
// ---------------------
session = HibernateUtil.getSession();
parent = (Parent)session.load(Parent.class, id);
// Accessing the children will generate SQL to
// lazily fetch from the child table.
System.out.println("number of children: "+parent.getChildren().size());
session.close();
}
private Long createData() {
Session session = HibernateUtil.getSession();
session.beginTransaction();
Map<String, Child> children = new HashMap<String, Child>();
Child c1 = new Child();
c1.setChildName("c1");
children.put("c1", c1);
Child c2 = new Child();
c2.setChildName("c2");
children.put("c2", c2);
Child c3 = new Child();
c3.setChildName("c3");
children.put("c3", c3);
Parent parent = new Parent();
parent.setName("parent name");
parent.setChildren(children);
Long id = (Long)session.save(parent);
session.getTransaction().commit();
session.close();
return id;
}
}