[Nhibernate]Mapping met composite key

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • jos707
  • Registratie: December 2000
  • Laatst online: 11-09 09:20
Ik zit hier met een Nhibernate probleem waar ik maar geen oplossing voor kan vinden.

Stel ik heb twee tabellen, zeg maar Customer and Order, beide tabellen hebben als primary key een
composite key dat dus bestaat uit de combinatie van twee kolommen.
Customer heeft als composite key kolom A en B.
Order heeft als composite key kolom A en C.

Nu tracht ik in Customer een bag te creeren die alle Order objecten mapt waar de waarde
in beide tabellen dezelfde is voor kolom A.

Hier is de Customer.hbm.xml
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<class name="NHibernate.Customer, NHibernate" table="Customer">
    
    <!-- Composite key (primary key consists of more than one field -->
    <composite-id>
      <key-property name="A" column="pkA"></key-property>
      <key-property name="B" column="pkB"></key-property>
    </composite-id>
  
    <!-- One-to-many mapping-->
    <bag name="OrderList" lazy="false">
      <key>
        <column name="A"/>
      </key>
      <one-to-many class="Order"></one-to-many> 
    </bag>
</class>


bij het uivoeren geeft Nhibernate mij telkens volgende foutmelding:
Foreign key (FK497BA9679EAD9D16:Order [A])) must have same number of columns as the referenced primary key (Customer [A, B])

Als ik de fout goed begrijp dan dien ik de bag aan te maken met de twee primary keys, maar aangezien tweede primary key (B voor Customer en C voor Order) niet gelijk zijn lijkt mij dit niet mogelijk?
Ik weet dat het gebruik van composite keys in combinatie met Nhibernate wordt afgewezen maar ik dit geval heb ik niet veel keus aangezien we een legacy database gebruiken zonder de mogelijkheid tot aanpassing.

Heeft iemand hier enige ervaring dit probleem ?

[ Voor 47% gewijzigd door jos707 op 28-10-2009 16:25 ]


Acties:
  • 0 Henk 'm!

  • Daspeed
  • Registratie: Maart 2001
  • Laatst online: 15:03
Je moet in de bag de twee kolommen opgeven van de Order die verwijzen naar de Customer.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 12-09 23:07
jos707 schreef op woensdag 28 oktober 2009 @ 15:29:

bij het uivoeren geeft Nhibernate mij telkens volgende foutmelding:
Foreign key (FK497BA9679EAD9D16:Order [A])) must have same number of columns as the referenced primary key (Customer [A, B])
Logisch toch ?
Je zegt zelf dat je primary key bestaat uit 2 kolommen, maar in je bag geef je slechts één column op als 'key'.
Als de PK In customer 2 kolommen beslaat, dan gaat je foreign key in customer toch ook uit 2 kolommen bestaan, en dus moet je in je mapping ook die 2 kolommen specifieren bij 'key'.
Anders kan NHibernate natuurlijk nooit de relatie leggen als hij een query moet genereren.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • jos707
  • Registratie: December 2000
  • Laatst online: 11-09 09:20
Daspeed schreef op woensdag 28 oktober 2009 @ 16:04:
Je moet in de bag de twee kolommen opgeven van de Order die verwijzen naar de Customer.
Dat is juist het probleem, ik heb geen tweede kolom. De enige gemeenschappelijke kolom tussen Customer en Order is kolom A.

Misschien kan een bag hier helemaal niet mee overweg, ik begrijp wel dat wanneer je aangeeft dat elke unieke Customer kan worden geïdentificeerd door kolom[A,B] dat Nibernate verwacht dat vanuit elke gemapte tabel die naar Customer verwijst eveneens de key kolommen [A,B] bestaan.
Als dit inderdaad het geval is dan biedt een bag geen oplossing voor mijn probleem en moet ik een andere manier vinden om gewoon in mijn Customer class een lijst bij te houden van alle Orders die aan de voorwaarde voldoen: [Customer.A == Order.A].
De vraag is natuurlijk dan hoe doe ik dit en bestaat hier een manier voor ?

Het komt erop neer dat ik gewoon een lijst wil bijhouden in Customer die het resultaat bevat van de volgende query:
code:
1
2
select Order.Id from Customer,Order 
where Customer.A = Order.A

Acties:
  • 0 Henk 'm!

  • Daspeed
  • Registratie: Maart 2001
  • Laatst online: 15:03
jos707 schreef op woensdag 28 oktober 2009 @ 16:23:
[...]

Dat is juist het probleem, ik heb geen tweede kolom. De enige gemeenschappelijke kolom tussen Customer en Order is kolom A.
Dan bevat een Order dus geen verwijzing naar een Customer en kun je de relatie niet leggen :P
Het komt erop neer dat ik gewoon een lijst wil bijhouden in Customer die het resultaat bevat van de volgende query:
code:
1
2
select Order.Id from Customer,Order 
where Customer.A = Order.A
Als je alleen wilt selecteren: Je kunt in HQL en de criteria API gewoon dit soort restricties leggen aan de resultset.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 12-09 23:07
jos707 schreef op woensdag 28 oktober 2009 @ 16:23:
[...]

Dat is juist het probleem, ik heb geen tweede kolom. De enige gemeenschappelijke kolom tussen Customer en Order is kolom A.
Je primary key bestaat uit 2 columns zeg je.
Dan moet je foreign key in order ook uit 2 kolommen bestaan, hoe kan je anders een correcte relatie leggen tussen een customer en zijn orders ?
Ben je zeker dat de primary key wel uit 2 kolommen bestaat ? Ben je zeker dat het een composite key is ?
Misschien kan een bag hier helemaal niet mee overweg,
Niemand kan daar mee overweg.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • jos707
  • Registratie: December 2000
  • Laatst online: 11-09 09:20
whoami schreef op woensdag 28 oktober 2009 @ 16:31:
[...]
Je primary key bestaat uit 2 columns zeg je.
Dan moet je foreign key in order ook uit 2 kolommen bestaan, hoe kan je anders een correcte relatie leggen tussen een customer en zijn orders ?
Ben je zeker dat de primary key wel uit 2 kolommen bestaat ? Ben je zeker dat het een composite key is ?
[...]
Niemand kan daar mee overweg.
Ik moet zeggen dat ik met nhibernate nog niet veel ervaring heb maar als ik het goed begrijp dient een bag enkel voor één op één mappings. Nu is de tabelstructuur waar ik probeer mee aan de gang te krijgen niet één echt voor de hand liggend.
Dit schetst de situatie ongeveer:
Afbeeldingslocatie: http://ultraxs.com/image-BBB8_4AE86B41.gif
Kolommen B en C worden alleen intern gebruikt door de table zelf om het record uniek te maken, deze kolommen houden een historiek bij van het betreffende record. Elke update maakt een nieuw record aan waarbij het historiekrecord nr wordt opgehoogd. Aangezien deze alleen intern in de betreffende tabel worden gebruikt kunnen deze niet als foreign key fungeren. Maar tegelijk zijn deze historiekkolommen wel noodzakelijk om een record uniek te maken in een tabel en behoren dus to de PK.

Afgaande op het bovenstaande schema probeer ik bij het ophalen van Customer 1000 automatisch nhibernate een lijst op te halen van alle orders waar kolom A = 1000 (resultaat = 3 orders).
Kolommen B en C hebben hier verder weinig mee te maken.

Hopelijk verduidelijkt dit het een beetje, maar zoals ik al zei misschien bestaat hier een betere manier waar ik mij niet van bewust ben? Dien ik telkens ik een Customer ophaal een dynamische query richting database te sturen, het resultaat op te halen en in een lijst te droppen?

[ Voor 3% gewijzigd door jos707 op 28-10-2009 17:22 ]


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 09:18

Creepy

Tactical Espionage Splatterer

(jarig!)
Hoe haal je dan nu zelf een lijst van customers op? Zit je daadwerkelijk altijd een MAX(historyId) met een GROUP BY te doen?

Je kan nu zoals je al merkt geen gebruik maken van een normale relaties tussen je tabellen. Is het geen optie om de historische data in een eigen tabel te zetten? Op die manier heb je een normale PK voor je customer tabel.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • Daspeed
  • Registratie: Maart 2001
  • Laatst online: 15:03
Begrijp ik het dan goed dat je een append only model hebt (in ieder geval voor die twee tabellen)?

In dat geval heb je sowieso niet zoveel aan een bag, omdat die bag je in staat stelt om wijzigingen door te voeren op bestaande records.

Maaruh als het je puur gaat om selecteren van data dan kun je dat altijd buiten de mapping om met nhibernate (hql/criteria) doen.

Acties:
  • 0 Henk 'm!

  • jos707
  • Registratie: December 2000
  • Laatst online: 11-09 09:20
Creepy schreef op woensdag 28 oktober 2009 @ 17:26:
Hoe haal je dan nu zelf een lijst van customers op? Zit je daadwerkelijk altijd een MAX(historyId) met een GROUP BY te doen?
...
Idd daar komt het op neer, helaas is er geen enkele mogelijkheid tot aanpassen van de tabelstructuur dus ik zit vast aan dit model.
Daspeed schreef op woensdag 28 oktober 2009 @ 17:30:
Begrijp ik het dan goed dat je een append only model hebt (in ieder geval voor die twee tabellen)?

In dat geval heb je sowieso niet zoveel aan een bag, omdat die bag je in staat stelt om wijzigingen door te voeren op bestaande records.

Maaruh als het je puur gaat om selecteren van data dan kun je dat altijd buiten de mapping om met nhibernate (hql/criteria) doen.
Ja, append only, geen delete of update, in weze gaat het enkel en alleen over het ophalen van records.
Het plan was in eerste instantie om dit eenvoudig te houden zonder dat ik met HQL aan de slag moet, HQL vereist nog steeds dat we dynamische queries moeten gaan bouwen en dit vermijden was juist één van redenen om met nhibernate aan de slag te gaan.

Bedankt voor de antwoorden iig.

Acties:
  • 0 Henk 'm!

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Ik heb laatst een gelijksoortig probleem aan de hand gehad met de Java versie van Hibernate. Composite primary keys met een foreign key kolom als onderdeel van die primary key is ook daar een lastig probleem. Ik heb er uiteindelijk omheen gewerkt, maar dat kon alleen omdat de tabel waar die key heen verwees constant is (en aangezien die tabel aan de ene kant al 5 jaar niet veranderd is en aan de andere kant die hele database over twee jaar toch vervangen wordt, was het echt de moeite niet waard het op te lossen zoals het hoort).

Wie trösten wir uns, die Mörder aller Mörder?

Pagina: 1