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:
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:
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:
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
Code:
PIZZA_ID name ORDERS_FK
1 Salami 2
2 Thunfisch 1
3 Napoli 1
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: