Mapeamentos JPA

De BIS Wiki
Ir para navegação Ir para pesquisar

A camada de persistência do BIS é atualmente desenvolvida com base no JPA e uma estrutura própria do BISCore que simplifica a criação de DAOs. A implementação JPA utilizada atualmente é a nativa do Glassfish: a EclipseLink.

Esta página tem o objetivo de exemplificar os diferentes tipos de mapeamentos entre objetos e tipos diferentes de campos para servir como guia rápido de consulta para os desenvolvedores.

Mapeamento de Atributos

Desde que a entidade (VO) esteja definida como @Entity o JPA tentará mapear automaticamente qualquer atributo da entidade no banco de dados. O JPA consegue mapear sozinho os atributos mais comuns como String, Integer, Float, Long, Boolean, etc. que não precisam de nenhuma transformação.


Annotation @Basic
Mesmo não sendo necessário inserir nenhuma annotation para os casos mencionados acima costumo colocar a anotação @Basic (que é exatamente o mesmo que não colocar notação alguma) só para deixar explicito para quem lê o código que aquele atributo está mapeado no banco.


Ignorar Atributo
Em alguns momentos pode ser necessário fazer com que o JPA ignore algum atributo que exista na entidade mas que não queremos que seja persistido, como algum atributo apenas auxiliar para o funcionamento mas que dispensa persistência.

Neste caso devemos anotar o atributo com a annotation @Transient!

Nome da Coluna

Se nenhum nome de coluna for especificado o JPA tentará procurar uma coluna com o nome exato do atributo. Se não for o caso será necessário especificar uma annotation para indicar para o JPA esse mapeamento. No exemplo abaixo mapeamos o atributo "name" do VO à coluna "st_nome" do banco de dados.

Nome da Coluna do Banco
@Column(name="st_nome")
private String name = null;

Campos Date

Campos 'temporais' precisam ter sempre sua precisão definida. No exemplo abaixo:

Precisão da Data
// venda - terá seu tempo completo salvo no banco: Data + Hora
@Temporal(TemporalType.TIMESTAMP)
private Date venda = null;

// horasaida - terá apenas seu tempo salvo no banco de dados.
@Temporal(TemporalType.TIME)
private Date horasaida = null;

// feriado - salvará apenas o dia, sem a hora.
@Temporal(TemporalType.DATE)
private Date feriado = null;

Mapeamento Entre Objetos

Elementos Orfãos de Mapeamentos
Note que por padrão o JPA não exclui os elementos que foram simplesmente removidos da lista/coleção do seu pai. Algumas implementações oferecem essa opção, como o próprio Hibernate que oferece a opção "delete-orphan".

No entanto essa opção não funcionará no BIS, pois fora da camada de persistência (DAOs) os objetos já foram completamente desanexados, o que o impede de monitorar e remover os objetos filhos. A lógica de remoção dos filhos não mais utilizados deve ser realizada no CRUD. Caso contrário o filho permanecerá no banco e anexado ao elemento pai. É recomendável também que essa análise e exclusão dos filhos não mais utilizados seja feita antes de outras alterações e persistência do objeto pai no banco para evitar inconsistência e "lock".

OneToMany - carregado em um Map

Imagine o objeto SchedulerVO, este tem uma coleção de SchedulerPropertyVO. Como mostram as tabelas abaixo:



SchedulerVO
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "schedulervo", fetch = FetchType.EAGER)
@MapKey(name = "name")
private Map<String, SchedulerPropertyVO> properties = new HashMap<String, SchedulerPropertyVO>();
SchedulerPropertyVO
@ManyToOne(cascade = CascadeType.REFRESH, optional = false, fetch = FetchType.LAZY)
@JoinColumn(name = "idcore_scheduler")
public SchedulerVO schedulervo = null;


OneToMany - carregado em uma List

Imagine o objeto SchedulerVO, este tem uma coleção de SchedulerPropertyVO. Como mostram as tabelas abaixo:



SchedulerVO
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "schedulervo", fetch = FetchType.EAGER)
private List<SchedulerPropertyVO> properties = new ArrayList<SchedulerPropertyVO>();
SchedulerPropertyVO
  @ManyToOne(cascade = CascadeType.REFRESH, optional = false, fetch = FetchType.LAZY)
  @JoinColumn(name = "idcore_scheduler")
  public SchedulerVO schedulervo = null;