-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Lazyload of Map using Hibernate Annotations only.
PostPosted: Fri Jul 27, 2007 6:55 am 
Newbie

Joined: Fri Jul 27, 2007 5:48 am
Posts: 8
Can any one please help me with Lazyload of Map objects of Java using Hibernate Annotations only?

My piece of code -

@CollectionOfElements
@OneToOne(fetch = FetchType.LAZY)
@MapKey(columns = { @Column(name = "locale", nullable = false)})
private Map values;

Instead of @OneToOne, I also tried with
@LazyCollection(LazyCollectionOption.TRUE)

But Unable to lazy load the map.

Moreover the mapping file used in Hibernate are automatically generated. I can't write them explicitly.

Regards,
Sucheta.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 27, 2007 12:58 pm 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
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;
   }
}


Top
 Profile  
 
 Post subject: Types of Maps
PostPosted: Mon Jul 30, 2007 2:16 am 
Newbie

Joined: Fri Jul 27, 2007 5:48 am
Posts: 8
Hey Mike,

Thanks for your explanation, I think it has helped me clear my ideas.

One more ques - can you give me some examples of @OneToOne & @ManyToMany Maps. I am unable to distinguish when Maps should be @OneToOne/ @ManyToMany/ @OneToMany / @ManyToOne.

Thanks,
Sucheta.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 30, 2007 7:21 am 
Expert
Expert

Joined: Fri Jul 13, 2007 8:18 am
Posts: 370
Location: london
Quote:
I am unable to distinguish when Maps should be @OneToOne/ @ManyToMany/ @OneToMany / @ManyToOne.


You need to consider the real-world relationships between your objects when deciding how to map them.

For example, every time I go supermarket shopping I make a shopping list. Over time I have many shopping lists so a Person->ShoppingList mapping would be OneToMany - one person has many shopping lists but those lists are only for that person, not shared by other people. The inverse relationship would therefor be ManyToOne - many shopping lists owned by one person.

My shopping list has multiple items I wish to buy. However, each item in the supermarket might also be on someone else's shopping list. This is an example of ManyToMany. The items are not solely for me but shared between other shoppers lists.

When I finish shopping I pay for my goods. I only pay once each time I go shopping so ShoppingList->CheckoutPaymentDetails would be a OneToOne relationship. Nobody else shares my payment details and each shopping list is only payed for once.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.