JPA+Hibernate

32 views
Skip to first unread message

Nuno Lima

unread,
Nov 10, 2009, 3:51:03 PM11/10/09
to ptjug-geral
Viva.

Decidi dar uma chance à "persistência" (mais uma vez, desta vez mais a
sério) e alterar um projecto onde já estava a tirar partido das
annotations do JPA.

Depois de acrescentar mais umas quantas annotations as entidades
(POJO's) necessárias, incluir o jar do hibernate e de criar a PU
(Persistence Unit), foi "só" começar a usar EntityManager's para
persiste, commit, flush, merge, etc...

Todos estes "testes" num projecto de trazer por casa, só mesmo para
ver as dificuldades e problemas de implementação encontrados ... e ai
estão eles ... ou melhor ele (The One) ... um que acho que ou é
burrisse minha (e de mais uns quantos internautas, metidos a
developer) ou então é mesmo um daqueles problemas que "vai sair na
próxima versão do JPA".

Trata-se de ... Como tratar as Constraints da B.Dados? mais
propriamente grupos UNIQUE de campos, ou campos simples UNIQUE.

A primeira dificuldade foi passar a usar o flush, em vez do commit
quando de uma nova inserção (sem ter que ir carregar todos os dados
antes) ... problema nr. 1 resolvido. Passemos ao próximo ...

Quando 1 campo/membro da entidade tem um valor que já existe na
B.Dados, algo se vai passar quando do flush, é lançada uma exception,
neste caso do JPA (EntityExistsException), que por sua vez "embrulha"
uma outra do Hibernate (ConstraintViolationException), que se pode
"apanhar" com um ex.getCause().

Mas isto tudo para quê? Deu erro acabou, morreu tudo ... não nada
disso, a ideia é mesmo tentar saber qual dos campos (neste caso
UNIQUE) que originou o erro, mas não vejo jeitos ...

Depois de apanhar a ConstraintViolationException, este tem um método
e.getConstraintName() que era um "espectáculo" se realmente funciona-
se, mas não, só retorna mesmo um frio e desgostoso null (parece que se
o SGBD fosse oracle já dava - ouvi dizer).


Pois amigos, ou é de mim (espero que seja mesmo), ou isto da
Persistence, é mais fogo de vista que outra coisa, pois se depois de
tanta "etiqueta" (annotation) e de tanta configuração, não se tira
partido de um simples controlo (prévio ou não) daquilo que se vai
inserir na B.Dados, para quê perder tempo?

Já vi também que no projecto Hibernate, existe um package Validation,
e no projecto OpenJPA que também falam de validação, dizendo até que
seguem o que será implementado quando sair o JPA 2.0 ... será que
alguma destas "coisas" ajuda a resolver o problema das Constraint's
UNIQUE ( e outras) e sendo assim, não seria que a presistência
(JPA1.0) não devia já tratar das validações que as annotations
descrevem?

Agradeço desde já as vossas opiniões e ideias sobre este assunto, a
ver se eu não dou todo este tempo a volta da Persistência novamente
como perdido.

Abraço a todos.
Nuno Lima

Nuno Lima

unread,
Nov 11, 2009, 7:48:47 PM11/11/09
to ptjug-geral
Viva.

Parece que a lista está pouco activa - infelizmente - ou ninguém gosta
destes 2 "flavors" (hibernate+jpa) juntos ;)

De qualquer forma, como "quem quer belota, trepa", não fiquei parado e
entre outras informações que fui encontrando sobre este assunto,
deparei-me com um excelente artigo, muito bem escrito e que explica
toda esta problemática dos "uniques" e da persistência (afinal eu não
era o UNIQUE'o com este problema).

Aqui fica o link, para os interessados, espero que ajude quem se
deparar com o mesmo problema.

http://www.lunatech-research.com/archives/2008/05/09/bean-validation-java-ee

Pena é não ter havido "bitaistes" do grupo até agora ... vamos lá
malta!

Abraço.
Nuno Lima

Samuel Santos

unread,
Nov 11, 2009, 9:58:35 PM11/11/09
to ptjug...@googlegroups.com
Viva Nuno,

Estás a usar o atributo unique na @Column (e.g. @Column(unique=true, nullable=false))?

Eu tenho por princípio tentar usar só JPA (javax) sem nada específico do Hibernate e gerar a BD a partir das entidades e não o contrário. E raramente me deparo com problemas como tantas vezes aparecem nesta lista.

Se chegares a alguma solução para esse problema informa também a malta ;)

Cumps,

--
Samuel Santos
http://www.samaxes.com/


2009/11/12 Nuno Lima <nunojo...@gmail.com>

Nuno Lima

unread,
Nov 12, 2009, 7:57:12 AM11/12/09
to ptjug-geral
Viva.

Mantendo a "coisa" genérica (sem sair do standard JPA) em termos de
atributos até estamos bem servidos ...

Para grupos de campos unique (campos relacionados):

@Table(
name="EMPLOYEE",
uniqueConstraints=
@UniqueConstraint(columnNames={"EMP_ID", "EMP_NAME"})
)

Para campos unique simples:

@Column(unique=true, nullable=false)

O problema mesmo é o "motor" da persistência depois tirar partido de
qualquer uma destas annotations, o que (pelo menos para já) está
apenas a ser feita para gerar/criar as tabelas na b.dados (O->R).

No entanto, já "desenhei" uma proposta para tentar solucionar o
problema de uma forma o mais genérica possível e com o código mais
"limpo" possível.
Já agora, fica aqui a minha ideia (ainda em esboço):

class ErroUnique {
boolean ok = true;
String superEntityName, errorEntityName, constraintErrorName;//
singleFieldName, groupFieldsName
(...)
}

ErroUnique validaEntidades(Entity ent){
//Ver quais os campos unique em @Table de ent
//Ver quais os campos unique simples de ent
//Ver as subentidades (que tenham annotations tipo: @ManytoOne,
@OneToMany, etc para verificar se as subentidades também tem campos
unique
//Chamar recursivamente este método para cada uma das sub-entidades
(ent.aninhadas)
//Consultar a BDados para ver se já existem estes dados inseridos
nos campos assinalados como unique
//return ErroUnique
}

Esta classe será uma EntityListener para depois podermos inclui-la nas
entidades com a annotation @EntityListeners
(class=ValidaUniques.class), sendo que o método validaEntidades(Entity
ent) seria anotado com @PrePersist para ser chamado de forma
"automática" a cada em.persist() ... tudo JPA.

Agora só falta implementar e analisar "buracos" que não esteja a ver
de momento.

Aceitam-se ideias, correcções e criticas ;)
Abraço.
Nuno Lima



On 12 Nov, 02:58, Samuel Santos <sama...@gmail.com> wrote:
> Viva Nuno,
>
> Estás a usar o atributo unique na @Column (e.g.
> @Column(unique=true, nullable=false))?
>
> Eu tenho por princípio tentar usar só JPA (javax) sem nada específico do
> Hibernate e gerar a BD a partir das entidades e não o contrário. E raramente
> me deparo com problemas como tantas vezes aparecem nesta lista.
>
> Se chegares a alguma solução para esse problema informa também a malta ;)
>
> Cumps,
>
> --
> Samuel Santoshttp://www.samaxes.com/
>
> 2009/11/12 Nuno Lima <nunojorgel...@gmail.com>
>
>
>
>
>
> > Viva.
>
> > Parece que a lista está pouco activa - infelizmente - ou ninguém gosta
> > destes 2 "flavors" (hibernate+jpa) juntos ;)
>
> > De qualquer forma, como "quem quer belota, trepa", não fiquei parado e
> > entre outras informações que fui encontrando sobre este assunto,
> > deparei-me com um excelente artigo, muito bem escrito e que explica
> > toda esta problemática dos "uniques" e da persistência (afinal eu não
> > era o UNIQUE'o com este problema).
>
> > Aqui fica o link, para os interessados, espero que ajude quem se
> > deparar com o mesmo problema.
>
> >http://www.lunatech-research.com/archives/2008/05/09/bean-validation-...
Reply all
Reply to author
Forward
0 new messages