[.NET] NHibernate

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Josvds
  • Registratie: November 2004
  • Laatst online: 26-08 20:42
Ik ben bezig met een product en heb gekozen voor NHibernate. Nu wil ik echter gebruik maken van onderliggende relaties binnen een object en loop ik tegen het lazy loading probleem aan.
Heb nu d.m.v. NHibernateUtil.initialize de objecten en de onderliggende relaties mee geinitialiseerd maar kan dit niet d.m.v. een functie waarbij, bij het eerste keer aanroepen van een relatie de data wordt opgehaald?

Ik had voorheen de sessie niet gesloten en dat werkte goed, echter leverde dat problemen op omdat er meerdere sessies 1 object in gebruik hadden.

Acties:
  • 0 Henk 'm!

  • TheNameless
  • Registratie: September 2001
  • Laatst online: 07-02 21:38

TheNameless

Jazzballet is vet!

Ik snap het niet helemaal:
maar kan dit niet d.m.v. een functie waarbij, bij het eerste keer aanroepen van een relatie de data wordt opgehaald?

dit is precies wat NHibernate doet als een collectie gedefinieerd is als lazy-loading.

Ik denk dat je misschien issues tegen komt die gerelateerd zijn aan je sessie management en niet zo zeer aan lazy-loading. De sessie die gebruikt werd om de "parent" in te laden moet namelijk wel nog beschikbaar zijn als nhibernate besluit om de collectie van de parent op te halen.

Is het project een desktop app, een website of iets anders?

[ Voor 15% gewijzigd door TheNameless op 03-03-2010 14:54 ]

Ducati: making mechanics out of riders since 1946


Acties:
  • 0 Henk 'm!

  • HMS
  • Registratie: Januari 2004
  • Laatst online: 21-08 23:06

HMS

Zoals TheNameless al zegt, lazy loading houdt in dat wanneer je de collection de eerste keer aanroept dat dan pas de query naar de database gestuurd wordt.

Denk er wel aan dat de Session waar je het object vandaan hebt gehaald (Session.Get<>() result dus) beschikbaar moet zijn, anders krijg je een LazyLoadingException.

Wat bedoel je trouwens met
Ik had voorheen de sessie niet gesloten en dat werkte goed, echter leverde dat problemen op omdat er meerdere sessies 1 object in gebruik hadden.
?

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:30
HMS schreef op woensdag 03 maart 2010 @ 21:06:
Wat bedoel je trouwens met


[...]


?
Als je eenzelfde object, in 2 (actieve) sessies laadt, dan krijg je een exception.

Het probleem is hier denk ik, dat de topicstarter nog geen goed systeem heeft ivm zijn session-management.
Volgens de best practices moeten sessies 'short-lived' zijn. Maarja, wat is short-lived ...
In een WinForms applicatie zou ik mijn sessie laten bestaan gedurende de ganse use case.
Bv, in een 'edit customer' use case, zou ik de sessie de ganse tijd laten bestaan zolang het 'EditCustomer' form open blijft staan bv.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • bastv
  • Registratie: September 2005
  • Laatst online: 08-09 20:34
Ik denk ook dat er in je structuur iets niet goed zit.
en een beetje voorbeeld code zal niet verkeerd zijn.

en is lazy load wel altijd gewenst?
dit kan ook namelijk (fluentnhibernate)
References(x => x.Items).Cascade.None().Not.LazyLoad().Not.Nullable();

Acties:
  • 0 Henk 'm!

  • Josvds
  • Registratie: November 2004
  • Laatst online: 26-08 20:42
TheNameless schreef op woensdag 03 maart 2010 @ 14:51:
Ik snap het niet helemaal:
maar kan dit niet d.m.v. een functie waarbij, bij het eerste keer aanroepen van een relatie de data wordt opgehaald?

dit is precies wat NHibernate doet als een collectie gedefinieerd is als lazy-loading.

Ik denk dat je misschien issues tegen komt die gerelateerd zijn aan je sessie management en niet zo zeer aan lazy-loading. De sessie die gebruikt werd om de "parent" in te laden moet namelijk wel nog beschikbaar zijn als nhibernate besluit om de collectie van de parent op te halen.

Is het project een desktop app, een website of iets anders?
De applicatie is een website, waarop gebruikers inloggen, een bestel formulier kunnen openen waarbij een header en subregeles worden aangemaakt a.h.v. een dropdownbox.

Wanneer ik bijvoorbeeld een bestelling ophaal lied ik de sessie open staan, daarbij kon ik dan gebruik maken van bestelling.subregels zonder daar iets voor te hoeven doen. Echter wanneer ik dan een bestelling ging update maakt ik opnieuwe d.m.v. sessionfactory een sessie aan, dan krijg je dus dat een andere sessie de data nog in gebruik heeft.

Dus dan maar elke sessie gelijk afsluiten, want weet ook niet of het veilig is de sessies open te laten op het internet? Maar dan loop je er tegen aan dat lazy loading niet meer werkt i.v.m. de sessie die dan gesloten is. Nu kun je dan wel vooraf zeggen dat hij alle subregels gelijk moet initialiseren maar dan moet je dat bij het inladen aangeven welke data je gaat gebruiken. Zo doe ik het nu...

Maar is er geen mogelijkheid dat hij zelf de sessie opbouwd wanneer ik lazy loading gebruik? Of kan het geen kwaad om de sessie constant open te laten staan? Dan heb je echter maar 1 sessie welke alle acties uitvoerd.

Weet niet wat de normale gang van zaken is bij het gebruik daarvan?

Acties:
  • 0 Henk 'm!

  • Guldan
  • Registratie: Juli 2002
  • Laatst online: 11-09 19:49

Guldan

Thee-Nerd

Ik heb met NHibernate in de config (hmb.xml bestand voor de duidelijkheid) aangegeven dat lazy loading false is voor die bags. Maar ik kon ook niet zo snel een betere oplossing vinden. Mocht die wel bestaan dan ben ik ook benieuwd.

[ Voor 9% gewijzigd door Guldan op 04-03-2010 12:26 ]

You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them?


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Josvds schreef op donderdag 04 maart 2010 @ 12:06:
[...]
De applicatie is een website, waarop gebruikers inloggen, een bestel formulier kunnen openen waarbij een header en subregeles worden aangemaakt a.h.v. een dropdownbox.
Voor websites word vaak het "Open Session in View" aangehouden. ( http://www.google.nl/sear...-8&q=open+session+in+view )

Op zich gaat dat dan altijd goed, want je hebt de complete life-time van je pagina je session open staan. Je moet dan alleen niet je objecten in je (HTTP)Session willen stoppen, maar bij elke request je data opnieuw laden.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • HMS
  • Registratie: Januari 2004
  • Laatst online: 21-08 23:06

HMS

In een web app is het makkelijkste om op request (of eventueel conversation) de sessions te cachen. Eventueel zou je dit door een IoC container / framework kunnen laten doen, maar het kan ook handmatig via de HttpContext.
whoami schreef op woensdag 03 maart 2010 @ 23:20:
[...]

Als je eenzelfde object, in 2 (actieve) sessies laadt, dan krijg je een exception.
Aha, opzich wel logisch uiteraard. Had altijd mijn sessie management wel voor elkaar, dus wist niet dat deze error bestond ;-). Bedankt.

[ Voor 43% gewijzigd door HMS op 04-03-2010 13:12 . Reden: kwoot ]


Acties:
  • 0 Henk 'm!

  • bastv
  • Registratie: September 2005
  • Laatst online: 08-09 20:34
Woy schreef op donderdag 04 maart 2010 @ 12:50:
[...]

Voor websites word vaak het "Open Session in View" aangehouden. ( http://www.google.nl/sear...-8&q=open+session+in+view )

Op zich gaat dat dan altijd goed, want je hebt de complete life-time van je pagina je session open staan. Je moet dan alleen niet je objecten in je (HTTP)Session willen stoppen, maar bij elke request je data opnieuw laden.
die techniek gebruik ik ook en gaat altijd goed.
ik gebruik dezelfde opzet als sharparchitecture: http://www.sharparchitecture.net/

bekijk de onderstaande classes maar eens, deze zijn erg handig
http://github.com/codai/S...harpArch.Data/NHibernate/
http://github.com/codai/S...SharpArch.Web/NHibernate/

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:30
Josvds schreef op donderdag 04 maart 2010 @ 12:06:
[...]


De applicatie is een website, waarop gebruikers inloggen, een bestel formulier kunnen openen waarbij een header en subregeles worden aangemaakt a.h.v. een dropdownbox.

Wanneer ik bijvoorbeeld een bestelling ophaal lied ik de sessie open staan, daarbij kon ik dan gebruik maken van bestelling.subregels zonder daar iets voor te hoeven doen. Echter wanneer ik dan een bestelling ging update maakt ik opnieuwe d.m.v. sessionfactory een sessie aan, dan krijg je dus dat een andere sessie de data nog in gebruik heeft.

Dus dan maar elke sessie gelijk afsluiten, want weet ook niet of het veilig is de sessies open te laten op het internet? Maar dan loop je er tegen aan dat lazy loading niet meer werkt i.v.m. de sessie die dan gesloten is. Nu kun je dan wel vooraf zeggen dat hij alle subregels gelijk moet initialiseren maar dan moet je dat bij het inladen aangeven welke data je gaat gebruiken. Zo doe ik het nu...

Maar is er geen mogelijkheid dat hij zelf de sessie opbouwd wanneer ik lazy loading gebruik? Of kan het geen kwaad om de sessie constant open te laten staan? Dan heb je echter maar 1 sessie welke alle acties uitvoerd.

Weet niet wat de normale gang van zaken is bij het gebruik daarvan?
Bij een web-app zou ik mijn NHIbernate sessie openen bij het begin van de HttpRequest, en sluiten bij het einde van de HttpRequest.
Op die manier ben je zeker dat je sessie open is, terwijl je met je 'objecten bezig bent', en is de levensduur van de sessie ook beperkt.

/laat
wat Woy dus ook al zegt.
en wat HMS ook al zei.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • HMS
  • Registratie: Januari 2004
  • Laatst online: 21-08 23:06

HMS

Daar komt bij dat je ook een transaction kan starten aan het begin van de Request zodat je worst-case alle wijzigingen weer kan terug rollen. Ook wel handig, met name wanneer je de second-level cache etc gaat gebruiken.

Acties:
  • 0 Henk 'm!

  • Josvds
  • Registratie: November 2004
  • Laatst online: 26-08 20:42
Het is nu gelukt inderdaad, de sessie starten bij beginrequest..
Kan iemand mij vertellen hoe veilig dit is?

Een commit stopt wel de sessie, dus heb ik ingebouwd dat bij het uitlezen van de sessie en de sessie bestaat niet hij de sessie opnieuw start.

Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Josvds schreef op donderdag 04 maart 2010 @ 15:19:
Het is nu gelukt inderdaad, de sessie starten bij beginrequest..
Kan iemand mij vertellen hoe veilig dit is?
Het open houden van een session tijdens de complete life-time van je request zelf is op zich zelf niet onveilig.
Een commit stopt wel de sessie,
Ehm... nee!! een Commit sluit alleen je transactie af.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • HMS
  • Registratie: Januari 2004
  • Laatst online: 21-08 23:06

HMS

Wat bedoel je met veilig? Hack proof? Data integrity?

De HttpContext is automatisch threadsafe (thread local storage), dus daar hoef je je al geen zorgen om te maken.

Acties:
  • 0 Henk 'm!

  • Josvds
  • Registratie: November 2004
  • Laatst online: 26-08 20:42
Oke, dat was idd wat ik me afvroeg, dat niemand van buitenaf gebruik kan maken van die sessie of iets dergelijks om daar data uitwisseling uit te halen.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:30
Woy schreef op donderdag 04 maart 2010 @ 15:22:
[...]


Ehm... nee!! een Commit sluit alleen je transactie af.
Een rollback ook. :P
Josvds schreef op donderdag 04 maart 2010 @ 16:08:
Oke, dat was idd wat ik me afvroeg, dat niemand van buitenaf gebruik kan maken van die sessie of iets dergelijks om daar data uitwisseling uit te halen.
Dat heeft niets met thread-safe te maken hoor. :)
Aangezien je sessie maar bestaat tussen de begin & end-request, zou ik me er niet al te veel zorgen over maken.

[ Voor 52% gewijzigd door whoami op 04-03-2010 16:17 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Josvds
  • Registratie: November 2004
  • Laatst online: 26-08 20:42
Bedankt voor jullie reacties..

Echter wil ik nu de library hergebruiken bij een webservice. Maar daarbij loop ik er tegen aan dat je geen IList mag gebruiken en ook geen ICollection en dat is juist wat NHibernate gebruikt bij get & set.
Ik denk dat het eventueel op telossen is door twee getters en setters te maken maar dat is ook onzin eigenlijk. Hoe kan ik dit oplossen weet iemand dat?

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:30
Ik snap niet wat je nu wilt zeggen / wat je probleem is ?
In je webservice gebruik je toch je 'domain-objecten', die door NHibernate gemanaged worden ?
Wat is het probleem dan juist ?
Wat wil je bv returnen ? Hoe ziet die webservice er uit ? etc...

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 10-09 20:32
Wat voor n webservice gebruik je ? WCF? En wat stuur je over de lijn? je NHibernate classes of DTO's ?

In het eerste geval moet je hier eens kijken, in het laatste geval is dit een goed artikel

[ Voor 10% gewijzigd door D-Raven op 05-03-2010 11:31 ]


Acties:
  • 0 Henk 'm!

  • Josvds
  • Registratie: November 2004
  • Laatst online: 26-08 20:42
Ik maak gebruik van ASP.NET Web service..

Ik heb bijvoorbeeld een object:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
public class gebruiker

private adressen as IList(Of adres) = new List(Of adres)

<bag>
<key>
<oneToMany>
public overridable property adressen
get ...
set ...
end property

end class


Zoiets kan ik wel gebruik in NHibernate maar de webservice kan niet omgaan met de IList, deze werkt wel met Adres() maar daar werkt NHibernate weer niet mee.

Ik heb inderdaad iets gelezen van tussen objecten, maar daar ben ik nog mee bezig. Houd dat in dat ik naast mijn objecten van Hibernate ook nog extra van elk object een data object moet maken welke over het internet gaat?

Ik stuur deze gebruiker in dit geval over het internet terug.. met alle onderliggende adressen

Is daarvoor geen andere oplossing.

[ Voor 6% gewijzigd door Josvds op 05-03-2010 12:04 . Reden: Extra antwoord ]


Acties:
  • 0 Henk 'm!

  • Josvds
  • Registratie: November 2004
  • Laatst online: 26-08 20:42
Ik heb daarvoor nu de oplossing gevonden..

List had ik staan als List(Of Adres) dat pikte hij niet heb daarvan nu List gemaakt, dan miste ik adres dus die heb ik geinclude dmv XmlInclude(getType(Adres)).

Echter loop ik er nu tegen aan dat het kring verband is, wanneer ik bij adres dan de gebruiker niet in xml laat weergeven is het opgelost maar dan kan ik nooit terugleiden als ik een adres ophalen welke gebruiker het is.

Acties:
  • 0 Henk 'm!

  • TheNameless
  • Registratie: September 2001
  • Laatst online: 07-02 21:38

TheNameless

Jazzballet is vet!

Josvds schreef op vrijdag 05 maart 2010 @ 11:16:
Bedankt voor jullie reacties..

Echter wil ik nu de library hergebruiken bij een webservice. Maar daarbij loop ik er tegen aan dat je geen IList mag gebruiken en ook geen ICollection en dat is juist wat NHibernate gebruikt bij get & set.
Ik denk dat het eventueel op telossen is door twee getters en setters te maken maar dat is ook onzin eigenlijk. Hoe kan ik dit oplossen weet iemand dat?
Als je webservice geen gebruik kan maken van een IList maar wel van een IEnumerable kan je het gewoon zo doen:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
Public Class Gebruiker

Private _adressen As IList(Of Adres) = new List(Of Adres) 

Public Property Addressen As IEnumerable(Of Adres)
  Get
    return _addressen
  End Get
  Set
    _addressen = value
  End Set
End Property


Als je er dan gewoon voor zorgt dat NHibernate je fields gebruikt i.p.v. properties, dan kan je webservice de property blijven gebruiken.
Kijk anders even voor details hier: http://nhforge.org/doc/nh/en/index.html#d0e3469

Ducati: making mechanics out of riders since 1946


Acties:
  • 0 Henk 'm!

  • Josvds
  • Registratie: November 2004
  • Laatst online: 26-08 20:42
Bedankt voor je reactie..

Echter heb ik er voor gekozen de gehele one to many relaties uit te schakelen om de error bij circulation references te voorkomen. Tenzij er een mogelijkheid is dat dit wel kan.

[ Voor 12% gewijzigd door Josvds op 05-03-2010 13:55 ]


Acties:
  • 0 Henk 'm!

  • Josvds
  • Registratie: November 2004
  • Laatst online: 26-08 20:42
Nu loop ik tegen een ander probleem aan hopelijk weet iemand wat ik hieraan kan doen? Ik sla mijn object op in een sessie van de pagina maar dat zelfde object sla ik op in de database. Nu klaagt hibernate over een dubbele sessie die ik open zou hebben staan maar dat kan niet want deze wordt eigenlijk automatisch gesloten..

Weet iemand wat ik hieraan kan doen?

Had de close sessie aan elke pagina niet goed geplaatst hij stond bij mij in eind sessie ipv eind request.
Veranderd naar : Sub Application_EndRequest(ByVal sender As Object, ByVal e As EventArgs)

[ Voor 21% gewijzigd door Josvds op 10-03-2010 10:05 . Reden: Opgelost ]


Acties:
  • 0 Henk 'm!

  • Josvds
  • Registratie: November 2004
  • Laatst online: 26-08 20:42
Nog een vraagje over NHibernate en de Update van de database.
Als je bij <property> wat argumenten veranderd zoals bijvoorbeeld van Null naar NotNull dan past hij deze niet aan in de database, wat doe ik hierbij verkeerd?

Ik heb de regel..
tConfig.SetProperty(Environment.Hbm2ddlAuto, "update")
Pagina: 1