-->
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.  [ 1 post ] 
Author Message
 Post subject: A Proxy alternative to Lightweight/Heavyweight
PostPosted: Thu Feb 12, 2004 9:59 am 
Newbie

Joined: Thu Dec 04, 2003 5:53 am
Posts: 11
Location: Toulouse, France
There are some disadvantages to the Lightweight Class, including the ones already mentioned in the link, plus the fact that client code has to know about the lightweight and heavyweight classes and decide between them.

Hibernate's CGLib proxies can be used to prevent all of the object's many-to-one properties from loading, but cannot be used for fine-grained loading of only certain properties.

I presume (can anyone confirm? I'll get around to testing this if nobody confirms) that if two Hibernate proxies are joined together by a graph, then instantiating the first proxy will not provoke instantiation of the second.

Here's a third solution which allows fine-grained loading of only certain entity properties (as in Lightweight/Heavyweight but without its disadvantages), using the Proxy pattern as well. It is based on the Document class described in the Lightweight pattern (minus a couple of properties).
Code:
public interface Document {
   public Long getKey();
   public String getName();
   public void setName(String name);
   public Folder getFolder();
   public void setFolder(Folder folder);
   public Clob getText();
   public void setText(Clob text);
}

class DocumentImpl implements Document {
   private Long _key;
   private String _name;
   private Folder _folder;
   private Clob _text;
   public Long getKey() { return _key; }
   protected void setKeyDB(Long key) { _key = key; }
   public String getName() { return _name; }
   public void setName(String name) { _name = name; }
   public Folder getFolder() { return _folder; }
   public void setFolder(Folder folder) { _folder = folder; }
   public Clob getText() { return _text; }
   public void setText(Clob text) { _text = text; }
}

class DocumentProxy implements Document {
   private DocumentImpl _subject = null;
   private Long _key;
   private String _name;
   private Folder _folder;
   public Long getKey() { return _subject==null ? _key : getSubject().getKey(); }
   protected void setKeyDB(Long key) { _key = key; }
   public String getName() { return _subject==null ? _name : getSubject().getName(); }
   public void setName(String name) { getSubject().setName() }
   protected void setNameDB(String name) { _name = name; }
   public Folder getFolder() { return _subject==null ? _folder : getSubject().getFolder(); }
   public void setFolder(Folder folder) { getSubject().setFolder(folder); }
   protected void setFolderDB(Folder folder) { _folder = folder; }
   public Clob getText() { return getSubject().getText(); }
   public void setText(Clob text) { getSubject().setText(text); }
   
   private DocumentImpl getSubject() {
      if (_key==null) {
         // ... get Hibernate session
        _subject = (DocumentImpl) session.load(DocumentImpl.class, _key);
      }
     return _subject;
   }
}


We can now implement certain methods to return the proxies, but the client doesn't know the difference, since all he gets back is the Document interface. As soon as he tries to get the CLOB, the real subject is loaded for him behind the scenes and the CLOB retrieved.
Something like this:
Code:
public Set findDocumentsByName(String name) throws HibernateException {
   // ... get the hibernate session
   Iterator results = session.iterate("SELECT document.key, document.name, document.folder"
      + " FROM tests.DocumentImpl AS document"
      + " WHERE document.name LIKE ?"
      + " ORDER BY document.name",
      "%" + name + "%",
      Hibernate.STRING);
   HashSet documents = new LinkedHashSet();
   while (results.hasNext()) {
      Object[] result = (Object[]) results.next();
      Long key = (Long) result[0];
      String name = (String) result[1];
      Folder folder = (String) result[2];
      DocumentProxy document = new DocumentProxy();
      document.setKeyDB(key);
      document.setNameDB(name);
      document.setFolderDB(folder);
      documents.add(document);
   }
   return documents;
}

Note that you could implement a graph of objects as proxies (say, we could make Folder a proxy), and fill in the entire graph as above.

Any thoughts? Is this a good approach? I know there is nothing revolutionary about this, but is it worth putting up on the Wiki alongside the Lightweight/Heavyweight pattern?

Best regards,
Assaf


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

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.