-->
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.  [ 10 posts ] 
Author Message
 Post subject: Mapping with association tables
PostPosted: Mon May 21, 2007 2:11 pm 
Newbie

Joined: Mon May 21, 2007 1:39 pm
Posts: 4
NHibernate version: 1.2.0

Sql Server 2005

This may be a very newbie question. I've googled and googled and found bits a pieces of answers but never a clear answer to this.

I have two tables, fdUser and fdPrinter.

fdUser:
UserID Guid
Name varchar(50)

fdPrinter:
PrinterID Guid
Name varchar(50)

I want to be able to assign any number of printers to a specific user or multiple users so I use an association table called fdUserPrinter. Included with this association is a user specific setting of "DEFAULT" for a given printer associated to the user.

fdUserPrinter:
UserID Guid
PrinterID Guid
Default bit

I have the mapping file for User like this:
Code:
<class name="User" table="fdUser">
    <id name="Id" access="nosetter.camelcase-underscore" column="UserID" type="guid" unsaved-value="00000000-0000-0000-0000-0000000000">
        <generator class="guid" />
    </id>
    <property name="Name" type="String" length="50" column="Name" non-null="true" />
   
    <bag name="Printers" cascade="save-update" table="fdUserPrinter">
        <key column="UserID" />
        <one-to-many class="DomainModel.UserPrinter, DomainModel" not-found="ignore" />
    </bag>
</class>


Then I have the mapping file for Printer like this:
Code:
<class name="Printer" table="fdPrinter">
    <id name="Id" access="nosetter.camelcase-underscore" column="PrinterID" type="guid" unsaved-value="00000000-0000-0000-0000-0000000000">
        <generator class="guid" />
    </id>
    <property name="Name" type="String" length="50" column="Name" non-null="true" />
   
    <bag name="Users" inverse="true" cascade="save-update" table="fdUserPrinter">
        <key column="PrinterID" />
        <many-to-many class="DomainModel.User, DomainModel" />
    </bag>
</class>



And finally I have my UserPrinter mapped like this:
Code:
<class name="UserPrinter" table="fdUserPrinter">
    <composite-id access="field">
        <key-property name="UserID" column="UserID" type="Guid" />
        <key-property name="PrinterID column="PrinterID" type="Guid" />
    </composite-id>
    <property name="Default" column="Default" type="boolean" not-null="false" />
</class>





So my question is how can I do the mapping such that the following can be done:
    Cascade saving and updating will save the associations
    Removing an association from User.Printers collection will delete the association in UserPrinter table
    The "Default" value in the UserPrinter class is mapped to the Printer class so I can itterate through User.Printers finding the "Default" printer


I'm somewhat new to NHibernate so I apologize in advance if this is something I should have found in the documentation! :)

Thanks for ANY help with this!


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 22, 2007 7:41 am 
Senior
Senior

Joined: Thu Feb 09, 2006 1:30 pm
Posts: 172
See the prior post:

http://forum.hibernate.org/viewtopic.php?t=974464&highlight=

Also for your cascade delete question try the "all-delete-orphan" which means that when a class in the collection is removed from the collection (no longer associated with a collection) it is to be deleted.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 22, 2007 11:00 am 
Newbie

Joined: Mon May 21, 2007 1:39 pm
Posts: 4
Ok, I tried that and now my Printers collection fails to initialize because it can't cast object UserPrinter to Printer.

I have created 3 entity classes, User, Printer and UserPrinter.

User class has a property:
Code:
public IList<Printer> Printers
{
    get { return _printers; }
    set { _printers = value; }
}


The mapping for User is now:

Code:
<class name="User" table="fdUser">
    <id name="Id" access="nosetter.camelcase-underscore" column="UserID" type="guid" unsaved-value="00000000-0000-0000-0000-0000000000">
        <generator class="guid" />
    </id>
    <property name="Name" type="String" length="50" column="Name" non-null="true" />
   
    <bag name="Printers" cascade="save-update" table="fdUserPrinter">
        <key column="UserID" />
        <composite-element class="UserPrinter" >
            <property name="DefaultPrinter" type="boolean" >
                <column name="DefaultPrinter" sql-type="bit" not-null="false" />
            </property>
            <many-to-one name="Printer" column="PrinterID" />
        </composite-element>
    </bag>
</class>


If I take the many-to-one out, I don't get the casting exception, but I also don't get any printers :) I'm not sure I understand why NHibernate is trying to make that cast. I've got to be missing something real simple! :(

Thanks for any help!


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 22, 2007 1:30 pm 
Senior
Senior

Joined: Thu Feb 09, 2006 1:30 pm
Posts: 172
shouldn't you be using an IList<UserPrinter> instead of IList<Printer>?


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 22, 2007 1:42 pm 
Newbie

Joined: Mon May 21, 2007 1:39 pm
Posts: 4
duh!

Yep that's it and it seems to be working now!

Thanks for your help!


Top
 Profile  
 
 Post subject: Same problem
PostPosted: Thu May 31, 2007 12:54 pm 
Newbie

Joined: Tue May 08, 2007 11:52 am
Posts: 6
Hi.
I've the same problem. I can't get it work.
Could you past the mapping documents and the classes documents, please.

I'm starting using this tool and i have some problems yet.
I would apreciate any help.

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 01, 2007 10:35 am 
Newbie

Joined: Mon May 21, 2007 1:39 pm
Posts: 4
Nassa,

I don't have those files with me at the moment. I will post everything for you later tonight.

Thanks


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 01, 2007 11:00 am 
Newbie

Joined: Tue May 08, 2007 11:52 am
Posts: 6
Ok. Thanks a lot.

I will wait for your help to try to resolve my problem.

Thanks again

Nassa


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 01, 2007 2:26 pm 
Newbie

Joined: Wed Jun 21, 2006 2:45 pm
Posts: 16
Yeah Mark - please post it soon so I don't have to email you all the time :)


Top
 Profile  
 
 Post subject: I think i've find the solution for me
PostPosted: Tue Jun 05, 2007 7:46 am 
Newbie

Joined: Tue May 08, 2007 11:52 am
Posts: 6
I'm posting my solution, to help other people with the same problem as me, that is the mapping for tables with a relationsship table with extra columns.

My tables :
tImpEntidade
tImpExpressao
tImpRelExpressaoEntidade

My map files :
Entidade :

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="ExportSTQData.Entidade, ExportSTQData" table="tImpEntidade">
<id name="CodEntidade" type="Guid">
<generator class="guid" />
</id>
<property name="CodImportacao" type="Guid"/>
<property name="Nome" type="String" length="256"/>
<property name="Descricao" type="String" length="1024"/>
<property name="Ordem" type="Int32"/>
<property name="CodDadoImportacao" type="Guid"/>
<property name="DataInsercao" type="DateTime"/>
<property name="DataAlteracao" type="DateTime"/>
<property name="InseridoPor" type="String" length="20"/>
<property name="AlteradoPor" type="String" length="20"/>


<many-to-one name="DadoImportacao" class="ExportSTQData.DadoImportacao, ExportSTQData" column="CodDadoImportacao" not-null="false" />

<bag name="Expressoes" cascade="save-update" table="tImpRelExpressaoEntidade" lazy="true">
<key column="CodEntidade" />
<composite-element class="ExportSTQData.RelacaoExpressaoEntidade, ExportSTQData" >
<parent name="Entidade" />
<property name="CodPropriedadeImportacao" column="CodPropriedadeImportacao" type="String" length="256" />
<property name="OperadorLogico" column="OperadorLogico" type="String" length="50" />
<property name="Valor" column="Valor" type="String" length="100" />
<property name="ePropriedadeInteraccao" column="ePropriedadeInteraccao" type="Boolean" />
<property name="eDadoInteraccao" column="eDadoInteraccao" type="Boolean" />
<property name="ePropriedadeProcesso" column="ePropriedadeProcesso" type="Boolean" />
<property name="Ordem" column="Ordem" type="Int32" />
<property name="DataInsercao" type="DateTime"/>
<property name="DataAlteracao" type="DateTime"/>
<property name="InseridoPor" type="String" length="20"/>
<property name="AlteradoPor" type="String" length="20"/>
<many-to-one name="Expressao" column="CodExpressao" />
</composite-element>
</bag>


</class>
</hibernate-mapping>


Expressao :


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="ExportSTQData.Expressao, ExportSTQData" table="tImpExpressao">
<id name="CodExpressao" type="Guid" column="CodExpressao">
<generator class="guid" />
</id>
<property name="Nome" type="String" length="256"/>
<property name="Descricao" type="String" length="1024"/>
<property name="ValorExpressao" column="Expressao" type="String"/>
<property name="CodTipoExpressao" type="Guid"/>
<property name="CodGrupoExpressao" type="Guid" not-null="false"/>
<property name="DataInsercao" type="DateTime"/>
<property name="DataAlteracao" type="DateTime"/>
<property name="AlteradoPor" type="String" length="20"/>
<property name="InseridoPor" type="String" length="20"/>



</hibernate-mapping>

RelacaoExpressaoEntidade :

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="ExportSTQData.RelacaoExpressaoEntidade, ExportSTQData" table="tImpRelExpressaoEntidade">
<composite-id access="property">
<key-property name="CodEntidade" column="CodEntidade" type="Guid" />
<key-property name="CodExpressao" column="CodExpressao" type="Guid" />
</composite-id>
<property name="CodPropriedadeImportacao" column="CodPropriedadeImportacao" type="String" length="256" />
<property name="OperadorLogico" column="OperadorLogico" type="String" length="50" />
<property name="Valor" column="Valor" type="String" length="100" />
<property name="ePropriedadeInteraccao" column="ePropriedadeInteraccao" type="Boolean" />
<property name="eDadoInteraccao" column="eDadoInteraccao" type="Boolean" />
<property name="ePropriedadeProcesso" column="ePropriedadeProcesso" type="Boolean" />
<property name="Ordem" column="Ordem" type="Int32" />
<property name="DataInsercao" type="DateTime"/>
<property name="DataAlteracao" type="DateTime"/>
<property name="InseridoPor" type="String" length="20"/>
<property name="AlteradoPor" type="String" length="20"/>
</class>
</hibernate-mapping>

My classes :

Entidade

public class Entidade : IScriptGenerator
{
private Guid codEntidade;
private Guid codImportacao;
private string nome;
private string descricao;
private int ordem;
private Guid codDadoImportacao;
private DateTime dataInsercao;
private DateTime dataAlteracao;
private string inseridoPor;
private string alteradoPor;
private IList<RelacaoExpressaoEntidade> _expressoes;

public virtual IList<RelacaoExpressaoEntidade> Expressoes
{
get { return this._expressoes; }
set { this._expressoes = value; }
}

}


Expressao :

private Guid codExpressao;
private string nome;
private string descricao;
private string expressao;
private Guid codTipoExpressao;
private Guid? codGrupoExpressao;
private DateTime dataInsercao;
private DateTime dataAlteracao;
private string inseridoPor;
private string alteradoPor;


RelacaoExpressaoEntidade

[Serializable]
public class RelacaoExpressaoEntidade : IScriptGenerator
{
private Guid _cod_entidade;
private Guid _cod_expressao;

private Entidade _entidade;
private Expressao _expressao;

private string _cod_propriedade_importacao;
private string _operador_logico;
private string _valor;
private bool _e_propriedade_interaccao;
private bool _e_dado_interaccao;
private bool _e_propriedade_processo;
private int _ordem;
private DateTime _data_insercao;
private DateTime _data_alteracao;
private string _inserido_por;
private string _alterado_por;

public override bool Equals(object obj)
{
return base.Equals(obj);
}

public override int GetHashCode()
{
return base.GetHashCode();
}

}

We just need to create the public virtual properties for each field in classes.

Hope this can be usefull to someone. Is so, please rate it. ;)

If there is anything wrong here, please tell me the correct way to do this.

Thanks.

Nassa


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