Greetings... haven't posted in a while, but this is an interesting problem for which I cannot find an answer. Essentially, the problem is this: I have a class with multiple collections in it. All the collections are marked as cascade=save-update - and for the most part this has worked very consistently on the first save. However, one of the three collections loses it's link back to the main table on subsequent saves. The best way I can describe is this - I have an orders table with a link table of order-items. These relate back via an order id. On the first save the order id of an order-item matches the id of it's original order. On the second save, the order id in order-item is set to zero. Now... the main object can still be tested for the presence of this linked data. It is still there... but hibernate no longer connects the dots.
Thoughts? I'm going to upgrade to the latest GA - I'm running 3.2.1 at the moment.
Hibernate version: 3.2.1
Mapping documents:
hibernate-mapping>
<class name="com.declivis.pos.dao.Order" table="orders">
<id name="id" type="long">
<column name="id" />
<generator class="identity" />
</id>
<property name="status" type="int">
<column name="status" length="4" not-null="true" />
</property>
<property name="orderId" type="string">
<column name="order_id" length="20" not-null="true"
index="IDX_ORDERS_OID" />
</property>
<property name="orderDate" type="java.util.Date">
<column name="order_date" sql-type="timestamp" />
</property>
<property name="orderPostedDate" type="java.util.Date">
<column name="order_posted_date" sql-type="timestamp" />
</property>
<set name="items" table="order_items"
cascade="save-update" lazy="false">
<key column="order_id" />
<one-to-many class="com.declivis.pos.dao.OrderItem" />
</set>
<list name="paymentDetails" table="order_payments" lazy="true"
cascade="save-update">
<key column="order_id" />
<list-index column="sort_order" base="1" />
<many-to-many column="payment_id"
class="com.declivis.pos.dao.OrderPaymentDetail" not-found="ignore" />
</list>
<list name="fulfillmentDetails" table="order_fulfillments"
lazy="true" cascade="save-update">
<key column="order_id" />
<list-index column="sort_order" base="1" />
<many-to-many column="fulfillment_id"
class="com.declivis.pos.dao.OrderFulfillmentDetail"
not-found="ignore" />
</list>
<property name="createdDate" type="java.util.Date">
<column name="created_date" sql-type="timestamp"
not-null="true" />
</property>
<property name="modifiedDate" type="java.util.Date">
<column name="modified_date" sql-type="timestamp"
not-null="true" />
</property>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
This has extra logging to watch the bad news go by - the order-items are always there.
private boolean saveOrUpdateOrder(Order order) throws ServletException {
// save the order
long l = order.getId();
if (order.getItems() == null)
log.debug("Bummer man");
else
log.debug("Has items: " + order.getItems().size());
boolean result = false;
Session ds = null;
Transaction tx = null;
SessionFactory sf = getSessionFactory();
order.setModifiedDate(new Date());
try {
ds = sf.openSession();
tx = ds.beginTransaction();
if (l == 0)
ds.save(order);
else
ds.update(order);
tx.commit();
result = true;
if (l == 0)
txlog.info("UPDATE: Order " + order.getId() + " saved");
else
txlog.info("UPDATE: Order " + order.getId() + " updated");
} catch (HibernateException he) {
log.warn(he.getMessage());
if (tx != null)
tx.rollback();
} finally {
if (ds != null)
ds.close();
}
return result;
}
Full stack trace of any exception that occurs: No exceptions
Name and version of the database you are using: MySQL 5.0.27 MAX
The generated SQL (show_sql=true):
Debug level Hibernate log excerpt: I haven't done this yet, but that is next after the version upgrade
|