JPA 2.2 – Novidades Apresentadas

A algum tempo atrás a Oracle anunciou o lançamento da JPA 2.2 (JSR-338). Fazia tempo que esperavamos por essa atualização, principalmente devido a API Java Time lançada com o Java 8. As classes como LocalDate, LocalTime, LocalDateTimeOffsetTime e OffsetDateTime não tinham suporte da JPA 2.1 e para usá-las no mapeamento de nossas entidades era necessário criar uma classe de conversão, tanto para enviar como para receber valores do banco de dados.

Enquanto isso, versões do Hibernate 5 já estavam provendo suporte ao uso da Java Time. Mas esse é um suporte da implementação e não da especificação, fazendo com que só quem usasse Hibernate tivesse acesso ao recurso. Agora com a especificação, todos os frameworks ORM que queriram implementar a JPA 2.2 deverão dar suporte ao Java Time.

@Entity
public class Oracamento implements Serializable {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "ID")
	private Long id;
	
	@Column(name="DATA_ORACAMENTO")
	private LocalDateTime dataOracamento;
	
	@Column(name="DATA_PREVISAO_ENTREGA")
	private LocalDate dataPrevisaoEntrega;
}

Entretando não foi apenas Java Time que chegou como uma novidade na JPA 2.2. Outro ponto interessante são as anotações repetitiveis. Isso vai tornar o código mais limpo, o que sempre é algo muito bem vindo.  Mas o que são anotações repetitiveis? São aquelas que você pode declarar varias vezes sobre uma classe ou atributo. 

Por exemplo, veja o seguinte trecho de código e preste atenção no uso da anotação @NamedNativeQueries. Essa anotação era necessária para a declaração das anotações @NamedNativeQuery, onde realmente a consulta seria declarada: 

@Entity
@NamedNativeQueries({
		@NamedNativeQuery(
				name = "Address.buscaPorEndereco",
				query = "select * from Addresses where city like ?1 and street like ?2",
				resultClass = Address.class
		),
		@NamedNativeQuery(
				name = "Address.functionConcatenaEndereco",
				query = "select funcConcatAddress(?1)"
	    )
})
public class Address implements Serializable {
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "ID_ADDRESS")
	private Long id;	
}

Já com a nova versão da JPA 2.2 agora podemos eliminar a anotação @NamedNativeQueries e apenas declarar as anotações @NamedNativeQuery repetidamente:

@Entity
@NamedNativeQuery(
		name = "Address.buscaPorEndereco",
		query = "select * from Addresses where city like ?1 and street like ?2",
		resultClass = Address.class
)
@NamedNativeQuery(
		name = "Address.functionConcatenaEndereco",
		query = "select funcConcatAddress(?1)"
)
public class Address implements Serializable {
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "ID_ADDRESS")
	private Long id;	
}

Este novo recurso está disponível também para a anotação @NamedQuery, @JoinColumn, entre outras. Veja a lista completa:

  • AssociationOverride
  • AttributeOverride
  • Convert
  • JoinColumn
  • MapKeyJoinColumn
  • NamedEntityGraph
  • NamedNativeQuery
  • NamedQuery
  • NamedStoredProcedureQuery
  • PersistenceContext
  • PersistenceUnit
  • PrimaryKeyJoinColumn
  • SecondaryTable
  • SqlResultSetMapping

Outra novidade é em relação ao suporte a  java.util.Stream para consultas. Até a JPA 2.1 somente listas eram retornadas por uma query, no entando, com a JPA 2.2 as interfaces Query and TypedQuery têm um novo método chamado getResultStream() o qual vai retornar um objeto do tipo Stream (nativo do Java 8). Um recurso como esse já era possível de ser realizado em consultas via Spring-Data JPA. Veja um breve exemplo de uso com a JPA 2.2:

Stream persons = em
	.createQuery("SELECT p FROM Person p", Person.class)
	.getResultStream();

Por fim, temos uma atualização no recurso de classes conversoras que implementam a interface AttributeConverter. Será possível agora fazer uso de CDI para injeção de dependencias. Um breve exemplo pode ser visualizado a seguir:

@Converter(autoApply = true)
public class DocumentConverter implements AttributeConverter<document, string=""> {
 
    @Inject
    private DocumentHelper helper;
     
    @Override
    public String convertToDatabaseColumn(Document obj) {
        return helper.toString(obj);
    }
 
    @Override
    public Document convertToEntityAttribute(String s) {
        return helper.toDocument(s);
    }
}

Bem, essas são as atualizações que fazem parte da versão 2.2 da JPA, não foram muitas, mas acredito que serão bastante uteis para nós desenvolvedores. Para testá-las você pode usar o Maven com a seguinte instrução adicionada em seu arquivo pom.xml:

<!-- https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api -->
<dependency>
    <groupId>javax.persistence</groupId>
    <artifactId>javax.persistence-api</artifactId>
    <version>2.2</version>
</dependency>

Referências

  • JSR 338: JavaTM Persistence API, Version 2.2 – http://download.oracle.com/otndocs/jcp/persistence-2_2-mrel-spec/index.html
  • Java 8: Iniciando o desenvolvimento com a Streams API – http://www.oracle.com/technetwork/pt/articles/java/streams-api-java-8-3410098-ptb.html

Ballem

Marcio Ballem é bacharel em Sistemas de Informação pelo Centro Universitário Franciscano em Santa Maria/RS. Tem experiência com desenvolvimento Delphi e Java em projetos para gestão pública e acadêmica. Possui certificação em Java, OCJP 6.

Você pode gostar...