Como criar sequence usando JPA em tempo de execução?

7 respostas
lindberg713

Pessoal, já pesquisei em tudo quanto é canto e venho recorrer aqui pra ver se alguém pode ajudar.

Como faço, se possível, para criar uma sequence em tempo de execução com JPA? Exemplo, digamos que por algum motivo eu precise de uma sequence para cada pessoa cadastra. Então, no momento do insert de pessoa eu preciso também criar a sequence seq_pessoa_<id_da_pessoa>. Como é uma sequence única para cada pessoa, então eu tenho que criar a mesma em tempo de execução.

Alguem sabe como fazer isso usando a API da JPA? Se não encontrar a solução, terei que fazer usando SQL nativo, o que não é uma boa abordagem e não é assim que quero fazer, já que uso JPA.

Obrigado.

7 Respostas

rogelgarcia

Só de estar querendo um sequence, você já está “invalidando” a interface do JPA pois não é todo banco que trabalha com sequence.

Em todo caso, o propósito do JPA é mapear objetos em dados relacionais, e não ser uma interface para contadores.

Não está errado em usar JDBC nativo. Principalmente nesse caso, onde o JPA não oferece suporte.

MAS ainda fica a pergunta, o que você está querendo fazer? Que precisa de um sequence para cada usuário?

Você poderia resolver com uma trigger no banco de dados, por exemplo.

L

da pra vc colocar na classe
@GeneratedValue(strategy=GenerationType.IDENTITY)
mas ela tem que ter um sequence ja no banco.

se isso ajuda em algo

lindberg713

Eu sei que usar sequence da forma como estou precisando já inválida o propósito da JPA, pois nem todo banco tem esse recurso. Sei claramente disso. Mas para o problema que temos aqui é justamente isso que precisamos, seja com JPA ou via trigger no banco (como também to pensando em fazer).

Com relação ao que o “luuucass” falou, não é isso que estou querendo. Usar o @GeneratedValue não é o que estou querendo, pois esta estrategia serve bem quando temos a sequence já cadastrada no banco e quando sempre o campo vai usar a mesma sequence, como por exemplo, primary key.

Vocês devem ta achando estranho o fato de criar uma sequence para cada usuário. Mas não é bem assim. O problema é o seguinte.

Vou da um exemplo simples. Imagine que temos uma classe Pessoa e uma classe, digamos, Pedido. Pedido esta relacionado com Pessoa. Só que temos um campo, que não é o ID, em Pedido que é sequencial e deve ser incremental iniciando de 1 e indo 2,3,4… para cada pessoa. Então cada Pessoa tem seus pedidos e seus pedidos tem o valor desse atributo incremental inicando de 1 até… n . Dessa forma, quando criarmos uma pessoa, preciso criar uma sequence para esse atributo também, relacionado com esta Pessoa como SEQ_NUM_REFERENCIA_PEDIDO_<ID_PESSOA>. Então, quando for incluir um pedido no banco a sequence especifica desse atributo para esta pessoa, será usada para setar o valor desse atributo.

Por isso que tenho que criar a sequence em tempo de execução.

Sei que não é algo trivial, sei que não é comum, nem julgo a melhor forma de se fazer. Inclusive, poderia até fazer um count no número de pedidos da pessoa e incrementar 1 no valor do atributo. Mas aí é que ta, nosso projeto tem uma alta concorrência e não posso contar que o count de registro no banco naquele momento vai ser o real no momento da real persistencia do registro.

Sei que isso não é comum e foge do padrão normal mas isso é um requisito que temos aqui e assim é que deve ser feito. A forma como será feita é que quero ver a melhor abordagem.

Fazer a trigger no banco também pensei nisso e estou avaliando isso. O que eu queria saber, é se a API da JPA me provê alguma algum recurso para isso.

Obrigado.

rogelgarcia

Huummm… entendi.

Bem, a solução do sequence é realmente interessante. Uma pergunta: os registros de pedidos tem que ser 1, 2, 3, 4, 5? Obrigatoriamente em sequencia? Ou podem ser falhados, exemplo: 1, 2, 4, 5. Porque se obrigatoriamente tem que ser em sequencia, se você pedir o sequence e na hora de inserir o pedido acontecesse alguma exceção, como por exemplo um campo que é obrigatório está com valor null, você “perderá” o sequence criada.

Eu acho que o controle via trigger é mais simples do que pela aplicação.

L

vc vai armazenar onde ?

da pra armazenar em um arquivo

mas dai vai ficar maior gambiarra. se alguem deletar ou alterar o arquivo ferrou dai.

L

JPA desconheço

A

Conforme explicado pelo rogelgarcia, se você utilizar uma Sequence, não há garantias de que os pedidos sairão em ordem sem “pulos”.

Se você precisa garantir uma ordem, sugiro que crie uma entidade para gerar o sequencial por pessoa.
Daí manipulando essa entidade, você teria controle transacional, que impediria os “pulos”.

Mas se ter esses “pulos” não tem problema, você pode usar logo uma sequence única para todas as pessoas.

Criado 29 de fevereiro de 2012
Ultima resposta 1 de mar. de 2012
Respostas 7
Participantes 4