-->
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.  [ 11 posts ] 
Author Message
 Post subject: Multiple inherited types in collection
PostPosted: Wed Dec 21, 2005 6:32 am 
Newbie

Joined: Fri Dec 02, 2005 12:08 am
Posts: 12
I have class Vehicle, class Car:Vehicle, class Bus:Car and class Truck:Car. Can I in other class Garage define collection which will have object of type Car (it may be Car, Bus or Truck)?

I want some like that:
Code:
public class Garage
{
   private ISet _cars = new HashedSet();

   public Garage() {}

   public ISet Cars {
      get { return _cars; }
      set { _cars = value; }
   }

}

private static void Main(string[] args) {
   Garage garage = new Garage();
//Add truck
   Truck truck = new Truck();
   garage.Cars.Add(truck);
   session.SaveOrUpdate(truck);
//Add bus
   Bus bus = new Bus();
   garage.Cars.Add(bus);
   session.SaveOrUpdate(bus);
//Add car
   Car car = new Car();
   garage.Cars.Add(car);
   session.SaveOrUpdate(car);
   session.SaveOrUpdate(garage);


NHibernate correct save all object, but when I retrieve objects by
Code:
ICriteria cr = session.CreateCriteria(typeof(Garage));
IList userList = cr.List();

I have exception

An unhandled exception of type 'NHibernate.ADOException' occurred in nhibernate.dll
Additional information: could not initialize collection: [TestORM.Bll.Garage.Cars#1]


What's wrong in my code?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 21, 2005 12:58 pm 
Senior
Senior

Joined: Wed Jun 15, 2005 4:17 am
Posts: 156
post your mappings.

Cheers,
Radu


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 22, 2005 12:20 am 
Newbie

Joined: Fri Dec 02, 2005 12:08 am
Posts: 12
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
   <class name="TestORM.Bll.Vehicle, TestORM" table="Vehicle">
      <id column="id" type="Int32">
         <generator class="identity" />
      </id>
      <property name="Name" type="String" />
      <property name="Speed" type="Int32" />
      <!-- ************************* Car ****************************** -->
      <joined-subclass name="TestORM.Bll.Car, TestORM" table="Car" extends="TestORM.Bll.Vehicle, TestORM">
         <key column="idVehicle" />
         <property name="Weight" type="Double" />
         <many-to-one name="Driver" class="TestORM.Bll.Driver, TestORM" column="idDriver" />
         <!-- ************************** Truck *****************************
         <joined-subclass name="TestORM.Bll.Truck, TestORM" table="Truck" extends="TestORM.Bll.Car, TestORM">
            <key column="idCar" />
            <property name="MaxCount" type="Int32" />
               <set name="Bicycles" table="Bicycle">
                  <key column="idTruck" />
                  <one-to-many class="TestORM.Bll.Bicycle, TestORM" />
                  
               </set>
         </joined-subclass>-->
         <!-- ************************* Bus ******************************
         <joined-subclass name="TestORM.Bll.Bus, TestORM" table="Bus" extends="TestORM.Bll.Car, TestORM">
            <key column="idCar" />
            <property name="Color" type="Int32" />
            <property name="Number" type="Char" />
         </joined-subclass>-->
                  
      </joined-subclass>
      <!-- ************************* Bicycle ****************************** -->
      <joined-subclass name="TestORM.Bll.Bicycle, TestORM" table="Bicycle" extends="TestORM.Bll.Vehicle, TestORM">
         <key column="idVehicle" />
         <property name="IsBell" type="Boolean" />
      </joined-subclass>
   </class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 22, 2005 6:13 am 
Senior
Senior

Joined: Wed Jun 15, 2005 4:17 am
Posts: 156
and the mapping for the Garage object? would be helpful to see the db definition as well.

Cheers,
Radu


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 22, 2005 7:53 am 
Newbie

Joined: Fri Dec 02, 2005 12:08 am
Posts: 12
Code:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
   <class name="TestORM.Bll.Garage, TestORM" table="Garage">
      <id column="id" type="Int32">
         <generator class="identity" />
      </id>   
      <property name="CountCar" type="Int32" />
      <set name="Cars" table="Car">
         <key column="idGarage"/>
         <one-to-many class="TestORM.Bll.Car, TestORM" />
      </set>
   </class>
</hibernate-mapping>


Struct DB is One class One Table nothing complicated


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 22, 2005 5:39 pm 
Senior
Senior

Joined: Wed Jun 15, 2005 4:17 am
Posts: 156
In fact the db stucture is important! You use idGarage as the key for your set but I don't know where it is defined - I suspect in table cars. Anyway I think that idGarage is null as you didn't define the relationship bidirectional so your cars aren't able to set their garage when are saved - check that in the db. This is why I think you can't reload the collection.
My suggestion is to make the relationship bidirectional: declare the set inverse=true and define a property garage in your car. Also declare cascade in your set so you can save everything just by saving the garage object.

HTH,
radu


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 22, 2005 11:40 pm 
Newbie

Joined: Fri Dec 02, 2005 12:08 am
Posts: 12
Yes, table cars contain field idGarage, in which correct save id of Garage.

Code:
create table Bus (
   idCar                int                  null,
   Color               int                  null,
   Number               char(1)              null,
   id                   int                  identity,
   constraint PK_BUS primary key  (id)
)

create table Car (
   idVehicle            int                  null UNIQUE NONCLUSTERED,
   Weight               float                null,
   id                   int                  identity,
   idGarage             int                  null,
   idDriver             int                  null,
   constraint PK_CAR primary key  (id)
)


create table Driver (
   idMan                int                  null,
   CarLicense           int                  null,
   Foto                 varbinary(100)       null,
   id                   int                  identity,
   constraint PK_DRIVER primary key  (id)
)


create table Garage (
   CountCar            int                  null,
   id                   int                  identity,
   constraint PK_GARAGE primary key  (id)
)

create table Man (
   Name                 varchar(10)          null,
   BirthDay             datetime             null,
   id                   int                  identity,
   constraint PK_MAN primary key  (id)
)

create table Truck (
   idCar                int                  null UNIQUE NONCLUSTERED,
   MaxCount             int                  null,
   id                   int                  identity,
   constraint PK_TRUCK primary key  (id)
)

create table Vehicle (
   Name                 varchar(10)          null,
   Speed                int                  null,
   id                   int                  identity,
   constraint PK_VEHICLE primary key  (id)
)

alter table Bus
   add constraint FK_BUS_GENERALIZ_CAR foreign key (idCar)
      references Car (idVehicle)


alter table Car
   add constraint FK_CAR_CAR_EXTEN_VEHICLE foreign key (idVehicle)
      references Vehicle (id)


alter table Car
   add constraint FK_CAR_CARS_GARAGE foreign key (idGarage)
      references Garage (id)


alter table Car
   add constraint FK_CAR__DRIVER_DRIVER foreign key (idDriver)
      references Driver (id)


alter table Driver
   add constraint FK_DRIVER_GENERALIZ_MAN foreign key (idMan)
      references Man (id)


alter table Truck
   add constraint FK_TRUCK_GENERALIZ_CAR foreign key (idCar)
      references Car (idVehicle)


Why i should use bidirectional relationship? Car must not to know in which Garage it stay. May be here other reason to use bidirectional relationship?
I think trouble may be in inheritance. I.e. class Vehicle, class Car:Vehicle, class Bus:Car and class Truck:Car. Can I save in collection ISet Cars objects Car and his descendants?
When I retrieve object of type Car or Truck or Bus I get exception
An unhandled exception of type 'NHibernate.ADOException' occurred in nhibernate.dll
Additional information: Unable to perform find

When I retrieve Garage i get exception
An unhandled exception of type 'NHibernate.ADOException' occurred in nhibernate.dll
Additional information: could not initialize collection: [TestORM.Bll.Garage.Cars#1]

I'm entangled, because it's my first (test) nHibernate apllication.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 23, 2005 2:53 pm 
Senior
Senior

Joined: Wed Jun 15, 2005 4:17 am
Posts: 156
well, your code works AS IS. post the whole stack trace for your exception

radu


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 26, 2005 4:14 am 
Newbie

Joined: Fri Dec 02, 2005 12:08 am
Posts: 12
StackTrace:
at NHibernate.Collection.AbstractCollectionPersister.Initialize(Object key, ISessionImplementor session)
at NHibernate.Impl.SessionImpl.InitializeCollection(PersistentCollection collection, Boolean writing)
at NHibernate.Collection.PersistentCollection.ForceInitialization()
at NHibernate.Impl.SessionImpl.InitializeNonLazyCollections()
at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Object optionalObject, Object optionalId, Object[] optionalCollectionKeys, Boolean returnProxies)
at NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters)
at NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet querySpaces, IType[] resultTypes)
at NHibernate.Loader.CriteriaLoader.List(ISessionImplementor session)
at NHibernate.Impl.SessionImpl.Find(CriteriaImpl criteria)
at NHibernate.Impl.CriteriaImpl.List()
at TestORM.MainClass.TestSelect() in c:\\temp\\testing orm\\nhibernate\\mainclass.cs:line 96\r\n at TestORM.MainClass.Main(String[] args) in c:\\temp\\testing orm\\nhibernate\\mainclass.cs:line 43


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 26, 2005 7:56 am 
Newbie

Joined: Fri Dec 02, 2005 12:08 am
Posts: 12
I read, that for hierarchy, when each class have its own separate table, I can't retrieve object by type of base class. It's true or not?
Now, I can retrieve collection of Bus and collection of Truck, but not collection of Car. And, as a consequence, I can't load object Garage with collection of Car (Cars and Trucks and Buses).

May be trouble in inheritance?
Code:
class Vehicle
...
class Car:Vehicle
...
class Bus:Car
...
class Truck:Car
...
public class Garage {
private ISet _cars = new HashedSet();
...


Can I save in collection ISet Cars objects Car and his descendants?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 28, 2005 8:02 pm 
Senior
Senior

Joined: Wed Jun 15, 2005 4:17 am
Posts: 156
The answer is yes. Check the docs here: http://www.hibernate.org/hib_docs/reference/en/html_single/#inheritance-limitations As your mapping uses the table per subclass strategy you can have a polymorphic collection with your vehicle hierarchy.

HTH,
Radu


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