# Hibernate Mapping Problem



## beuschl (5. Dez 2009)

hi

habe eine Frage zum Hibernate Mapping (annotations)
und zwar habe ich folgende Tabellen auf der Datenbank: Person - Stock - Product
person tabelle hat personid als PK
product tabelle hat product id als PK
und Stock hat stockid als PK, 2 FKs (userid, productid) und nein zusätzliches attribut "quantity"

Wenn ich jetzt zb ein vorhandenes Stock Object updaten will (habe zb quantity erhöht) bzw ein User objekt uodaten will(weil er ein neues Stock Objekt in sein HashSet bekommen hat) bekomme ich den Fehler: Aktualisieren von ("SS09_DBS1"."STOCK"."USERID") zu NULL nicht möglich
Hibernate will immer folgendes Statement absetzen: update stock set userid=null where userid=?
(wenn man ein User Objekt updaten will)
bzw beim Stock update, setzt er zuerst einen richtigen update Befehl und gleich danach den obigen update Befehl, weshalb ich dann natürlich eine Exception habe

Könnt ihr euch evtl mein Mapping anschaun und mir sagen ob ich irgendwo einen Fehler habe?



```
@Entity
@Table(name= "person")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int userid;

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinColumn(name="userid")
    private Set<Stock> userStock = new HashSet<Stock>();  // Stock Zwischentabelle   
.
.
.
```


```
@Entity
@Table(name= "stock")
public class Stock {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int stockid;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="userid")
    private User user;

    @OneToOne(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinColumn(name="productid")
    private Product product;    // Welches Product
    private int quantity;       // Wieviel davon
```

Wenn ich jetzt zb ein neues Stock Objekt erzeuge und das mit Werten ausfülle (also ihm ein Product und einen user zuweise) und dann NEU in die Datenbank einfüge funktioniert es. Wenn ich allerdings von einem vorhandenen Stock Objekt die Quantity ändere und es nur updaten will, kommt der oben genannte Fehler

So zb will ich das Stock objekt updaten


```
Stock stock = new Stock(p, 1); // p = ein product objekt
         stock.setUser(u); // u = ein User objekt

    session.update(stock);  // stock update
                                    stocklist.add(stock);  // stock objekt zu einer HashSet hinzufügen
                                     u.setUserStock(stocklist);  // neue HashSet liste dem Use rzuordnen
                                     session.update(u);    // User updaten
```


----------



## SlaterB (6. Dez 2009)

wie passt 
> So zb will ich das [vorhandene] Stock objekt updaten
zu Code mit 'new Stock(p, 1)'?

von Stock aus brauchst du doch sicher kein Cascade nach User, oder?

die Verbindung sollte glaube ich auch nur einmal gesetzt werden, 
wenn du 'stock.setUser(u);' ausführst, dann müsste Hibernate selber den Stock beim User in die Liste einfügen,
evtl. erst nach update oder Neuladen des Users,

ganz schräg sieht es aus, wenn du danach beim User eine neue stocklist setzt bzw ein stockset, ist doch ein HashSet, 
jeder User hat doch ein Set, wieso ein neues? und wo kommt das her, wer hat das wann erzeugt?

es muss doch fertige Beispiele zu sowas geben, in
https://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html/example-parentchild.html
steht z.B.
> Now that the Child entity is managing the state of the link, we tell the collection not to update the link. We use the inverse attribute.


----------



## beuschl (6. Dez 2009)

hi

diese stocklist die du ansprichs hole ich mir vorher von einem User... dann iteriere ich diese durch (mache ein paar programmspezifische dinge, und füge ein neues Stock Objekt in die Liste ein.
Danach bekommt der angemeldete User diese aktualisierte stocklist (u.setUserStock(stocklist)). Das ganze soll dann atürlich auch in der Datenbank aktualisiert werden. So zumindest hab ich mir das ganze gedacht

und ja stocklist ist ein HashSet und jedes Userobjekt hat so ein HashSet


----------



## beuschl (6. Dez 2009)

hab mich noch kurz herumgespielt und folgendes gemacht


```
Stock stock = new Stock(p, 1); //neues Stock Object erzeugen (quantity = 1)
stock.setUser(u);   // Object dem User zuordnen

int quant = 0;

 if(stocklist != null){   // stocklist ist die aktuelle Stockliste des Users (u)
   for(Stock x : stocklist){
            if(x.getProduct().getId() == stock.getProduct().getId()){
                  quant = x.getQuantity();             // quantity des Stockobjects aus der liste holn und um 1 erhöhn
                   quant += stock.getQuantity();
             }
   }
                   
 stock.setQuantity(quant);

 session.update(stock);
  session.flush();
```

führe ich diesen code aus macht Hibernate auch richtig das kommando
 update stock set productid=?, quantity=?, userid=? where stockid=?

commit etc geht auch alles richtig durch
nur in d er Datenbank wird die neue Quantity des einen Stock objects nicht upgedatet. also es sit zb vor dem code 5 und nach dem code müsste es 6 sein (laut debugger haben die Objekte auch die richtigen Werte) nur wird es nicht in die Datenbank geschrieben
hat jemand eine idee wieso?


----------

