Lets setup the question first.
What I have is >4 tables: Customer, Address, Order, OrderItems. Each are mapped using Hibernate Annotations and accessed through a Spring DAO/Services layer.
What I am trying to do is merge duplicate customers together. So all that really needs to happen is all orders and addresses associated with customer B, need to update their customer_id foreign key to point to customer A. Then customer B must have its disabled bit set.
Instead of sending these simple queries to our database, hibernate goes crazy and issues a ton of select then update queries. Particularly it selects all order items attached to an order (because this is defined EAGER
, and this point is not changeable.). To get the selects before update to stop happening I tried adding the hibernate entity annotation on top of the regular javax.persistence.Entity
like:
@org.hibernate.annotations.Entity(dynamicUpdate = true, selectBeforeUpdate = false, dynamicInsert = true)
this seemed to have no affect, except with simple queries where it only updated single items in a table.
I get the objects using the following hibernate criteria:
Criteria c1 = null;
Criteria c2 = null;
Criteria c = session.createCriteria(Customer.class);
c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
if(resultLimit>0) c.setMaxResults(resultLimit);
if(timeout>0) c.setTimeout(timeout);
for(String filter: sqlFilters) {
if(filter.indexOf("{alias}.customer_")!=-1) c.add(Restrictions.sqlRestriction(filter));
else if(filter.indexOf("{alias}.address_")!=-1 && addrsAttached) {
if(c1==null)
c1 = c.createCriteria("addresses").setFetchMode("type", FetchMode.JOIN);
c1.add(Restrictions.sqlRestriction(filter));
} else if(filter.indexOf("{alias}.order_")!=-1 && ordersAttached) {
if(c2==null)
c2 = c.createCriteria("orders").setFetchMode("orderItems", FetchMode.SELECT);
c2.add(Restrictions.sqlRestriction(filter));
}
}
return (List<Customer>) c.list();
Then i move all of the address and order objects from customer B to customer A and run a
return (Customer) this.getHibernateTemplate().merge(customer);
on both customer objects. This ends up creating a ton of select statements that get all of the associated objects (i.e. OrderItems, Products, ProductType, ProductPricingTmpl, etc..)
I need to get these selects removed! If they were not there the query would look normal and be efficient! The Update outputted queries are perfect and dynamic.
Any ideas?