HELP!! ActiveRecord - Lazy Loading Not Working.

64 views
Skip to first unread message

Diego AC

unread,
Dec 15, 2010, 12:35:06 PM12/15/10
to Castle Project Users
Hi,

I need some help in understanding this issue. I'm using the repository
pattern with ActiveRecordMediator. I've enabled the session scope http
module, marked my classes with the ActiveRecord(Lazy = true).

The problem is that each time I perform a FindAll or SlicedFindAll,
the mediator returns a collection of initialized elements instead of
proxies. Could someone point me out in the right direction?

This is my repository:

public interface IEntityRepository<TEntity>
{
IList<TEntity> FindAll(int page, int pageSize, out int
resultCount);
}

public class EntityRepository<TEntity> : IEntityRepository<TEntity>{
public virtual IList<TEntity> FindAll(int page, int pageSize)
{
return
(IList<TEntity>)ActiveRecordMediator.SlicedFindAll(typeof(TEntity),
(page * pageSize), pageSize);
}
}

[ActiveRecord(Lazy = true)]
public class DocumentEntity
{
private Guid _id;
private IList<DocumentVersionEntity> _versions;

[PrimaryKey(PrimaryKeyType.GuidComb, "Id")]
public virtual Guid Id
{
get { return _id; }
set { _id = value; }
}

[HasAndBelongsToMany(typeof(DocumentVersionEntity),
RelationType.Bag, Table = DocumentEntriesToDocumentVersions",
ColumnKey = "DocumentEntryId",
ColumnRef = "DocumentVersionId", Cascade
= ManyRelationCascadeEnum.AllDeleteOrphan, Lazy = true)]
public virtual IList<DocumentVersionEntity> Versions
{
get { return _versions; }
set { _versions = value; }
}
}

[ActiveRecord(Lazy = true)]
public class DocumentVersionEntity
{
private Guid _id;

[PrimaryKey(PrimaryKeyType.GuidComb, "Id")]
public virtual Guid Id
{
get { return _id; }
set { _id = value; }
}
}

When I execute the FindAll method, all the objects in the Versions
array of the DocumentEntity are DocumentVersionEntity instead of
DocumentVersionEntityProxy and are all intialized.

What am I doing wrong?

Jason Meckley

unread,
Dec 15, 2010, 2:44:59 PM12/15/10
to Castle Project Users
proxies are only returned when calling Load<> or when a referenced
entity is accessed. neither of which is the case here. here are some
examples. this is NH code, but it should all be the same for AR since
AR is using NH under the hood.

session.Get<Entity>(id);// returns the actual object
session.Load<Entity>(id);// returns a proxy of the object. note this
will throw if the entity doesn't actually exist

var entity = session.Get<Entity>(id);
var other = entity.ReferencedEntity; //returns a proxy of the
referenced entity

var entities = session.CreateCriteria<Entity>().List<Entity>(); //
returns a list of actual objects
foreach(var entity in entities)
{
var other = entity.ReferencedEntity; //returns a proxy of the
referenced entity

Diego AC

unread,
Dec 15, 2010, 4:11:41 PM12/15/10
to Castle Project Users
So there's no way to perform a FindAll or a HQL query to retrieve lazy-
loaded entities? I mean, a query like the one I'm attempting to
perform would be really expensive to the database since it has more
properties with relations. There must be other way, ain't it?

Jason Meckley

unread,
Dec 16, 2010, 9:46:26 AM12/16/10
to Castle Project Users
"a query like the one I'm attempting to perform would be really
expensive to the database since it has more properties with relations"
this is vague statement.
How expensive is the query?
Why is it expensive?
Quantifying the answers will give you the information required to
resolve the bottleneck.
In any case proxied entities wouldn't resolve the expense/bottleneck.

something ORM's have taught me is there is a balance between the
number of queries executed and the amount of data returned. the
obvious goal is to reduce the number of remote calls. I have found
that sometimes it's better to issue multiple queries with smaller sets
of data, than issue one query that retrieves everything.

The best techniques I have found for improving database performance
are properly indexing the database, limiting the results returned by
the query and batching reads and writes. after that I try to limit the
number of joins per query. as a last restore to improve performance I
introduce caching.

Diego AC

unread,
Dec 16, 2010, 4:17:11 PM12/16/10
to Castle Project Users
Well, I have an entity class, which have property that is a collection
of other entity classes, and each one of those classes have more
relations with more classes. If I perform a FindAll for the first
class, the mediator is retrieving all the classes with ALL the
collections initialized. Which queries pretty much the entire
database.

I think that is very expensive assuming a lot of client users perform
many find operations constantly.

Jason Meckley

unread,
Dec 16, 2010, 4:55:46 PM12/16/10
to Castle Project Users
what do you mean the "collections are initialized"? do you mean
property is marked as initialized, or the data is loaded from the
database? if you provide the code used to determine if the property is
initialized then we can provide more insight into what's happening.
Reply all
Reply to author
Forward
0 new messages