Pergunta

Basicamente, eu quero uma maneira de valores seqüência de acesso de uma forma de banco de dados neutro. O caso de uso é que eu tenho um campo em uma entidade que pretende definir com base em um valor de incremento (diferente do id).

Por exemplo, digamos que eu tenho uma entidade Shipment. Em algum momento após a expedição é criado, ele é enviado. Uma vez que ele é enviado, um número manifesto é gerado por ele e atribuído. O número manifesto é algo como M000009 (Onde o material após o 'M' é um valor deixado acolchoado a partir de uma seqüência).

Algo semelhante foi perguntado aqui no SO , mas eu não sou um fã da solução uma vez que exige uma outra tabela para manter e parece ser um relacionamento estranho ter.

Alguém sabe se é possível usar algo como MultipleHiLoPerTableGenerator de hibernação como algo diferente de um gerador de ID?

Se isso não for possível, alguém sabe de quaisquer bibliotecas que lidar com isso (usando hibernate ou mesmo apenas puro JDBC). Eu prefiro não ter que escrever isso mesmo (e tem que lidar com prefetching valores, bloqueio e sincronização).

Graças.

Foi útil?

Solução

Eu acho que a complexidade da sua tarefa depende se ou não se manifestam necessidades numéricas para ser sequenciais:

  • Se você não precisa de números de manifesto sequenciais então é dias felizes e pode usar uma seqüência.
  • Se você precisa de números de manifesto sequenciais (ou seu banco de dados não suporta seqüências), em seguida, usar uma tabela id com o bloqueio apropriado, de modo que cada transação obtém um valor seqüencial único.

Em seguida, você tem 2 opções que eu posso pensar de:

  • escrever o código JDBC necessárias sobre o seu cliente, garantindo (se o número manifesto é seqüencial) que a transação a ser utilizado é o mesmo que para a atualização do banco de dados.
  • usar um gatilho para criar o número manifesta quando a atualização apropriada ocorre.

Eu acho que a minha preferência seria o gatilho porque o lado da transação de coisas seria tomado cuidado de, embora isso significaria o objeto seria necessário refrescante no cliente.

Outras dicas

Eu não li sobre a solução semelhante ligada, mas soa como algo que acabei fazendo. Eu criei uma tabela apenas para seqüências. I adicionou-se uma linha para a tabela para cada tipo de sequência I necessário.

Então eu tive uma classe gerador de sequência que faria a consulta SQL necessário para buscar e atualizar o valor de seqüência para uma determinada seqüência nomeada.

Eu usei classe Dialect de hibernação para fazê-lo de uma forma neutra db.

Também gostaria de 'Cache' as sequências. Eu iria colidir o valor da seqüência armazenada por um grande número, e, em seguida, distribuir os para fora essas sequências alocados de minha sala do gerador. Se a classe foi destruído (isto é. App desligamento), uma nova instância do gerador de sequência de arranque se no valor armazenado. (Que tem uma lacuna nas minhas números de sequência não importa)

Aqui está uma samnple código. Gostaria de Advertência este com - Eu não comiled isso e reuires código de primavera. Dito isso, ele ainda deve fornecer os ossos do que você quer fazer.

public Long getManifestNumber() {
        final Object result = getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session sess) throws HibernateException, SQLException { 
                SQLQuery sqlQuery = sess.createSQLQuery("select MY_SEQUENCE.NEXTVAL from dual");
                sqlQuery.uniqueResult();
            }
        });
        Long toReturn;
        if (result instanceof BigDecimal) {
            toReturn = ((BigDecimal)result).longValue();
        }
        return toReturn;
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top