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.  [ 8 posts ] 
Author Message
 Post subject: Is it a one-to-one mapping bug?
PostPosted: Mon Aug 13, 2007 6:41 am 
Newbie

Joined: Fri Jul 20, 2007 5:09 am
Posts: 5
Location: Pune, India
Hi,

I am trying to use one-to-one mapping using a primary key association. The problem is when I try to save the parent, the child record doesn't get saved.

To replicate, here is my code -
Code:
namespace Care.Inventory {

    public class Person {

        private int id;
        private string name;
        private Author author;

        public Person() {
            author = new Author();
        }
       
        public virtual int Id {
            get { return id; }
            set { id = value; }
        }

        public virtual string Name {
            get { return name; }
            set { name = value; }
        }

        public virtual Author Author {
            get { return author; }
            set { author = value; }
        }
    }
}

namespace Care.Inventory {

    public class Author {

        private int id;
        private string alias;
        private Person person;

        public virtual int Id {
            get { return id; }
            set { id = value; }
        }

        public virtual string Alias {
            get { return alias; }
            set { alias = value; }
        }

        public virtual Person Person {
            get { return person; }
            set { person = value; }
        }

    }
}


and the table definitions -
Code:
CREATE TABLE [dbo].[Person](
   [Id] [int] IDENTITY(1,1) NOT NULL,
   [Name] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED
(
   [Id] ASC
)

CREATE TABLE [dbo].[Author](
   [Id] [int] IDENTITY(1,1) NOT NULL,
   [Alias] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
CONSTRAINT [PK_Author] PRIMARY KEY CLUSTERED
(
   [Id] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[Author]  WITH CHECK ADD  CONSTRAINT [FK_Author_Person] FOREIGN KEY([Id])
REFERENCES [dbo].[Person] ([Id])
GO


and the code in the Dao -
Code:
// insert
            Person p = new Person();
            p.Name = "Manoj";

            Author a = new Author();
            a.Alias = "Waikar";
            a.Person = p;
            p.Author = a;

            personDao.Save(p);


Now only the record in the Person table is getting saved but the one in Author is not saved.

Please let me know if I am missing something?

Thanks and regards,
Manoj.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 14, 2007 5:11 am 
Beginner
Beginner

Joined: Wed Oct 04, 2006 8:57 am
Posts: 25
Really need to see your mapping file..
it is probably because you have not specified cascase on the Author property of Person.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 14, 2007 5:16 am 
Newbie

Joined: Fri Jul 20, 2007 5:09 am
Posts: 5
Location: Pune, India
I am sorry, I forgot to include the code for the mapping files -
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
   <class name="Care.Inventory.Author, Care.Inventory" table="Author">

      <id name="Id" column="Id" type="Int32">
         <generator class="assigned" />
      </id>

      <property name="Alias" column="Alias" />
      <one-to-one name="Person" class="Care.Inventory.Person, Care.Inventory" constrained="true" />

   </class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
   <class name="Care.Inventory.Person, Care.Inventory" table="Person">

      <id name="Id" column="Id" type="Int32">
         <generator class="native" />
      </id>

      <property name="Name" column="Name" />
      <one-to-one name="Author" class="Care.Inventory.Author, Care.Inventory" />

   </class>
</hibernate-mapping>


Please let me know where's the problem.

Thanks a lot,
Manoj.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 14, 2007 5:28 am 
Beginner
Beginner

Joined: Wed Oct 04, 2006 8:57 am
Posts: 25
try putting cascade="save-update" on your one-to-one mappings.
so:

Code:
      <one-to-one name="Author" class="Care.Inventory.Author, Care.Inventory" cascade="save-update" />


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 14, 2007 5:35 am 
Newbie

Joined: Fri Jul 20, 2007 5:09 am
Posts: 5
Location: Pune, India
Sorry, that doesn't help. I've tried even cascade="all-delete-orphan".


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 16, 2007 1:50 pm 
Newbie

Joined: Wed Aug 15, 2007 1:22 pm
Posts: 5
pls let me know how this got resolved.

I am also facing some problems in one to many and one to one cases.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Aug 17, 2007 3:34 am 
Newbie

Joined: Fri Jul 20, 2007 5:09 am
Posts: 5
Location: Pune, India
Hi,

Basically, Derek's suggestion of using cascade="save-update" helped, but I think the actual problem was in the table structure. There should not be any foreign key from the child table to the parent table.

Please see the table definitions, mapping files and the C# classes below (I have a one-to-one relationship between a Product and a Stock)-

Tables -
Code:
CREATE TABLE [dbo].[Product](
   [Id] [int] IDENTITY(1,1) NOT NULL,
   [Name] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
   [Description] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
   [CompanyId] [int] NOT NULL,
CONSTRAINT [PK_Product] PRIMARY KEY CLUSTERED
(
   [Id] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]


CREATE TABLE [dbo].[Stock](
   [Id] [int] NOT NULL,
   [Quantity] [int] NOT NULL,
CONSTRAINT [PK_Stock] PRIMARY KEY CLUSTERED
(
   [Id] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]


Mapping files-
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
   <class name="Care.Inventory.Product, Care.Inventory" table="Product">

      <id name="Id" type="Int32" unsaved-value="null">
         <column name="Id" length="4" sql-type="int" not-null="true" unique="true" index="PK_Product"/>
         <generator class="native" />
      </id>

      <property name="Name" column="Name" type="String" length="50" not-null="true" />
      <property name="Description" column="Description" type="String" length="50" not-null="false" />

      <one-to-one name="Stock" class="Care.Inventory.Stock, Care.Inventory" cascade="all-delete-orphan" />
      <many-to-one name="Company" column="CompanyId" class="Care.Inventory.Company, Care.Inventory" not-null="true" />

   </class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
   <class name="Care.Inventory.Stock, Care.Inventory" table="Stock">

      <id name="Id" column="Id" type="Int32">
         <generator class="foreign">
            <param name="property">Product</param>
         </generator>
      </id>

      <property name="Quantity" column="Quantity" type="Int32" length="4" not-null="true" />
      <one-to-one name="Product" class="Care.Inventory.Product, Care.Inventory" constrained="true" />

   </class>
</hibernate-mapping>


The classes-
Code:
using System;
using System.Collections.Generic;

namespace Care.Inventory {

    public class Product {

        private int id;
        private string name;
        private string description;
        private Stock stock;
        private Company company;

        public Product() {
            name = String.Empty;
            description = String.Empty;

            company = new Company();
            stock = new Stock();
        }

        public virtual int Id {
            get { return id; }
            set { id = value; }
        }

        public virtual string Name {
            get { return name; }
            set { name = value; }
        }

        public virtual string Description {
            get { return description; }
            set { description = value; }
        }

        public virtual Stock Stock {
            get { return stock; }
            set {
                stock = value;
                stock.Product = this;
            }
        }

        public virtual Company Company {
            get { return company; }
            set { company = value; }
        }
    }
}

using System;
using System.Collections.Generic;

namespace Care.Inventory {

    public class Stock {

        private int id;
        private int quantity;
        private Product product;

        public virtual int Id {
            get { return id; }
            set { id = value; }
        }

        public virtual int Quantity {
            get { return quantity; }
            set { quantity = value; }
        }

        public virtual Product Product {
            get { return product; }
            set { product = value; }
        }
    }
}


Note that I've used cascade="all-delete-orphan" so that when you delete a Product the corresponding Stock record also gets deleted.

Hope it helps.

Regards,
Manoj.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 04, 2007 4:30 am 
Newbie

Joined: Tue Sep 26, 2006 10:59 am
Posts: 15
2 mmwaikar

It's interesting to see how you create new Product and Stock.

Thx.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 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.