Hibernate - N:1 Beziehung

Studdi23

Mitglied
Hallo zusammen,

arbeite mich zur Zeit in Hibernate ein und versuche mich an einigen Beispielen aus einem Buch. Und zwar habe ich zwei annotierte Klassen "Pizza" und "Order", die in einer N zu 1 Beziehung stehen, d.h. mehere Pizzen werden einer Bestellung zugeordnet und zu jeder Bestellung gehört genau eine Pizza.
Die Pizza-Klasse besitzt eine Fremdschlüsselspalte der Order-Klasse.
Nun bedeutet das für mich das eine Pizza jeweils zwei unterschiedlichen Bestellungen zugeordnet werden kann. Wenn ich also eine Pizza mit dem Namen "Salami" habe dann kann ich sie der Bestellung mit der ID=1 und der ID=2 hinzufügen. Z.B. möchte ich mittels Java-Code folgendes in die Datenbank mappen:
Code:
PIZZA_ID  name      ORDERS_FK
          
1         Salami        1
2         Thunfisch     1
3         Napoli        1
4         Salami        2
Sobald ich jedoch das gleiche Pizza-Objekt einer neuen Bestellung hinzufüge, wird der ORDER_FK dieses Objekts mit dem von der neuen Bestellung überschrieben. Beispielsweise ändert sich der Wert von ORDER_FK der Salami-Pizza mit ID=1 von 1 in 2. Das ganze sieht dann so aus:

Code:
PIZZA_ID  name      ORDERS_FK
          
1         Salami        2
2         Thunfisch     1
3         Napoli        1
Ich komme einfach nicht dahinter woran das liegen könnte. Brauche ich für ein korrektes Ergebnis eine Many-To-Many Relation? Hier ist mein Java-Code:

Java:
public class TestExample {
	final static Logger logger = LoggerFactory.getLogger(TestExample.class);

	public static void main(String[] args) {

		Transaction tx = null;
                Pizza salami = new Pizza();
		salami.setName("Salami");

                Pizza thunfisch = new Pizza();
		thunfisch.setName("Thunfisch");

                Pizza napoli = new Pizza();
                napoli.setName("Napoli");

                Order order = new Order();
		order.setCreationTime(new Date());
		order.setState(OrderState.NEW);
                order.addPizza(salami );
		order.addPizza(thunfisch );

                Order order2 = new Order();
		order.setCreationTime(new Date());
		order2.setState(OrderState.NEW);
                order.addPizza(napoli);
                order.addPizza(salami);

                Session session = SessionFactoryUtil.getInstance().getCurrentSession();
		try {
			tx = session.beginTransaction();
                        session.save(pizza);
			session.save(pizza2);
                        session.save(order);
			session.save(order2
                        tx.commit();
		} catch (RuntimeException e) {
			if (tx != null && tx.isActive()) {
				try {
					tx.rollback();
				} catch (HibernateException e1) {
					logger.debug("Error rolling back transaction");
				}
				throw e;
			}
		} finally {
			SessionFactoryUtil.getInstance().close();
		}
	}
}

Java:
@Entity
@Table(name = "pizza")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Pizza implements Cloneable, Serializable {

    private static final double BASE_PRICE = 3.0;

    private Integer id;

    private String name;

    private Order order;

   private List<Topping> toppings;

   public Pizza() {
        this.toppings = new ArrayList<Topping>();
    }

    public Pizza(Integer aPizzaId) {
        this();
        this.id = aPizzaId;
    }

    public Pizza(String aName, List<Topping> theToppings) {
        this.name = aName;
        this.toppings = theToppings;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "PIZZA_ID")
    public Integer getId() {
        return id;
    }

    public void setId(Integer anId) {
        this.id = anId;
    }

    /**
     * Der Name der Pizza.
     */
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @ManyToOne
    @JoinColumn(name = "ORDERS_FK")
    public Order getOrder() {
        return order;
    }

    public void setOrder(Order order) {
        this.order = order;
    }

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinTable(name = "pizza_topping", joinColumns = @JoinColumn(name = "PIZZA_FK"), inverseJoinColumns = @JoinColumn(name = "TOPPING_FK"))
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    public List<Topping> getToppings() {
        return toppings;
    }

    public void setToppings(List<Topping> toppings) {
        this.toppings = toppings;
    }

    public void addTopping(Topping topping) {
        this.toppings.add(topping);
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("[").append(super.toString());
        sb.append(", id: ").append(id);
        sb.append(", name: ").append(name);
        sb.append(", toppings: [");
        for (Topping top : toppings) {
            sb.append(top).append(",");
        }
        if (order != null) {
            sb.append(", order: ").append(order.getId()).append(", ")
                    .append(order.getState());
        } else {
            sb.append(", order: null");
        }
        sb.append("]]");

        return sb.toString();
    }

    @Override
    public Object clone() {
        return new Pizza(name, toppings);
    }

   @Transient
    public double getPrice() {
        double price = BASE_PRICE;
        for (Topping topping : toppings) {
            price += topping.getPrice();
        }
        return price;
    }

}

Java:
@Entity
@Table(name = "orders", uniqueConstraints = @UniqueConstraint(columnNames = {
        "CUSTOMER_FK", "CREATIONTIME" }))
@NamedNativeQuery(name = "orders.get_orders", query = "? = call orders.get_orders( ? )", resultClass = Order.class, callable = true)
public class Order implements Serializable {
    private Integer id;

    private Customer customer;

    private List<Pizza> pizzas = new ArrayList<Pizza>();

    /** eine neue Bestellung hat den Status NEW */
    private OrderState state = OrderState.NEW;

    private Date creationTime = new Date();

    public Order() {
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ORDER_ID")
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @ManyToOne(optional = true)
    @JoinColumn(name = "CUSTOMER_FK")
    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    @OneToMany(mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    public List<Pizza> getPizzas() {
        return pizzas;
    }

    public void setPizzas(List<Pizza> pizzas) {
        this.pizzas = pizzas;
    }

    @Enumerated(EnumType.STRING)
    public OrderState getState() {
        return state;
    }

    public void setState(OrderState aState) {
        this.state = aState;
    }

    @Transient
    public double getPrice() {
        double price = 0.0;
        for (Pizza pizza : pizzas) {
            price += pizza.getPrice();
        }
        return price;
    }

    public boolean addPizza(Pizza pizza) {
        if (state != OrderState.NEW) {
            return false;
        }
        pizzas.add(pizza);
        pizza.setOrder(this);
        return true;
    }

    public void removePizza(Pizza pizza) {
        pizzas.remove(pizza);
        pizza.setOrder(null);
    }

    @Temporal(TemporalType.TIMESTAMP)
    public Date getCreationTime() {
        return creationTime;
    }

    public void setCreationTime(Date creationTime) {
        this.creationTime = creationTime;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        final Order order = (Order) o;

        if (creationTime != null ? !creationTime
                .equals(order.creationTime)
                : order.creationTime != null) return false;
        if (customer != null ? !customer.equals(order.customer)
                : order.customer != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result;
        result = (customer != null ? customer.hashCode() : 0);
        result = 29
                * result
                + (creationTime != null ? creationTime.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return "id: " + id + ", state: " + state + ", pizzas: "
                + pizzas + ", customer: " + customer
                + ", creationTime: " + creationTime;
    }

    public boolean containsPizza(int aPizzaId) {
        for (Pizza pizza : this.pizzas) {
            if (pizza.getId() == aPizzaId) {
                return true;
            }
        }
        return false;
    }

    public boolean finishOrder() {
        boolean stateChangedOK = false;
        if (state == OrderState.NEW) {
            state = OrderState.OPEN;
            stateChangedOK = true;
        }
        return stateChangedOK;
    }

}
 
Zuletzt bearbeitet:

Cage Hunter

Aktives Mitglied
Also wenn man sich das so überlegt...ja, eine Many-to-Many-Relation wäre in Order angebracht...
Du hast zwar eigentlich nur mehrere Pizzen in Order, aber von Pizza aus gesehen gibt es mehrere Orders, denen eine Pizza zugeordnet ist :)
Ich hätte das mit dem FK weggelassen, das liest sich besser und Hibernate mapped das sowieso, von daher unnötig...meine Meinung jedenfalls

Wenn du's aber so lassen möchtest, dann bau doch einfach nen Counter in Pizza ein :)
Schon zwecks Redundanz wäre das wohl eine bessere Lösung, einfach ein Integer oder sowas, das hochgezählt wird, wenn 2 Salamis bestellt werden ;)
 

Studdi23

Mitglied
Hi. Danke erstmal für die Antwort. Ich denke ein Counter macht nur Sinn wenn ich eine Pizza zweimal oder mehr der gleichen Bestellung zuordnen will. Hatte auch schon darüber nachgedacht ein solches Attribut nachträglich einzufügen. Das erklärt aber nicht wieso ich einer zweiten Bestellung nicht die selbe Pizza übergeben kann. Wenn ich zwei unterschiedliche Kunden habe dann muss ich ja erstens wissen welche Pizzen zu seiner Bestellung gehören, was eine ORDER_FK zwingend notwendig macht und zweitens könnte dieser Kunde ja auch die gleiche Pizza bestellen, zunächst mal unabhängig von der Anzahl. Es sollte also theoretisch möglich sein bei einer N:1 Beziehung redundante Daten, in meinem Fall mehrere gleiche Pizza-Objekte, jeweils einer einzigen eindeutigen Bestellung zuzuordnen ohne auf eine Many-To-Many Beziehung zurückgreifen zu müssen oder etwa nicht? Kann auch sein das ich einen Denkfehler hab :)
 
G

Gast2

Gast
1. Dein TestExample stimmt ja hinten und vorne nicht ;) order2 wird nie etwas hinzugefügt...
2. gibts es pizza und pizza2 nicht...
3. Wenn du eine 1:N Beziehung hast musst auch die Salami Pizza 2mal anlegen. Sonst wird die alte Pizza einfach einer anderen Bestellung zugeordnet...

Also ich würde jedesmal ein neues PizzaObjekt machen, da in jeder Bestellung auch eine neue Pizza reinkommt, da bei Sonderwünschen ddas Objekt sich immer verändern kann. Pizzas sind ja keine Stammdaten wie Belage...
 

Studdi23

Mitglied
ja sorry, hab den code noch mal schnell auf dieser seite geändert um klarere variablennamen zu vergeben und dabei einige änderungen vergessen. selbstverständlich werden die pizzen der order hinzugefügt und das mappen in die datenbank funktioniert auch einwandfrei.


"Also ich würde jedesmal ein neues PizzaObjekt machen, da in jeder Bestellung auch eine neue Pizza reinkommt, da bei Sonderwünschen ddas Objekt sich immer verändern kann. Pizzas sind ja keine Stammdaten wie Belage... "

Auf die Idee bin ich ja auch gekommen, nur hätte ich gerne gewußt warum es nicht möglich ist die selbe Pizza für neue Bestellungen zu nutzen und stattdessen diese immer neu erstellen muss, ist nicht gerade elegant die Lösung. Ich weiß das man mittels der Methode "evict()" ein Hibernate-Objekt explizit von einer Session lösen kann damit dieses nicht mehr von Hibernate überwacht wird. Sollte es danach nicht möglich sein, das bereits erzeugte Objekt neu zu persistieren? Ein einfacher Aufruf dieser Methode hat allerdings nicht die gewünschte Wirkung erzielt. Wenn es nicht anders geht würde ich es dann doch noch mal mit einer "viele-zu-viele-Beziehung" probieren.
 
Zuletzt bearbeitet:
G

Gast2

Gast
Du du kannst die gleiche Pizza benutzen dann brauchst du aber eine m:n beziehung und dann wird eine extra Tabelle angelegt dann funktioniert das auch... bei einer 1:N Beziehung kann deine Pizza halt nur einmal in einer Bestellung vorkommen...

Und wenn du diese Ordnung willst musst du nunmal eine neue Pizza erstellen, da es auch ein neues Objekt ist, siehst du ja an der ID...

Code:
PIZZA_ID  name      ORDERS_FK
          
1         Salami        1
2         Thunfisch     1
3         Napoli        1
4         Salami        2
 

tuttle64

Bekanntes Mitglied
Du du kannst die gleiche Pizza benutzen dann brauchst du aber eine m:n beziehung und dann wird eine extra Tabelle angelegt dann funktioniert das auch... bei einer 1:N Beziehung kann deine Pizza halt nur einmal in einer Bestellung vorkommen...


solange der order als member in der pizza-klasse vorhanden ist, kommt Studdi23 um eine 1:N nicht drum herum. um das zu lösen, muss auch der order aus der pizza-klasse verschwinden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Oracle Hibernate M:N-Beziehung mit nur einer vorhandenen Tabelle Datenbankprogrammierung 5
turmaline H2 [Hibernate] @OneToOne-Beziehung Datenbankprogrammierung 5
M Hibernate - Welche Beziehung? Datenbankprogrammierung 3
S Hibernate - spezielle Frage, n zu n Beziehung Datenbankprogrammierung 11
R [Hibernate] 0..1 Beziehung mit XDoclet abbilden Datenbankprogrammierung 3
G Frage zu Hibernate und M:N Beziehung Datenbankprogrammierung 9
Y Hibernate - Mapping der Beziehung zwischen 2 Tabellen Datenbankprogrammierung 2
Y Hibernate - 1:1 Beziehung liefert leeres Objekt Datenbankprogrammierung 19
torresbig MySQL hibernate - could not resolve entity class ... (Datenbank Anfänger) Datenbankprogrammierung 19
I Hibernate Predicate mit IN Clause "Unaware how to convert value to requested type" Datenbankprogrammierung 0
T org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: ..., could not initialize proxy - no Session Datenbankprogrammierung 5
T Realisierungsvorschläge Hibernate SQL Datenbankprogrammierung 1
Zrebna Wie mittels Hibernate eine Join-Tabelle als eigene Java-Klasse erstellen? Datenbankprogrammierung 5
Zrebna Tabellen-Erzeugung via Hibernate ignoriert 'CascadeType' settings Datenbankprogrammierung 1
I Hibernate / JPA - Spaltenname von Query (Select) bekommen Datenbankprogrammierung 6
M Mysql Views und Hibernate Caching Datenbankprogrammierung 4
damike84 Hibernate: persistieren eines Graphen Datenbankprogrammierung 2
N Hibernate Entitäten bei Selects aus 2 Tabellen Datenbankprogrammierung 7
OnDemand Hibernate Realationen Datenbankprogrammierung 7
OnDemand Hibernate ManyToOne Datenbankprogrammierung 5
D Hibernate oneToMany Syntaxfehler Datenbankprogrammierung 3
D Hibernate Error: NoSuchMethodError Datenbankprogrammierung 4
D hibernate mit postgreSQL Datenbankprogrammierung 3
S MySQL Hibernate: Fehler bei Verwendung von 2 unterschiedlichen Enumration Datenbankprogrammierung 3
F Problem mit Hibernate c3p0 Datenbankprogrammierung 2
OnDemand MySQL Trigger löst nicht aus bei Hibernate Update Datenbankprogrammierung 12
OnDemand Hibernate OneToMany ManyToOne Datenbankprogrammierung 61
J Hibernate One-To-One mit Where Klausel Datenbankprogrammierung 6
L hibernate.cfg.xml Could not parse configuration Datenbankprogrammierung 0
L H2 Hibernate definieren? Datenbankprogrammierung 1
T JPA Mapping Enum (hibernate 5) Datenbankprogrammierung 1
H In hibernate.cfg.xml schreiben und auslesen Datenbankprogrammierung 0
K Hibernate: Ein Fluch Datenbankprogrammierung 3
K Java Object mit Hibernate in MySQL abspeichern Datenbankprogrammierung 1
K Eclipse: JBoss Hibernate Tool: Kein Zugriff auf Datenbank Datenbankprogrammierung 5
S JpaRepositories & Hibernate: ungewolltes trim() in findBy Datenbankprogrammierung 7
S MySQL hibernate exception: illegal state exception : entityManagerFactory is closed Datenbankprogrammierung 5
S Hibernate: Verschiedene Klassen zurückgeben. Datenbankprogrammierung 2
looparda Architektur für JPA Hibernate Umstieg Datenbankprogrammierung 14
O HSQLDB Hibernate Criteria Problem Datenbankprogrammierung 3
perlenfischer1984 Hibernate mit final members Datenbankprogrammierung 3
perlenfischer1984 Java Objecte speichern mit Hibernate ? Datenbankprogrammierung 2
N SQLite Hibernate und Aufruf von Funktion SELECT last_insert_rowid() Datenbankprogrammierung 2
N Sqlite3 und Hibernate Datenbankprogrammierung 3
A Hibernate Cache leeren Datenbankprogrammierung 4
I MySQL Hibernate zu viele Queries Datenbankprogrammierung 2
Psypsy Hibernate / JPA erkennen von schon gespeicherten Objekten Datenbankprogrammierung 4
Psypsy Hibernate / JPA OneToOne MappedBy Frage Datenbankprogrammierung 2
J Hibernate + DTOs - DTOs in DAOs verwenden? Datenbankprogrammierung 1
S Hibernate-Konfiguration : Unverständliche Ausgabe beim Ausführen Datenbankprogrammierung 0
I MySQL Hibernate / MySQL alias in WHERE clause Datenbankprogrammierung 1
J Hibernate + HSQL embedded Datenbankprogrammierung 2
P Hibernate Einstieg Datenbankprogrammierung 5
C Hibernate und createQuery Datenbankprogrammierung 2
V kennt jemand empfehlenswerte online tutorials zur Hibernate ? gerne auch englisch. Datenbankprogrammierung 4
G H2 Hibernate - wie joins machen Datenbankprogrammierung 1
D Hibernate: Zustand eines Objekts erkennen? Datenbankprogrammierung 0
D Unterschiede Hibernate Vs. Java Persistence API Datenbankprogrammierung 8
I Hibernate / JPA Index hinzufügen Datenbankprogrammierung 1
X Hibernate Cache Verständnisproblem Datenbankprogrammierung 0
T Hibernate und inner class Datenbankprogrammierung 0
K n:m Tabellen mit Hibernate erstellen Datenbankprogrammierung 1
T Hibernate DAO gute Tutorials/Bücher gesucht Datenbankprogrammierung 0
C Hibernate: could not resolve property Datenbankprogrammierung 1
J Plug-In-Framework für Hibernate-Klassen Datenbankprogrammierung 0
M Hibernate - Save Child wenn nötig Datenbankprogrammierung 10
M DAO's + Hibernate Theorie Datenbankprogrammierung 4
T Hibernate, HSQLDB und UNIQUE Datenbankprogrammierung 2
F Hibernate - verschiedene Schemen Datenbankprogrammierung 7
D Hibernate SaveOrUpdate Exception Datenbankprogrammierung 2
D Hibernate CreateQuery ohne Result Datenbankprogrammierung 7
E MySQL Hibernate mit JaxWS führt zu LazyInitialization Exception Datenbankprogrammierung 8
L Einarbeitung in Hibernate -> wenn gute SQL Kenntnisse vorhanden? Datenbankprogrammierung 2
B DB2 Hibernate findet Datenbank nicht Datenbankprogrammierung 18
K JPA / Hibernate Annotations Datenbankprogrammierung 4
M JPA / Hibernate mit Postgres DB Datenbankprogrammierung 3
P JSF + H2 + TomEE + Hibernate/JPA Datenbank wird nicht angelegt Datenbankprogrammierung 3
E MySQL Hibernate ( Anfänger ) Datenbankprogrammierung 3
P Lazy-Fetchig und Session-Problem mit Hibernate Datenbankprogrammierung 4
J Hibernate Select auf Parameterliste Datenbankprogrammierung 3
C Hibernate ManyToMany zusammengesetzter Primärschlüssel, problem. Datenbankprogrammierung 3
P Oracle Hibernate - Oracle-VarChar-Index wird nicht genutzt Datenbankprogrammierung 3
M Hibernate Foreign Key definieren Datenbankprogrammierung 4
M Abstrakte Klassen Hibernate Datenbankprogrammierung 4
D Mit Hibernate (mit Annotation) auf Views zugreifen Datenbankprogrammierung 2
M [Hibernate]Abgleich eines lokalen Objekts mit dem Zustand aus der Datenbank. Datenbankprogrammierung 3
P Mit Hibernate mehrere Datensätze löschen Datenbankprogrammierung 7
P Probleme mit meinem 1. Hibernate Beispiel Datenbankprogrammierung 3
P erste Schritte mit Hibernate Datenbankprogrammierung 3
V Hibernate Interfaces von anderem Projekt Datenbankprogrammierung 2
J MySQL Datenbank konfigurieren, JDBC, MySQL oder Hibernate Datenbankprogrammierung 2
B Hibernate und portierbare Datenbank Datenbankprogrammierung 3
qwerqer [Hibernate] Mappingvarianten Datenbankprogrammierung 2
lumo Teneo Hibernate & JPA Datenbankprogrammierung 15
Z JPA mit Hibernate - Unable to build EntityManagerFactory Datenbankprogrammierung 7
Dit_ Hibernate, effiziente SQL-Abfrage definieren Datenbankprogrammierung 5
K Hibernate vs. JDBC Datenbankprogrammierung 4
J Hibernate Info 593 ? Datenbankprogrammierung 4
J Erstellen der SessionFactory in Hibernate 4.1 Datenbankprogrammierung 2
L PostgreSQL Hibernate-Frage Datenbankprogrammierung 2

Ähnliche Java Themen

Neue Themen


Oben