Получение Hibernate для простых обновлений, вместо огромного выбора, а затем обновлений

StackOverflow https://stackoverflow.com/questions/1009504

Вопрос

Давайте сначала зададим вопрос.

У меня есть > 4 таблицы: Customer, Address, Order, OrderItems. Каждый из них сопоставлен с использованием аннотаций Hibernate и доступен через уровень Spring DAO / Services.

Я пытаюсь объединить дублирующих клиентов. Таким образом, все, что действительно должно произойти, - это все заказы и адреса, связанные с клиентом B, необходимо обновить его внешний ключ customer_id, чтобы он указывал на клиента A. Тогда для клиента B должен быть установлен бит отключения.

Вместо того, чтобы отправлять эти простые запросы в нашу базу данных, hibernate сходит с ума и выдает тонну запросов на выбор, а затем обновляет. В частности, он выбирает все позиции заказа, прикрепленные к заказу (потому что это определено EAGER , и эта точка не подлежит изменению.). Чтобы получить выборки перед обновлением, чтобы перестать происходить, я попытался добавить аннотацию объекта гибернации поверх обычной javax.persistence.Entity , например:

@org.hibernate.annotations.Entity(dynamicUpdate = true, selectBeforeUpdate = false, dynamicInsert = true)

это, похоже, никак не сказалось, за исключением простых запросов, в которых обновлялись только отдельные элементы таблицы.

Я получаю объекты, используя следующие критерии гибернации:

            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();

Затем я перемещаю все объекты адреса и заказа от клиента B к клиенту A и запускаю

return (Customer) this.getHibernateTemplate().merge(customer);

на обоих объектах заказчика. В результате создается тонна операторов выбора, которые получают все связанные объекты (например, OrderItems, Products, ProductType, ProductPricingTmpl и т. Д.)

Мне нужно удалить эти выборки! Если бы их не было, запрос выглядел бы нормально и был бы эффективным! Обновленные выходные запросы являются совершенными и динамичными.

Есть идеи?

Это было полезно?

Решение

Подсказка может заключаться в выборе операции слияния (). Из спящего Javadoc:

  

Скопируйте состояние данного объекта   на постоянный объект с   тот же идентификатор. Если нет   постоянный экземпляр в настоящее время   связанный с сеансом, он будет   быть загруженным.

Таким образом, вы заставляете Hibernate загружать все данные перед их изменением.

Попробуйте другую операцию, например update ():

  

Обновите постоянный экземпляр с помощью   идентификатор данного отдельного объекта   экземпляр.

Однако никаких обещаний Hibernate может решить, что ему все равно нужно его загрузить. Конфигурация dynamicUpdates = true на самом деле может ухудшить ситуацию, поскольку она должна знать, с чего начать, прежде чем сможет выпускать динамические обновления.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top