Category Archives: Java

Solução: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException

E ai galera beleza, estava estudando um projeto Spring MVC com Hibernate que será colocado na AWS, porém estava apanhando pra subir o projeto no TomCat, estava tomando esse erro:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class br.com.casadocodigo.loja.configuration.JPAConfiguration: Invocation of init method failed; nested exception is org.hibernate.cfg.beanvalidation.IntegrationException: Error activating Bean Validation integration
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1568)
...
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:399)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:341)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1627)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1564)
... 21 more
Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
at org.hibernate.validator.engine.ConfigurationImpl.parseValidationXml(ConfigurationImpl.java:252)
at org.hibernate.validator.engine.ConfigurationImpl.buildValidatorFactory(ConfigurationImpl.java:143)
...
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.hibernate.cfg.beanvalidation.BeanValidationIntegrator.integrate(BeanValidationIntegrator.java:150)
... 32 more
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1339)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1167)
... 42 more

Depois de tentar com TomCat 7, 8 e 8.5 descobri que as APIs do JAXB foram consideradas APIs do Java EE então não estão mais no classpath default do Java SE 9. Já no Java 11, elas foram completamente removidas do JDK. E eu estou com o JDK 12 na minha máquina… tsc tsc tsc…

Resolvi esse problema adicionando as seguintes dependências no pom.xml do maven:


<!-- API, java.xml.bind module -->
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.2</version>
</dependency>

<!-- Runtime, com.sun.xml.bind module -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
</dependency>

Simples, assim… é isso ai galera, lição aprendida! Abraços!

 

Fonte: Andy Guibert – Stackoverflow

Novidades do Java 8

Só alguns poucos (6) anos atrasado, venho publicar esse post com as principais novidades do Java 8 que foi lançado em Março de 2014 através da especificação JSR 337.

Esse post é o primeiro da série onde pretendo centralizar as melhorias de cada uma das versões que vieram após o Java 7.

Lambda Expression

Também conhecida como funções anônimas, acredito que essa seja maior mudança na versão 8, as expressões lambdas podem causar estranhesa a primeira vista por quem apenas programou utilizando Java. Mas elas já são bem comuns para programadores que tiveram contato com linguagens como C#, Clojure, Go, Groovy, Javascript, Kotlin, Ruby, Scala e muitas outras.

Essas expressões facilitam a implementação dos comportamentos de inferfaces funcionais, que são aquelas interfaces que possuem apenas um único método abstrato.

Como por exemplo a clássica interface java.util.Comparator, comumente utilizada para ordenar coleções. Anteriormente precisaríamos implementar essa interface em uma classe ou instância-la como classe anonima como no exemplo abaixo:

List<String> linguagens = Arrays.asList("Java", "C#", "Php", "Html");

Comparator<String> comparadorPorTamanho = new Comparator() {
	public int compare(String s1, String s2) {
		return Integer.compare(s1.length(), s2.length());
	}};

Collections.sort(linguagens, comparadorPorTamanho);

Agora abaixo um código equivalente ao de cima, substituindo a instanciação da classe anonima pela expressão lambda:

List<String> linguagens = Arrays.asList("Java", "C#", "Php", "Html");

Comparator<String> comparadorPorTamanho = (s1, s2) -> Integer.compare(s1.length(), s2.length());

Collections.sort(linguagens, comparadorPorTamanho);

Podemos fazer uma versão mais enxuta ainda, passando a expressão lambda direto como argumento para o método sort:

List <String> linguagens = Arrays.asList("Java", "C#", "Php", "Html");

Collections.sort(linguagens, (s1, s2) -> Integer.compare(s1.length(), s2.length()));

Detalhando um pouco mais a sintaxe da expressão lambda apresentada:

(s1, s2) -> Integer.compare(s1.length(), s2.length())

É iniciada com a declaração dos parametros do método que estamos implementando. O método da interface Comparator aguarda 2 parametros do tipo String, a tipagem dos parâmetros é opcional, já que temos apenas um único método na interface, o compilador ja sabe com quais tipos ele está lidando, por isso declaramos apenas o nome que desejamos para as variáveis:

(s1, s2) ...

Se o método aguardasse apenas 1 parametro, então declaramos somente o nome do parametro, sendo que neste cenário os parênteses passam a ser opcionais.

s1 ...

Caso o método não tivesse parametros, seria declarado com parenteses vazios:

() ...

Após a declaração dos parametros colocamos o arrow token, que é composto por um hífen, seguido por um sinal de maior (->):

(s1, s2) -> ...

Em seguida devemos colocar o conteúdo do nosso método, no exemplo que estamos utilizando é { return Integer.compare(s1.length(), s2.length()); }, como o nosso corpo é simples e tem apenas uma única linha (instrução), podemos suprimir as chaves, o return e o ponto e vírgula (;), pois nesse caso tornan-se opcionais:

(s1, s2) -> Integer.compare(s1.length(), s2.length())

Caso o nosso conteúdo fosse ‘mais complexo’, com mais de uma linha (instrução), necessitaríamos da utilização das chaves, do return (caso o método não seja void, claro :D) e do ponto e vírgula (;) no final de cada comando, como por exemplo:

(s1, s2) -> {
    // imagine qualquer comando aqui
    int resultado = Integer.compare(s1.length(), s2.length());
    // imagine qualquer comando aqui
    return resultado;
}

Ordenando Collections

Como vimos no exemplo acima, ordenavamos nossas coleções utilizando o método utiitário Collections.sort (Classe), agora no java 8 temos outra maneira mais simples de efetuar tal ação, temos o método Collection.sort (Interface), que espera como parâmetro apenas um Comparator compatível com o tipo da lista, o qual está disponível em todas as nossas coleções, como por exemplo na interface List.

List<String> linguagens = Arrays.asList("Java", "C#", "Php", "Html");

linguagens.sort((s1, s2) -> Integer.compare(s1.length(), s2.length()));

A interface Comparator ganhou um método estático (sim! agora é possível :D) Comparator.comparing, que facilitar a criação de uma instância de um comparador simples:

List<String> linguagens = Arrays.asList("Java", "C#", "Php", "Html");

linguagens.sort(Comparator.comparing(s -> s.length()));

Podemos simplificar ainda mais com outra novidade, o Method Reference, que nos permite fazer referência a um método específico de uma classe:

List<String> linguagens = Arrays.asList("Java", "C#", "Php", "Html");

linguagens.sort(Comparator.comparing(String::length));

Novos métodos nas Collections

Nas nossas coleções tivemos algumas mudanças, ganhamos diversos métodos novos como o Collection.sort visto acima, muitos deles esperam com parâmetro implementações de interfaces funcionais (assunto que veremos a seguir), segue mais alguns:

Iterable.forEach(Consumer)
Iterator.forEachRemaining(Consumer)
Collection.removeIf(Predicate)
Collection.spliterator()
Collection.stream()
Collection.parallelStream()
List.sort(Comparator)
List.replaceAll(UnaryOperator)
Map.forEach(BiConsumer)
Map.replaceAll(BiFunction)
Map.putIfAbsent(K, V)
Map.remove(Object, Object)
Map.replace(K, V, V)
Map.replace(K, V)
Map.computeIfAbsent(K, Function)
Map.computeIfPresent(K, BiFunction)
Map.compute(K, BiFunction)
Map.merge(K, V, BiFunction)
Map.getOrDefault(Object, V)

Interface

Ocorreram melhorias também nas interfaces, como a possibilidade de declarar métodos concretos, chamados de Default Method, fazendo com que as interfaces tenham uma grande similaridade com as classes abstratas, que até então eram um meio termo entre interfaces e classes concretas. Esse tipo de método necessita do operador default em sua declaração.

Solução criada para possibilitar a evolução das interfaces já existentes, assim quando criarmos novos métodos em interfaces que já estão em uso, essas alterações não irão causar erros de compilação nas outras interfaces e/ou classes que as implementam.

Por exemplo, o novo método sort da interface List:

default void sort(Comparator<? super E> c) {
    Collections.sort(this, c);
}

Outra novidade também, como vimos na interface Comparator.comparing, agora podemos declarar métodos estáticos, o que não era possível anteriormente:

Interfaces funcionais

Como ja vimos no começo do post, inferfaces funcionais, que são aquelas interfaces que possuem apenas um único método abstrato.

Antes dessa nova versão ja tinhamos outras interfaces funcionais, é isso mesmo! Um exemplo seria a interface Runnable, que é implementada pela famosa classe Thread.

Agora as interfaces funcionais ganharam mais destaque, e também novas interfaces localizadas no pacote java.util.function:

Function<T, R> − recebe T como entrada, retorna R como saída;
Predicate<T> − recebe T como entrada, retorna um valor booleano como saída;
Consumer<T> − recebe T como entrada, não retorna nada como saída;
Supplier<T> − não recebe entrada, retorna T como saída;
BinaryOperator<T> − recebe duas entradas T, retorna um T como saída.

Também temos uma nova anotação @FunctionalInterface, que deve ser utilizada para indicar que uma interface é funcional. O que obriga o compilador a verificar se existe apenas um método declarado na interface. Em caso negativo, ocorrerá um erro de compilação. Todas as antigas interfaces que são consideradas funcionais, receberam essa anotação.

Optional

Nova classe que nos ajuda a evitar a má prática de retornar null em nosso métodos, e espalhar comparações do tipo if (resultado != null), deixando o nosso código muito mais elegante. Estamos falando da classe java.util.Optional que usufrui de Generics, possibilitando uma codificação tipada. Segue algumas maneira de aplica-la:

Retornando resutado não-nulo:

public Optional<String> buscar() {
    String resultado = "XPTO";
    return Optional.of(resultado);
}

Retornando resutado que é vazio, antigo return null:

public Optional<String> buscar() {
    return Optional.empty();
}

Retornando resultado que tem a possibilidade de ser nulo:

public Optional<String> buscar() {
    String resultado = null;
    return Optional.ofNullable(resultado);
}

Internamente o método acima verifica o parametro passado e decide se prossegue com o método of ou empty.

Agora segue alguns exemplos do lado de quem recebeu o Optional como retorno, como o utilizamos:

Verificando se temos um resultado preenchido:

Optional<String> opt = buscar();
boolean preenchido = opt.isPresent();

Obtendo o resultado encapsulado, devemos verificar com o método isPresent para evitar receber uma exceção:

Optional<String> opt = buscar();
String resultadoEsperado = opt.get();

Se o resultado estiver presente, você pode ja passar uma função para consumi-lo:

Optional<String> opt = buscar();
opt.ifPresent(r -> System.out.println(r));

Você ja pode deixar seu código preparado para receber outro valor caso o resutado não esteja presente:

Optional<String> opt = buscar();
String outroResultado = opt.orElse("Vazio!");

Lançando exceção caso o resutado não esteja presente:

Optional<String> opt = buscar();
opt.orElseThrow(IllegalStateException::new);

Stream

Uma grande novidade que nos ajuda muito no dia a dia, é o pacote java.util.stream, que nos possibilita uma programação no estilo funcional. Simplificando a forma de iterar, filtrar, transformar, consolidar e coletar os dados.

A forma mais comum de ter acesso a uma instância de Stream é através de collections já populadas, através do método Collection.stream, que nos devolve uma instância de java.util.stream.Stream, possibilitando o uso de uma infinidade de métodos que esperam como parâmetro a implementação de diversas interfaces funcionais (ex.: as que mostramos acima) de acordo com o tipo de operação.

Iterando (ex.: Imprimindo as linguagens):

List<String> linguagens = Arrays.asList("Java", "C#", "Php", "Html");

linguagens.stream()
    .forEach( l -> System.out.println("Imprimindo linguagem "+l ));

Obs.: Também podemos ter acesso a esse método de forma mais prática, diretamente na coleção com Iterable.forEach.

Transformando (ex.: Obtendo as iniciais de cada linguagem):

List<String> linguagens = Arrays.asList("Java", "C#", "Php", "Html");

List<Character> iniciais = linguagens.stream()
    .map(l -> l.charAt(0))
    .collect(Collectors.toList());

Nesse exemplo fizemos chamadas sequenciais/encadeadas de 2 métodos, o map e o collect, onde um faz a transformação de cada objeto e o outro é responsável por obter o resultado da operação anterior.

Ordenando (ex.: Ordem alfabetica)

List<String> linguagens = Arrays.asList("Java", "C#", "Php", "Html");

List<String> novaListaOrdenada = linguagens.stream()
    .sorted(Comparator.comparing(String::toString))
    .collect(Collectors.toList());

Nesse exemplo ordenamos com sorted e em seguida obtivemos a lista ordenada com o collect.

Removendo duplicados

List<Integer> numeros = Arrays.asList(1, 1, 2, 3, 4, 4, 5);

numeros.stream()
    .distinct()
    .forEach(n -> System.out.println(n));

Removemos os duplicados através do distinct, o qual se utiliza do método equals do objeto para distinguir os valores, e para variar, não coletamos o resutado, e sim, imprimimos cada um deles com o forEach.

Filtrando (ex.: Linguagens que começam com “J”)

List<String> linguagens = Arrays.asList("Java", "C#", "JavaScript", "Html");

linguagens.stream()
    .filter(l -> l.startsWith("J"))
    .forEach(l -> System.out.println(l));

Filtramos utilizando o filter e imprimimos utilizando forEach.

Temos muitas outras possibilidades para trabalhar com Stream, para descobrir todas elas, basta dar uma olhada na documentação oficinal 😀

Também temos Streams para trabalhar com tipos primitivos, como IntStream, LongStream e DouleStream, que nos oferecem métodos específicos para trabalhar com números, como average, sum, reduce e muito mais.

Além de tudo isso, podemos efetuar esses processamentos de forma paralela de maneira bem simples, com o uso do método Collection.parallelStream ao invés de Collection.stream, possibilitando um possível ganho de performance.

Datas e horas

Finalmente ganhamos uma nova API para trabalhar com data e hora, baseada no JodaTime, o JodaTime ja era uma biblioteca bastante utilizada pelos desenvolvedores, agora nossa vida será muito mais fácil quando o assunto for lidar com data e hora.

As antigas classes java.util.Date, java.sql.Date, java.util.GregorianCalendar e cia, dão espaço para as classes dos pacotes java.time, como por exemplo LocalDate para trabalhar apenas com data, LocalTime para trabalhar apenas com horas, LocalDateTime para trabalhar com data e hora. Também temos a classe java.time.format.DateTimeFormatter para ajudar na formatação e muitas outras.

Segue um breve exemplo do uso das classes citadas:

System.out.println("Hoje: " + LocalDate.now());

System.out.println("Agora: " + LocalTime.now());

LocalDate nascimento = LocalDate.of(1989, Month.MAY, 22);
System.out.println("Nascimento: " + nascimento);

String nascimentoFormatado = nascimento.format(DateTimeFormatter.ofPattern("dd/MM/yy"));
System.out.println("Nascimento formatado: " + nascimentoFormatado);

A nova API tem muitas classes e muitos métodos, não irei abordar tudo aqui pois não é o intuito desse post. Para ver todas as funcionalidades dê uma olhadinha nesse post da oracle!

Essas classes ja são suportadas pelo JDBC e JPA, então você pode mapear seu modelo utilizando-as sem medo! 😀

Outras mudanças

Melhorias na própria JVM relacionado ao uso da memória disponível (Metaspace);
Melhorias na API de Concorrência;
Melhorias na API de IO/NIO;
Melhorias para trabalhar com Reflection;
Nova implementação para utilizar JavaScript dentro do Java: Nashhorn;
Nova implementações para unir Strings como o método String.join e a classe java.util.StringJoiner;
Conexão com Banco de dados via JDBC-ODBC foi removida;
Não roda no Windows XP;

Fontes:
Caelum, Matera, Feltex, Infoq, Oracle – Docs, Oracle – Specs, Wikipedia

ArrayIndexOutOfBoundsException ao utilizar NamedParameterJdbcTemplate + MapSqlParameterSource

Fala galera, bora tirar o pó do blog rs…

me deparei com o erro abaixo, nada intuitivo, utilizando NamedParameterJdbcTemplate e MapSqlParameterSource, onde eu tenho na minha query parâmetros opcionais/nullable, ou seja, parâmetros que podem vir ou não com valor (null):

java.lang.ArrayIndexOutOfBoundsException: 128
	at oracle.jdbc.driver.OracleParameterMetaDataParser.computeBasicInfo(OracleParameterMetaDataParser.java:327)
	at oracle.jdbc.driver.OracleParameterMetaDataParser.getParameterMetaDataSql(OracleParameterMetaDataParser.java:433)
	at oracle.jdbc.driver.OracleParameterMetaData.getParameterMetaData(OracleParameterMetaData.java:58)
	at oracle.jdbc.driver.OraclePreparedStatement.getParameterMetaData(OraclePreparedStatement.java:12861)
	at oracle.jdbc.driver.OraclePreparedStatementWrapper.getParameterMetaData(OraclePreparedStatementWrapper.java:1551)
	at org.springframework.jdbc.core.StatementCreatorUtils.setNull(StatementCreatorUtils.java:248)
	at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:229)
	at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:147)
	at org.springframework.jdbc.core.PreparedStatementCreatorFactory$PreparedStatementCreatorImpl.setValues(PreparedStatementCreatorFactory.java:278)
	at org.springframework.jdbc.core.PreparedStatementCreatorFactory$PreparedStatementCreatorImpl.createPreparedStatement(PreparedStatementCreatorFactory.java:236)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:603)
	at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:657)
	at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:682)
	at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:736)
	at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.query(NamedParameterJdbcTemplate.java:212)
	...

após perder alguns minutos pesquisando, não achei nada para resolver, então criei uma solução/tratamento simples:

public <T> void setOptionalParameter(MapSqlParameterSource parameters, String name, T value) {
   if (valor == null)
      parameters.addValue(name, value, Types.NULL);
   else
      parameters.addValue(name, value);
}

Forma de utilização:

MapSqlParameterSource parameters = new MapSqlParameterSource();
new MapSqlParameterSourceUtil().setOptionalParameter(parameters, "optionalParam", optionalParam);
parameters.addValue("mandatoryParam", mandatoryParam);
jdbcTemplate.query(...);

Espero ter ajudado, see ya! 😀

ActiveMQ + JMS – This class is not trusted to be serialized as ObjectMessage payload.

Galera estou estudando um pouco mais a fundo o ActiveMQ, e me deparei com essa mensagem de erro no momento de ‘deserializar’ uma instância de ObjectMessage, ele ocorre a partir da versão 5.12.2:

javax.jms.JMSException: Failed to build body from content. Serializable class not available to broker. Reason: java.lang.ClassNotFoundException: Forbidden class br.com.modelo.Pedido! This class is not trusted to be serialized as ObjectMessage payload. Please take a look at http://activemq.apache.org/objectmessage.html for more information on how to configure trusted classes.
at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:36)
at org.apache.activemq.command.ActiveMQObjectMessage.getObject(ActiveMQObjectMessage.java:213)
at br.com.jms.ConsumidorTopicoComercial$1.onMessage(ConsumidorTopicoComercial.java:47)
at org.apache.activemq.ActiveMQMessageConsumer.dispatch(ActiveMQMessageConsumer.java:1404)
at org.apache.activemq.ActiveMQSessionExecutor.dispatch(ActiveMQSessionExecutor.java:131)
at org.apache.activemq.ActiveMQSessionExecutor.iterate(ActiveMQSessionExecutor.java:202)
at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:133)
at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:48)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.ClassNotFoundException: Forbidden class br.com.modelo.Pedido! This class is not trusted to be serialized as ObjectMessage payload. Please take a look at http://activemq.apache.org/objectmessage.html for more information on how to configure trusted classes.
at org.apache.activemq.util.ClassLoadingAwareObjectInputStream.checkSecurity(ClassLoadingAwareObjectInputStream.java:112)
at org.apache.activemq.util.ClassLoadingAwareObjectInputStream.resolveClass(ClassLoadingAwareObjectInputStream.java:57)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1868)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1751)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2042)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at org.apache.activemq.command.ActiveMQObjectMessage.getObject(ActiveMQObjectMessage.java:211)
… 9 more

Para ajudar quem possa vir a tomar esse erro, há duas opções para corrigir o problema alterando a classe consumidora.

Solução 1:

Adicionando o trecho:

System.setProperty("org.apache.activemq.SERIALIZABLE_PACKAGES","*");

Solução 2:

Substituindo o trecho:

ConnectionFactory factory = (ConnectionFactory) context.lookup("ConnectionFactory");

por

ActiveMQConnectionFactory factory = (ActiveMQConnectionFactory) context.lookup("ConnectionFactory");
factory.setTrustAllPackages(true);

Não sei se é a forma mais correta, porém resolveu. Se alguém tiver algum adendo, só postar aqui nos comentários 😉

See ya!

Apostila – Introdução ao Java 7

Boa noite galera,

Segue a apostila que eu montei e utilizo no curso de introdução ao java 7 lecionado para os estagiários da empresa em que trabalho:
Introdução ao Java 7 – v1.2

Abraços!

Erro: web.xml is missing and is set to true

E ai galera, beleza?

Está tomando o erro “web.xml is missing and <failOnMissingWebXml> is set to true” no seu projeto maven dentro do eclipse???

Então vamos corrigir esse erro!

  1. Clique com o botão direito no ‘Deployment Descriptor’ dentro do seu projeto no ‘Project Explorer’.
  2. Selecione a opção ‘Generate Deployment Descriptor Stub’.
  3. Pronto !!! 😀

Isso irá gerar a pasta ‘WEB-INF’ no src/main/webapp com o web.xml dentro.

Abraços!!!

Fonte: stackoverflow.com – Wojciechu

JPA/Hibernate Static Metamodel Attributes não populados / nulos — Gerando NullPointerException

E ai galera, beleza?

Hoje tive um problema tentando utilizar os atributos metamodel estáticos do JPA/Hibernate,
sempre quando eu ia utilizá-los, eles estavam nulos… depois de um tempo quebrando a cabeça consegui achar o motivo!

Vamos exemplificar o cenário:

Entidade:

package com.mydomain.model.user;

public class User {

/** Número de identificação */
@Id
private Long id;

/** Nome de autenticação */
private String username;

//getters e setters
}

Metamodel:

package com.mydomain.metamodels;

import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel;

@StaticMetamodel(User.class)
public class User_ {
public static volatile SingularAttribute<User, String> username;
}

Uso do metamodel no predicado (predicate):


cb.equal(root.get(User_.username), “usuario_teste”);

Toda vez que eu tentava dar get(…) eu estava tomando nullpointerexception,
e a solução que encontrei foi colocar a classe User.class e a User_.class no mesmo pacote…
não sei o real motivo para precisarem estar, porém só assim funcionou pra mim..

Pesquisando descobri também que em futuros releases talvez essas classes possam ficar em pacotes diferentes,
segue algumas regras descritas na especificação do JPA 2:

  • Classes Metamodel devem estar no mesmo pacote das classes de entidade que elas descrevem;
  • Elas devem ter o mesmo nome das classes de entidade que elas descrevem, seguido por um traço-baixo (“_”, underline, underscore…).
    Exemplo: Produto.class é a classe de entidade e o Produto_.class é a classe metamodel.
  • Se uma entidade herdar de outra entidade ou de uma superclasse mapeada (mapped superclass) deve herdar da classe metamodel que descreve sua superclasse.
    Exemplo: Se ProdutoEspecial.class estende Product.class, que estende ObjetoPersistente.class, então ProdutoEspecial_.class deve estender Produto_.class, que deve estender ObjetoPersistente_.class.

É isso ai pessoal espero ter ajudado!
valeu!!!

Fonte: stackoverflow.com – debbie/Vítor E. Silva Souza

Como persistir LocalDate e LocalDateTime do Java 8 com JPA

E ai galera beleza? faz muito tempo que eu não postava nada novo, então bora com “novidade” do java 8 + JPA 😀

O Java 8 trouxe muitas grandes funcionalidades e uma das mais importantes e uma das antecipadas foi a nova API de data e hora. Haviam muitos problemas com a antiga API e não vou entrar em detalhes do porque nós precisamos de uma nova. Tenho certeza que você teve que lutar com ela com frequencia.

Todos esses problemas se foram com Java 8 \o/. A nova API de data e hora é bem desenhada, fácil de usar e (finalmente) imutável. O único problema que permanece é, que você não pode usava com JPA.

Bem, isso não totalmente verdade. Você pode usa-la, porém o JPA irá mapeá-la para BLOB ao invés de DATE ou TIMESTAMP. Que significa que a base de dados não está ciente do objeto de data e não pode aplicar nenhuma otimização para isso. E não é desse jeito que deveríamos ou gostaríamos de fazê-lo.

Porque o JPA não suporta LocalDate e LocalDateTime?

A resposta é simples, o JPA 2.1 foi liberado antes do Java 8 e a API de data e hora simplesmente não existia naquela época. Portanto a anotação @Temporal pode apenas ser aplicada a atributos do tipo java.util.Date e java.util.Calendar.

Se você deseja armazenar um atributo LocalDate em uma coluna Date ou uma LocalDateTime em uma coluna TIMESTAMP, você mesmo precisa definir o mapeamento para java.sql.Date ou java.sql.Timestamp. Graças ao conversor de atributo, uma das diversas novas funcionalidades do JPA 2.1, isso pode ser alcançado com apenas algumas linhas de código.

Nos exemplos abaixo, eu vou mostrar pra vocês como criar um conversor de atributos para LocalDate e LocalDateTime. Se você quer aprender mais sobre conversor de atributo, dê uma olhada aqui (inglês).

O exemplo

Antes de nós criar os conversores de atributo, vamos dar uma olhada na entidade de exemplo para esse post:

@Entity
public class MyEntity {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = “id”, updatable = false, nullable = false)
private Long id;

@Column
private LocalDate date;

@Column
private LocalDateTime dateTime;

}

O conversor de atributo faz parte da especificação do JPA 2.1 e pode portanto ser usado com qualquer implementação de JPA 2.1, ex.: Hibernate ou EclipseLink. Eu usei Wildfly 8.2 com Hibernate 4.3 para os seguintes exemplos.

Convertendo LocalDate

Como você pode ver no seguinte pedaço de código, não é necessário muita coisa para criar um conversor de atributo para LocalDate.

@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {

@Override
public Date convertToDatabaseColumn(LocalDate locDate) {
return (locDate == null ? null : Date.valueOf(locDate));
}

@Override
public LocalDate convertToEntityAttribute(Date sqlDate) {
return (sqlDate == null ? null : sqlDate.toLocalDate());
}
}

Você precisa implementar a interface AttributeConverter<LocalDate, Date> e seus 2 métodos convertToDatabaseColumn e convertToEntityAttribute. Como você pode ver nos nomes dos métodos, um deles define a conversão do tipo do atributo da entidade (LocalDate) para o tipo de coluna da base de dados (Date) e o outro é a conversão inversa. A conversão em si é simples porque java.sql.Date ja nos provê o método para fazer a conversão “de” e “para” um LocalDate.

Adicionalmente o conversor de atributo precisa ser anotado com a anotação @Converter. Devido a propriedade opcional autoApply=true, o conversor será aplicado a todos os atributos do tipo LocalDate. Dê uma olhada aqui (inglês), se você quer definir o uso de cada conversor para cada atributo individualmente.

A conversão do atributo é transparente para o desenvolvedor e o atributo LocalDate pode ser usado como qualquer outro atributo da entidade. Você pode usa-lo como parâmetro de query por exemplo.

LocalDate date = LocalDate.of(2015, 8, 11);
TypedQuery<MyEntity> query = this.em.createQuery(“SELECT e FROM MyEntity e WHERE date BETWEEN :start AND :end”, MyEntity.class);
query.setParameter(“start”, date.minusDays(2));
query.setParameter(“end”, date.plusDays(7));
MyEntity e = query.getSingleResult();

Convertendo LocalDateTime

O conversor de atributo para LocalDateTime é basicamente o mesmo. Você precisa implementar a interface attributeConverter<LocalDateTime, Timestamp> e o conversor precisa ser anotado com a anotação @Converter. Assim como o LocalDateConverter, a conversão entre LocalDateTime e um java.sql.Timestamp é feita através dos métodos de conversão do Timestamp.

@Converter(autoApply = true)
public class LocalDateTimeAttributeConverter implements AttributeConverter<LocalDateTime, Timestamp> {

@Override
public Timestamp convertToDatabaseColumn(LocalDateTime locDateTime) {
return (locDateTime == null ? null : Timestamp.valueOf(locDateTime));
}

@Override
public LocalDateTime convertToEntityAttribute(Timestamp sqlTimestamp) {
return (sqlTimestamp == null ? null : sqlTimestamp.toLocalDateTime());
}
}

Conclusão

O JPA 2.1 foi liberado antes do Java 8 e portanto não suporta a nova API de data e hora. Se você quer usar as novas classes (do jeito certo), você mesmo precisa definir a conversão para java,sql.Date e java.sql.Timestamp. Isso pode ser feito facilmente implementando a interface AttributeConverter<EntityType, DatabaseType> e anotando a classe com a anotação @Converter(autoApply=true). Setando autoApply=true, a conversão será aplicada a todos os atributos do EntityType e nenhuma alteração na entidade é necessária.

Até onde eu sei, a próxima versão do JPA suportará a nova API de data e hora e as diferentes implementações provavelmente irão suporta-la ainda mais cedo. O Hibernate 5 por exemplo irá suporta-la como uma funcionalidade proprietária.

É isso ai galera, espero tê-los ajudado 😀

Fonte: thoughts-on-java.org – Thorben Janssen

JPQL – Como criar query de DELETE com JOIN

E ai galera beleza?
Estou em um novo projeto muito legal, e me deparei com um problema, eu precisava fazer uma query para deletar uns dados no banco, só que pra selecionar exatamente oque eu precisava excluir era necessário utilizar joins, porém ao montar uma query parecida com essa:

delete from Queue q
where q.enabledMember = :enabledMember
and q.letter.eventReason.event.type = :eventType
and q.letter.eventReason.reason = :reason

Tomei o seguinte erro:

The entity abstract schema type declaration is malformed

Pesquisei um pouco na net e achei a seguinte solução, deletar a partir de um subselect, a query ficou assim:

delete from Queue q
where q in (select sq from Queue sq
where sq.enabledMember = :enabledMember
and sq.letter.eventReason.event.type = :eventType
and sq.letter.eventReason.reason = :reason )

Bom, é isso ai galera, espero que tenha ajudado 😀

Abraços!

Fonte: Jake Trent – JakeTrent.com

BigDecimal – Resolvendo o Erro: java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

E ai pessoal, beleza?

Me deparei com esse erro ao trabalhar com BigDecimal, e no meu caso,
como eu estou trabalhando com $$$ não é sempre uma boa fazer arredondamentos
no meio dos cálculos… podem resultar em alguns reais de diferença…

Erro no seguinte código:

BigDecimal a = newBigDecimal("1.6");
BigDecimal b = newBigDecimal("9.2");
a.divide(b);

Para resolver o erro apenas arredondando, faça da seguinte forma:

BigDecimal a = newBigDecimal("1.6");
BigDecimal b = newBigDecimal("9.2");
a.divide(b, 2, RoundingMode.HALF_UP);

Onde o “2”, é o número de cadas após o ponto… e o RoundingMode é o modo de arredondamento (existem diversos)!

Para resolver o erro SEM arredondar, faça da seguinte forma:

BigDecimal a = newBigDecimal("1.6");
BigDecimal b = newBigDecimal("9.2");
a.divide(b, MathContext.DECIMAL128);

Você pode escolher o número de bits que você quer entre 32, 64 ou 128…

Bom é isso ai pessoal… abraços!!!

Fonte: StackOverflow – DVK / MindBrain