Assim, finalmente resolvi gastar alguns momentos do meu precioso tempo pra aprender JPA utilizando o Hibernate e eis que eu descubro uma coisa no mínimo bizarra.
A especificação não tem uma API equivalente a Criteria do Hibernate!
E o pior, os “líderes” da especificação acharam que a api de criteria é um requisito exótico e que não valia a pena ser adicionado na especificação.
Agora eu pergunto aos gênios que tiveram essa maravilhosa idéia, se eu tiver que montar uma query em tempo de execução (dinamicamente) eu vou ter que fazer concatenação de Strings em EJB-QL? Isso é absurdo!
Pronto, agora é que eu não migro do Hibernate mas nem amarrado, porque eu é que não vou ficar fazerndo concatenação de Strings e fazendo binding de parâmetros porque algum i$%@ta achou que uma coisa básica como uma API de busca absolutamente orientada a objetos é um “requisito exótico” em uma ferramenta de mapeamento objeto relacional.
Desculpem o abuso e as palavras baixas, mas isso realmente foi demais pra mim. Desse jeito, EJB vai continua sendo só hype mesmo, porque até na hora de copiar o que presta os caras se perdem, nã…
É uma pena mesmo, o EJB3 deu uma boa evoluida, mas quem utiliza-lo vai continuar preso a sua implementacao. Se eu usar EJB3 com Hibernate vou ficar preso ao recusos extras dele, Criteria, validacoes e por ai vai. O mesmo serve pro TopLink ou outros que surgirem.
Quem sabe na proxima eles acertam.
Eu so nao sei se isso foi de proprosito pois um dos responsaveis por isso é o proprio Gavin assim o Hibernate continua com um diferencia frente ao EJB3.
Descordo… acho que Entitys do EJB 3 ficaram bem legais… calro que voce nao tem criteria (puts… quantos % da sua plicação voce monta query dinamica ? 1% ? 2% ? ) e ao contrario das declaracoes aqui… nao fica preso nao… a nao ser que voce USE caracteristicas proprias… se voce usar o padrao… fica tudo compativel (uso hibernate e toplink aqui mudando 1 linha do XML persistence.xml )
Acho que é exagero falar que “EJB” eh soh session… os Entitys 3 ficaram bem legais…
Eu prefiro sacrificar algumas “novidades” do que deixar meu software na mão de um fornecedor apenas…
A integracao transparente do EntityManager não tem preço.
[quote=chun]Descordo… acho que Entitys do EJB 3 ficaram bem legais… calro que voce nao tem criteria (puts… quantos % da sua plicação voce monta query dinamica ? 1% ? 2% ? ) e ao contrario das declaracoes aqui… nao fica preso nao… a nao ser que voce USE caracteristicas proprias… se voce usar o padrao… fica tudo compativel (uso hibernate e toplink aqui mudando 1 linha do XML persistence.xml )
[/quote]
Rapaz, se você acha que fazer concatenação de Strings é uma coisa boa e normal, boa sorte. Eu, pessoalmente, detesto.
[quote=Maurício Linhares][quote=chun]Descordo… acho que Entitys do EJB 3 ficaram bem legais… calro que voce nao tem criteria (puts… quantos % da sua plicação voce monta query dinamica ? 1% ? 2% ? ) e ao contrario das declaracoes aqui… nao fica preso nao… a nao ser que voce USE caracteristicas proprias… se voce usar o padrao… fica tudo compativel (uso hibernate e toplink aqui mudando 1 linha do XML persistence.xml )
[/quote]
Rapaz, se você acha que fazer concatenação de Strings é uma coisa boa e normal, boa sorte. Eu, pessoalmente, detesto.[/quote]
Eu detesto tmb… mas continuo afirmando que Querys dinamicas são praticamente 1 ou 2% da minha app , entao não costumo fazer tempestade em um copo d’agua… é s´po separar e pronto…
Odeio acessar via JNI as coisas… mais eh 1% de tudo tmb… entao… prefiro conviver com isso a ficar preso a um unico fornecedor.
Na minha opiniao , isso não é motivo suficiente para deixar JPA de lado… ela proporciona uma integracao muito boa… e a vida eh feita de escolhas
A falta da API de criteria no JPA é realmente motivo suficiente pra chorar soluçando!
Mas é possível criar queries dinâmicas sem concatenar strings através de @NamedQueries e @NamedQuery. Ex:
@Entity
@Table(name = "produto")
@NamedQueries( {
@NamedQuery(
name = "Produto.findByDescricao",
query = "SELECT p FROM Produto p WHERE p.descricao = :descricao"),
@NamedQuery(
name = "Produto.findByPreco",
query = "SELECT p FROM Produto p WHERE p.preco = ?1")
} )
public class Produto implements Serializable {
. . . // Implementação do Entity Bean.
}
public class ProdutoDAO ...
. . .
public List<Produto> findByPreco(final BigDecimal preco) {
return manager.createNamedQuery("Produto.findByPreco").
/* Positional Parameter in Query */
setParameter(1, preco).getResultList();
}
. . .
}
Também é possível criar a query através do método createQuery do EntityManager.
public class ProdutoDAO ...
. . .
public Produto findByName(final String nome) {
Produto temp = null;
try {
temp = (Produto) manager.createQuery(
"SELECT p FROM Produto p WHERE p.nome LIKE :nome")
/* Named Parameter in Query */
.setParameter("nome", nome).getSingleResult();
} catch(Exception e) {
e.printStackTrace();
}
return temp;
}
. . .
}
Maurício, muito bom esse documento, sobre esse assunto do tópico informando que a JPA não tem o Criteria, a especificação JPA não tem o especifica o Criteria (pode me corrigir se estiver errado), mas para trabalhar com JPA temos que utilizar algum mecanismo que implementou a JPA sendo assim utilizamos o Hibernete ou Toplink, certo?
Qual é o problema utilizar o que tem de amais no Hibernet ou no Toplink, pois o tópico desse forum “JPA não tem uma API de Criteria? Que absurdo é esse?” não é verdade conforme o exemplo que mandei e segue o pequeno trecho abaixo:
public List<T> findByExample(T instance) throws DAOException {
Session session = (Session) getEntityManager().getDelegate();
Example example = Example.create(instance).excludeZeroes();
Criteria criteria = session.createCriteria(instance.getClass()).add(example);
return criteria.list();
}
[quote=marcus.floriano]Qual é o problema utilizar o que tem de amais no Hibernet ou no Toplink, pois o tópico desse forum “JPA não tem uma API de Criteria? Que absurdo é esse?” não é verdade conforme o exemplo que mandei e segue o pequeno trecho abaixo:
public List<T> findByExample(T instance) throws DAOException {
Session session = (Session) getEntityManager().getDelegate();
Example example = Example.create(instance).excludeZeroes();
Criteria criteria = session.createCriteria(instance.getClass()).add(example);
return criteria.list();
}
Estou enganado?[/quote]
Está, esse código não funciona pro TopLink, só pro Hibernate.
mas whatever, sobre a API de critéria, o que talvez possa ser interessante é, caso tu queira um negócio mais “compatível” com o resto das coisas, ou usa um QueryObject ou usa a API de critéria do Hibernate ou Toplink. Ambos tem suas respectivas implementações, basta dar uma olhada
Complicado mesmo Maurício. Nesse exato momento estou escrevendo um componente adicional para o WLI ( Weblogic Integration - Apache Beehive) encapsulando a persistência no modelo ORM.
Como vou utillizá-lo dentro de um processo ( JSR 207), todas as queries serão dinâmicas.
Infelizmente ele vai ter de mudar de nome para HibernateControl, rsss até a JPA 2 sair do papel … :roll: