I apologies if this has already been answered else where but although I've come across a lot of a material describing why the one-to-one mapping does not support lazy loading I've not found any concrete examples of working around this for what must be a very common pattern.
For performance reasons I want to split a number of my classes into the main class (lets call it the summary class) and a detail class that will be available through a property of the main or summary class.  The idea being that many of these classes will simply be loaded for display in a grid where some of the (large) detail properties are not required, there will be situations however where the details for an individual item will be required and then I would like to go out to the database to get these individually (lazy load them).
So I set everything up with the one-to-one mapping as shown below (commented out) however as that does not perform a lazy loading of the detail class that is not what I want.  If I try replacing the one-to-one with a many-to-one as I've read about I get an exception when trying to save a new item, exception is shown below.
Surely this is a very common pattern, how should I implement this?
Hibernate version: 
2.0.1 GA
Mapping documents:
Code:
<?xml version="1.0"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
   <class name="Test.Asset, Test" table="Assets">
      <id name="Id" column="Id" type="Int32" unsaved-value="-1" access="nosetter.camelcase">
         <generator class="identity"/>
      </id>
      <property name="Name" column="Name" type="String" length="64"/>
      
      <!-- <one-to-one name="Detail" class="Test.AssetDetail, Test" cascade="all"/> -->
      
      <many-to-one name="Detail" column="Id" class="Test.AssetDetail, Test" cascade="all"/>
   </class>
   
   <class name="Test.AssetDetail, Test" table="AssetDetails">
      <id name="AssetId" column="AssetId" type="Int32" unsaved-value="-1" access="nosetter.camelcase">
         <generator class="foreign">
            <param name="property">Asset</param>
         </generator>
      </id>
      
      <one-to-one name="Asset" class="Test.Asset, Test" constrained="true"/>
      
      <property name="ABigProperty" column="ABigProperty" type="String" length="64"/>
   </class>
</hibernate-mapping>
Code:Code:
using System;
using NHibernate;
using NHibernate.Cfg;
namespace Test
{
   public class Asset
   {
      private int id;
      private string name;
      private AssetDetail detail;
      
      public Asset()
      {
         id = -1;
         
         detail = new AssetDetail();
         
         detail.Asset = this;
      }
      
      public virtual int Id
      {
         get {
            return(id);
         }
      }
      
      public virtual string Name
      {
         get {
            return(name);
         }
         
         set {
            name = value;
         }
      }
      
      public virtual AssetDetail Detail
      {
         get {
            return(detail);
         }
         
         set {
            detail = value;
         }
      }
   }
   
   public class AssetDetail
   {
      private int assetId;
      private Asset asset;
      private string aBigProperty;
      
      public AssetDetail()
      {
         assetId = -1;
      }
      
      public virtual int AssetId
      {
         get {
            return(assetId);
         }
      }
      
      public virtual Asset Asset
      {
         get {
            return(asset);
         }
         
         set {
            asset = value;
         }
      }
      
      public virtual string ABigProperty
      {
         get {
            return(aBigProperty);
         }
         
         set {
            aBigProperty = value;
         }
      }
   }
   
    public class Test
   {
      public static void Main(string[] arguments)
      {
         Configuration configuration;
         ISessionFactory sessionFactory;
         ISession session;
         ITransaction transaction;
         Asset asset;
         
         configuration = new Configuration();
         
         configuration.Configure();
         
         sessionFactory = configuration.BuildSessionFactory();
         
         session = sessionFactory.OpenSession();
         transaction = session.BeginTransaction();
         asset = new Asset();
         
         asset.Name = "Test";
         asset.Detail.ABigProperty = "Blah blah blah";
         session.Save(asset);
         transaction.Commit();
         Console.WriteLine(asset.Id.ToString());
         
         session.Close();
         sessionFactory.Close();
      }
    }
}
Full stack trace of any exception that occurs:Code:
Unhandled Exception: NHibernate.Id.IdentifierGenerationException: null id generated for:Test.AssetDetail
   at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean req
uiresImmediateIdAccess)
   at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
   at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
   at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
   at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
   at NHibernate.Impl.SessionImpl.FireSaveOrUpdate(SaveOrUpdateEvent event)
   at NHibernate.Impl.SessionImpl.SaveOrUpdate(String entityName, Object obj)
   at NHibernate.Engine.CascadingAction.SaveUpdateCascadingAction.Cascade(IEventSource session, Object child, String entityName, Object anything, Boolean isCasc
adeDeleteEnabled)
   at NHibernate.Engine.Cascade.CascadeToOne(Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled)
   at NHibernate.Engine.Cascade.CascadeAssociation(Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled)
   at NHibernate.Engine.Cascade.CascadeProperty(Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled)
   at NHibernate.Engine.Cascade.CascadeOn(IEntityPersister persister, Object parent, Object anything)
   at NHibernate.Event.Default.AbstractSaveEventListener.CascadeBeforeSave(IEventSource source, IEntityPersister persister, Object entity, Object anything)
   at NHibernate.Event.Default.AbstractSaveEventListener.PerformSaveOrReplicate(Object entity, EntityKey key, IEntityPersister persister, Boolean useIdentityCol
umn, Object anything, IEventSource source, Boolean requiresImmediateIdAccess)
   at NHibernate.Event.Default.AbstractSaveEventListener.PerformSave(Object entity, Object id, IEntityPersister persister, Boolean useIdentityColumn, Object any
thing, IEventSource source, Boolean requiresImmediateIdAccess)
   at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean req
uiresImmediateIdAccess)
   at NHibernate.Event.Default.DefaultSaveEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event)
   at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event)
   at NHibernate.Event.Default.DefaultSaveEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event)
   at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event)
   at NHibernate.Impl.SessionImpl.FireSave(SaveOrUpdateEvent event)
   at NHibernate.Impl.SessionImpl.Save(Object obj)
   at Test.Test.Main(String[] arguments) in Test.cs:line 119
Name and version of the database you are using:Microsoft SQL Server 2005
Code:
create table dbo.Assets (
   Id int identity(1, 1) not null,
   Name nvarchar(64) not null,
   constraint PK_Assets primary key (Id) )
go
create table dbo.AssetDetails (
   AssetId int not null,
   ABigProperty nvarchar(64) not null,
   constraint PK_AssetDetails primary key (AssetId),
   constraint FK_AssetDetails_Assets foreign key (AssetId) references dbo.Assets (Id) )
go
The generated SQL (show_sql=true):
None
Debug level Hibernate log excerpt: