Obtendo Hibernate fazer atualizações simples, em vez de enormes selecione atualizações, em seguida,

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

Pergunta

Permite configurar a primeira pergunta.

O que eu tenho é> 4 mesas: Cliente, Endereço, Ordem, OrderItems. Cada são mapeados utilizando hibernação Anotações e acedido através de uma camada de Primavera DAO / Serviços.

O que estou tentando fazer é mesclar clientes duplicados juntos. Então, tudo o que realmente precisa acontecer é todos os pedidos e os endereços associados com o cliente B, necessidade de atualizar sua customer_id chave estrangeira para ponto para o cliente A. Em seguida, cliente B deve ter o seu conjunto de bits desativado.

Em vez de enviar essas consultas simples para nosso banco de dados de hibernação vai e questões loucas uma tonelada de consultas seleção de atualização em seguida. Particularmente selecciona todos os itens do pedido ligados a uma ordem (porque este é definido EAGER, e neste ponto não é variável.). Para obter os seleciona antes de atualização para parar acontecendo Eu tentei adicionar a anotação entidade de hibernação no topo do javax.persistence.Entity regular como:

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

este parecia ter nenhum efeito, exceto com consultas simples onde só atualizados itens únicos em uma tabela.

Eu obter os objetos usando os seguintes critérios de hibernação:

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

Então eu mover todos os endereços e pedir objetos de cliente B para o cliente A e executar um

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

em ambos os objetos dos clientes. Isso acaba criando uma tonelada de instruções select que obter todos os objetos associados (ou seja OrderItems, produtos, ProductType, ProductPricingTmpl, etc ..)

eu preciso para obter estes seleciona removido! Se eles não estavam lá a consulta seria normal e ser eficiente! A Atualização emitido consultas são perfeitos e dinâmica.

Todas as idéias?

Foi útil?

Solução

A pista pode estar em sua escolha de operação merge (). Do javadoc Hibernate:

Copie o estado do objeto dado para o objecto com o persistente mesmo identificador. Se não há instância persistente atualmente associada com a sessão, será ser carregado.

Então você está forçando o Hibernate para carregar todos os dados antes de modificá-lo.

Tente uma operação diferente, como update ():

Atualize a instância persistente com o identificador de um dado individual exemplo.

Sem promessas, no entanto, o Hibernate pode decidir que precisa carregá-lo de qualquer maneira. O dynamicUpdates = true configuração pode realmente piorar a situação, já que ele precisa saber o que está lá para começar antes que possa emitir atualizações dinâmicas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top