-->
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: one-to-one and what else (in the C# code)
PostPosted: Wed Jan 11, 2006 4:20 am 
Regular
Regular

Joined: Fri Feb 18, 2005 3:34 am
Posts: 88
Location: Poland/Wrocław
Hi everyone,

I've a class Picture and Data with one to one relationship (Data instance is being contained by Picture instance). I have the following mappings defined:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="Pix.Data.Picture, Pix.Data" table="OBJECT">
<id name="Id" column="ID" type="Int32" unsaved-value="0" access="field">
<generator class="sequence">
<param name="sequence">OBJECT_ID_GEN</param>
</generator>
</id>
<property name="Name" column="NAME" type="String" access="field" />
<property name="Path" column="PATH" type="String" access="field" />
<property name="Checksum" column="CHECKSUM" type="String" access="field" />
<property name="Encrypted" column="ENCRYPTED" type="Boolean" access="field" />
<one-to-one name="Data" class="Pix.Data.Data, Pix.Data"
constrained="true" access="field" />
</class>
</hibernate-mapping>


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="Pix.Data.Data, Pix.Data" table="PICTURE">
<id name="Id" column="ID" type="Int32" unsaved-value="0" access="field">
<generator class="foreign">
<param name="property">Owner</param>
</generator>
</id>
<property name="Bytes" column="IMAGE" type="BinaryBlob" access="field" />
<one-to-one name="Owner" class="Pix.Data.Picture, Pix.Data" access="field" />
</class>
</hibernate-mapping>

The question is whether these mappings are correct (please givme a hint if not). Next issue is how to commit an object...

ITransaction transaction = session.BeginTransaction();
try
{
Pix.Data.Picture item = new Pix.Data.Picture();
item.Data = new Pix.Data.Data();
// item.Data.Owner = item; // need this??
progress += (100M / ((string[])e.Argument).Length);
ctrlImportWorker.ReportProgress(Convert.ToInt32(progress));
item.Name = Path.GetFileName(path);
item.Path = Path.GetFullPath(path);
byte[] imageBuffer = LoadFile(path);
item.Data.Bytes = Encryption.CoDec.Encrypt(imageBuffer);
item.Checksum = Encryption.CoDec.Hash(imageBuffer);
imageBuffer = null;
session.Save(item);
transaction.Commit();
}
catch(HibernateException x)
{
transaction.Rollback();
}


I get following error: "not-null property referrences a null or transient value: Pix.Data.Picture.Data". What exactly means transient - not yet saved?

P.S. How to write posts with tabs in the text?

TIA

_________________
Please rate this post if you've found it helpfull
Roland


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 11, 2006 6:34 am 
Contributor
Contributor

Joined: Wed May 11, 2005 4:59 pm
Posts: 1766
Location: Prague, Czech Republic
transient = does not exist in the database, that is, not yet saved or already deleted


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 12, 2006 3:27 am 
Regular
Regular

Joined: Fri Feb 18, 2005 3:34 am
Posts: 88
Location: Poland/Wrocław
OK - I will try to explain my question a bit better...

I have classes as following (in my data layer):

Code:
class Picture
{
  public int Id = 0;
  public Data Data;
}

class Data
{
  public Picture Owner;
  public int Id = 0;
  public byte[] Bytes;
}


I have changed mapping a bit so now it looks like this:
Code:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
  <class name="Pix.Data.Picture, Pix.Data" table="OBJECT">
    <id name="Id" column="ID" type="Int32" unsaved-value="0"
          access="field">
      <generator class="foreign">
        <param name="property">Data</param>
      </generator>
    </id>
    <one-to-one name="Data" class="Pix.Data.Data, Pix.Data"
                       constrained="true" access="field" />
  </class>
</hibernate-mapping>


and

Code:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
  <class name="Pix.Data.Data, Pix.Data" table="PICTURE">
    <id name="Id" column="ID" type="Int32"
          unsaved-value="0"access="field">
      <generator class="sequence">
        <param name="sequence">OBJECT_ID_GEN</param>
      </generator>
    </id>
    <property name="Bytes" column="IMAGE" type="BinaryBlob"
                    access="field" />
    <one-to-one name="Owner" class="Pix.Data.Picture, Pix.Data"
                       access="field" />
  </class>
</hibernate-mapping>


And now I would like to store a picture in my database (Firebird). So I assume I need to follow this:

Code:
void SavePicture(byte[] bytes, ISession sess)
{
  ITransaction tr = sess.BeginTransaction();
  try
  {
    Picture pic = new Picture();
    pic.Data = new Data();
    pic.Data.Bytes = bytes;
    sess.Save(pic);
    tr.Commit();
  }
  catch(HibernateException)
  {
    tr.Rollback();
  }
}


And now I wanted to ask my question... but decided to test it before. And finally I discoverred it works this way (did not with previous mapping).

So I also decided not to abandon this post. If it could be helpfull to anyone then I think it is worth to put it anyway. At least I did not find any hints in existing furum archive...

_________________
Please rate this post if you've found it helpfull
Roland


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 12, 2006 4:10 am 
Regular
Regular

Joined: Fri Feb 18, 2005 3:34 am
Posts: 88
Location: Poland/Wrocław
Now I added lazy initialization to Data class:
Code:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
  <class name="Pix.Data.Data, Pix.Data" table="PICTURE" lazy="true">
    <id name="Id" column="ID" type="Int32"
          unsaved-value="0"access="field">
      <generator class="sequence">
        <param name="sequence">OBJECT_ID_GEN</param>
      </generator>
    </id>
    <property name="Bytes" column="IMAGE" type="BinaryBlob"
                    access="field" />
    <one-to-one name="Owner" class="Pix.Data.Picture, Pix.Data"
                       access="field" />
  </class>
</hibernate-mapping>


Great... But now when I read my stored Picture object, I do NOT have Data field being initialized. Can anyone explain it to me? Does the generic proxy implementation in NHibernate (it is Castle, isn't i?) work with fields? If it does then why just simple invokation:

Code:
void Read(ISession sess, int id)
{
  Picture pic = (Picture)sess.Load(typeof(Picture), id);
  ShowPicture(pic.Data.Bytes);
}


doesn't work? The Data property has been initialized (I see it is just the proxy), but the data in it is NOT. Owner is null, id is zero, Bytes is null.

When I don't use lazy loading then it works :|

TIA

_________________
Please rate this post if you've found it helpfull
Roland


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.