开发者

Only one of "create" or "delete", in parent child association, works at a time

I am trying to implement parent child relation on traditional Order and Items tables. For this I am using uni-directional one-to-many association but I can make either "save" operation work or the "delete", one at a time.

If I set inverse="false" I can create new order (with items) but can't Delete it because hibernate tries to delete order record first and it fails due to reference in Items table

On the other hand, if I set inverse="true" then Order can be deleted but not created as it tries to create OrderItems record first that fails due to missing reference in Order table (orderId is not null in Items table)

Bi-directional association is also a pain because it leads to circularities in object graphs. Can anyone suggest me a solution?

My hibernate mapping is:

  <class name="Order" table="ORDERS">
    <id column="ID" name="id" type="long">
      <generator class="native" />
    </id>
    <property name="orderDate" type="timestamp" />
    <property name="customer" type="string" />
    <set cascade="all-delete-orphan" name="items" inverse="true" lazy="true">
      <key column="orderId" not-null="true" />
      <one-to-many class="OrderItem" />
    </set>
  </class>

  <class name="Item" table="Items">
    <id column="id" name="itemId" type="long">
      <generator class="native" />
    </id>
    <property name="product" type="string" />
    <property name="quantity" type="int" />
  </class>

Order.java is:

public class Order implements java.io.Serializable {
    private Long id;
    private Date orderDate;
    private String customer;

    private Set<Item> items;

    public Long getId() {
        return id;
    }

    public Date getInvDate() {
        return invDate;
    }

    public String getCustomer() {
        return customerId;
    }

    public Set<Item> getItems() {
        return items;
    }

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

    public void setOrderDate(Date orderDate) {
        this.orderDate= orderDate;
    }

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

    public void setItems(Set<Item> items) {
        this.items = items;
    }
}

Item.java

public class Item implements java.io.Serializable {
    private Long itemId;
    private String product;
    private int quantity;

    public Long getItemId() {
        return itemId;
    }

    public String getProduct() {
        return product;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setItemId(Long itemId) {
        this.itemId = itemId;
    }

    public void setProduct(String productId) {
        this.product = product;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }
}

OrderManager.java

public class OrderManagerBase {

    public Long save(Order theOrder) throws RemoteException {
        Session session = HbmUtils.getSessionFactory().getCurrentSession();
        Transaction tx = null;
        Long orderId = null;
        try {
            tx = session.beginTransaction(开发者_StackOverflow中文版);
            session.persist(theOrder);
            tx.commit();
            orderId = theOrder.getId();
        } catch (RuntimeException e) {
            if (tx!=null) 
                tx.rollback();
            throw new RemoteException("Order could not be saved");
        }finally{
            if (session.isOpen())
                session.close();
        }
        return orderId;
    }

    public Long delete(Order order) throws RemoteException {
        Session session = HbmUtils.getSessionFactory().getCurrentSession();
        Transaction tx = null;
        Long orderId = order.getId();
        try {
            tx = session.beginTransaction();
            session.delete(order);
            tx.commit();
        } catch (RuntimeException e) {
            tx.rollback();
            orderId = null;
        }finally{
            if (session.isOpen())
                session.close();
        }
        return orderId;
    }

    public Order getOrder(long cid) throws RemoteException {
        Session session = HbmUtils.getSessionFactory().getCurrentSession();
        Transaction tx = null;
        Order theOrder = null;
        try {
            tx = session.beginTransaction();
            Query q = session.createQuery("from Order as order " +
                    "left outer join fetch order.items " +
                    "where order.id = :id").setReadOnly(true);
            q.setParameter("id", cid);
            theOrder = (Order) q.uniqueResult();
            tx.commit();
        } catch (RuntimeException e) {
            if (tx!=null) 
                tx.rollback();
            e.printStackTrace();
        }finally{
            if (session.isOpen())
                session.close();
        }
        return theOrder;
    }
}

Table are:

CREATE TABLE  Orders (
  id bigint(20) NOT NULL AUTO_INCREMENT,
  orderDate datetime DEFAULT NULL,
  PRIMARY KEY (id),
)

CREATE TABLE  Items (
  id bigint(20) NOT NULL AUTO_INCREMENT,
  orderId` bigint(20) NOT NULL,
  product varchar(50) DEFAULT NULL,
  quantity bigint(20) DEFAULT NULL,
  PRIMARY KEY (id),
  CONSTRAINT FK_orderitems_1 FOREIGN KEY (orderId) REFERENCES Orderss (id)
)


on parent Order:

<set name="items" access="field" inverse="true" cascade="all" order-by="id">
    <key column="parent_order_id" />
    <one-to-many class="com.example.Item" />
</set>

void addItem(Item item) {
    items.add(item);
    item.setParent(this);
}

on child Item:

<many-to-one name="parent" not-null="true" column="orderId" foreign-key="FK_order_to_item" />

private Order parent;

void setParent(Order order) {
    this.parent = order;
}

Add items via Order#addItem(Item). Item manages relation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜