POJO’s são classes JAVA que serão vinculadas com o Banco de Dados?
Qual a maneira correta de se fazer esses POJO’s, eu vi que tem o hbm.xml, mas me disseram que é um método muito antigo para se fazer isso, o correto é fazer uma classe com os mesmos atributos que estão no banco e implementar serializable e mapear a classe com o banco através das anotações. É isso?
Obrigado
Qual a maneira correta para fazer POJO's
38 Respostas
Cara, de maneira bem básica, é isso mesmo o que você falou, os atributos estão vinculados às colunas do banco de dados.
A questão de usar hbm.xml ou annotations está vinculada ao Hibernate. Ele evoluiu e permite que usemos annotations ao invés de xml (foi gerado um movimento chamado XML Hell, pois era de difícil manutenção).
Quanto ao POJO, como o link do nosso amigo ai em cima diz: Plain Old Java Objects…
Cara, se é OLD, eu não vejo motivos para usá-los. Hoje em dia o Hibernate consegue popular a sua classe sem que você tenha getters e setters, ele usa reflection para fazer isso.
Ou seja, pense bem antes de fazer um monte de getters e setters: qual a diferença real entre getters e setters e atributos públicos?
Hoje em dia o Hibernate permite que você crie métodos baseado na sua necessidade, e não na necessidade dele.
EDIT
Quanto à implementação de Serializable só é necessária quando você tem tabelas com IDs compostos…
Mas se não, só deve implementar quando VOCÊ precisar.
Não seria a importância do encapsulamento, da segurança?
Não seria a importância do encapsulamento, da segurança?
Sim, eu vejo que você deve criar seus objetos baseados na modelagem do seu sistema. Independente do framework que vai usar.
E um POJO é basicamente isso, é um objeto Java, que não sabe se será persistido com Hibernate, com JDBC, ou até se será persistido ou não.
Quanto à getters e setters isso sempre gera polêmica. Se seu modelo é anêmico, provavelmente vai ter eles pra todos os atributos da classe, agora se trabalha com um modelo mais rico, por ter um sistema modelado por DDD, aí provavelmente sua API terá mais métodos de negócio do que getters e setters em si.
Não seria a importância do encapsulamento, da segurança?
O Rodrigo falou MUITO bem!
Eu sou contra esse modelo mais anêmico que ele cita.
A ideia é encapsular, um monte de getters e setters não está encapsulando nada, não tem regras, não tem validações, não tem negócio e qualquer classe pode fazer o que quiser com essa instancia…
Mais ou menos assim:
public class ContaCorrente {
private double saldo;
private double limite;
// getters e setters
}
Para fazer um depósito nessa conta eu vou precisar lembrar de aumentar o saldo, se eu for fazer uma retirada eu vou precisar lembrar de verificar o limite e fazer a retirada…
Sem falar que se eu esquecer de verificar o limite, eu posso deixar o cara retirar 500 milhões da conta dele e tudo bem…
Para mim, a regra de negócio DEVE ficar nessas classes, quando fizerem sentido.
Rafael Guerreiro,
E se eu estiver usando um framework, como o Spring MVC, que usa esses getters e setters pra exibir os atributos dos objetos nas jsp?
Não seria a importância do encapsulamento, da segurança?
O Rodrigo falou MUITO bem!
Eu sou contra esse modelo mais anêmico que ele cita.
A ideia é encapsular, um monte de getters e setters não está encapsulando nada, não tem regras, não tem validações, não tem negócio e qualquer classe pode fazer o que quiser com essa instancia…
Mais ou menos assim:
public class ContaCorrente {
private double saldo;
private double limite;
// getters e setters
}
Para fazer um depósito nessa conta eu vou precisar lembrar de aumentar o saldo, se eu for fazer uma retirada eu vou precisar lembrar de verificar o limite e fazer a retirada…
Sem falar que se eu esquecer de verificar o limite, eu posso deixar o cara retirar 500 milhões da conta dele e tudo bem…
Para mim, a regra de negócio DEVE ficar nessas classes, quando fizerem sentido.
Desta maneira, você está dizendo que não precisamos trabalhar com outras classes, não é? Afinal, tudo ficará apenas no ‘POJO’.
A questão dos getters e setters é um pouco mais complexa que simplesmente encapsular. Ela está ligada a outros conceitos, como o $ERVER colocou. E não é preciso nem utilizar um framework de terceiro para isto, basta seguir o padrão java…
Do meu ponto de vista, a regra de negócios deve ficar isolada, permitindo que a manutenção seja mais simples e limpa possível.
Pois é, nesse caso, quando vamos trafegar informações diretamente entre o browser e o server (aonde entram os frameworks MVCs) é ideal que a gente use um tipo de objeto chamado DTO.
Ou seja, Data Transfer Object. É importante que você tenha 1 DTO para cada FUNCIONALIDADE, ou seja, uma mesma entidade pode ter vários DTOs.
Os maiores focos do DTO são:
1- Não afetar as regras de negócio (getters e setters atrapalham as regras);
2- Evitar o Mass Assignment, uma falha de segurança bastante preocupante.
drsmachado,
E quanto a esse isolamento das regras de negócio, você cria uma camada especificamente pra isso? Como ela fica?
Os dois únicos projetos que fiz aqui eram muito pequenos, então nem foi necessário chegar a esse nível de abstração, mas tenho muita curiosidade em aprender.
Caso tenha algum link que possa me clarear um pouco mais sobre o assunto, agradeço.
Abraços.
Desta maneira, você está dizendo que não precisamos trabalhar com outras classes, não é? Afinal, tudo ficará apenas no ‘POJO’.
A questão dos getters e setters é um pouco mais complexa que simplesmente encapsular. Ela está ligada a outros conceitos, como o $ERVER colocou. E não é preciso nem utilizar um framework de terceiro para isto, basta seguir o padrão java…
Do meu ponto de vista, a regra de negócios deve ficar isolada, permitindo que a manutenção seja mais simples e limpa possível.
Não que não devam existir outras classes, longe disso. A ideia é transformar um POJO “burro” em um VO útil e devidamente encapsulado. No caso essa outra classe seria um BO (Business Object), mas eu não acho legal, pois se uma classe pode fazer “o que bem entender” com esse objeto, outras classes também poderão, e ai temos um encapsulamento falho e vazado.
Sim, essa questão é bem mais complicada, quanto ao que o $ERVER colocou, existem soluções que conseguem garantir a integridade das nossas classes… Eu nunca recebo uma classe do tipo entidade diretamente nos controllers, para evitar o mass assignment. Uso sempre os DTOs que conseguem fazer esse trabalho…
Rafael Guerreiro,
Achei bem interessante os DTOs. Devemos implementar manualmente, ou existe alguma ferramenta que ajuda na criação deles?
Caraca, quanto mais eu estudo OO eu vejo que ela tá indo pro saco mesmo, pois quando é resolvido um problema dela, aparecem N outros. Ao menos é o que me parece no pouco tempo que tenho.
Abraços.
Não sei não, eu penso de uma forma parecida com o saoj a respeito de DTOs.
E, pela minha experiência, posso dizer, com todas as letras, que não existe bala de prata.
De qualquer forma, essa discussão vai acabar como as que são realizadas em torno dos DAOs…
Rafael Guerreiro,Achei bem interessante os DTOs. Devemos implementar manualmente, ou existe alguma ferramenta que ajuda na criação deles?
Caraca, quanto mais eu estudo OO eu vejo que ela tá indo pro saco mesmo, pois quando é resolvido um problema dela, aparecem N outros. Ao menos é o que me parece no pouco tempo que tenho.
Abraços.
Vamos lá, EU desconheço ferramentas e crio manualmente… Não vejo problemas nisso.
Um exemplo de como eu trabalho com DTOs:
public class User { // Entidade
private String username;
private String password;
private String name;
// Métodos que sabem o que fazer com cada DTO dos listados abaixo...
}
public class SignInUser { // DTO para a funcionalidade de login
private String username;
private String password;
}
public class UpdateUser { // DTO para a funcionalidade de alteração de dados cadastrais
private String nome;
}
public class ChangePasswordUser { // DTO para a funcionalidade de trocar de senha
private String oldPassword;
private String newPassword;
private String confirmNewPassword;
// Aqui faz validações de senha
}
A ideia, por exemplo, é evitar que o user consiga setar a propriedade password quando fizer uma requisição para trocar o username, somente…
Ou seja, se eu permito que a minha entidade seja setada “cegamente” pelos parametros passados pela requisição, eu posso permitir que ele sete coisas estranhas sem uma prévia validação.
Além de eu evitar que a minha action fique assim:
public void trocarDeSenha(String newPassword, String oldPassword, String confirmNewPassword){...}
Ela pode ficar um pouco mais elegante:
public void trocarDeSenha(ChangePasswordUser changePassword){...}
Não sei não, eu penso de uma forma parecida com o saoj a respeito de DTOs.
E, pela minha experiência, posso dizer, com todas as letras, que não existe bala de prata.
De qualquer forma, essa discussão vai acabar como as que são realizadas em torno dos DAOs…
Muito interessante esse tópico…
Mas existe uma coisa que eu concordo com o saoj, “Camada de serviços só pode trabalhar com modelo, entidades reais, nunca DTO.”
Também concordo que não existe bala de prata, e sim, isso é uma discussão que não vai ter fim, pois cada um trabalha do jeito que mais lhe convém.
Mas uma coisa para mim é fato: não gosto de expor minhas entidades, pois qualquer coisa que for feito nelas podem refletir no banco, causando problemas maiores.
Por isso, eu trabalho com DTOs dessa forma, o DTO chega na action e a entidade “absorve ele”…
Não sei não, eu penso de uma forma parecida com o saoj a respeito de DTOs.
E, pela minha experiência, posso dizer, com todas as letras, que não existe bala de prata.
De qualquer forma, essa discussão vai acabar como as que são realizadas em torno dos DAOs…
Muito interessante esse tópico…
Mas existe uma coisa que eu concordo com o saoj, “Camada de serviços só pode trabalhar com modelo, entidades reais, nunca DTO.”Também concordo que não existe bala de prata, e sim, isso é uma discussão que não vai ter fim, pois cada um trabalha do jeito que mais lhe convém.
Mas uma coisa para mim é fato: não gosto de expor minhas entidades, pois qualquer coisa que for feito nelas podem refletir no banco, causando problemas maiores.
Por isso, eu trabalho com DTOs dessa forma, o DTO chega na action e a entidade “absorve ele”…
Muito interessante esse tópico.
Rafael Guerreiro, você possui algum pequeno projeto que demostra a aplicação desses conceitos, que possa disponibilizar aqui o link??
Até mais.
Rafael Guerreiro,
Muito interessante. Você teria algum link de artigo ou qualquer coisa dando exemplos de uso de DTO e camadas de serviço também? Encontrei alguns mas parecem ser meio estranhos.
Obrigado.
Refazendo a pergunta: pra que serve a camada de serviço?
Obrigado, abraços.
Muito interessante esse tópico.
Rafael Guerreiro, você possui algum pequeno projeto que demostra a aplicação desses conceitos, que possa disponibilizar aqui o link??Até mais.
Olá Douglas, infelizmente eu não tenho nenhum projeto open source desse jeito… =/
Rafael Guerreiro,Muito interessante. Você teria algum link de artigo ou qualquer coisa dando exemplos de uso de DTO e camadas de serviço também? Encontrei alguns mas parecem ser meio estranhos.
Obrigado.
Na verdade muita coisa eu aprendi nesses cursos da Caelum, pode parecer merchan, mas eu recomendo fortemente. Tem também o Caelum Online que é uma versão minimalista do que passamos na sala de aula.
Acho que vale muito a pena investir em conhecimento, sendo que você pode vir a ter um cargo melhor…
Refazendo a pergunta: pra que serve a camada de serviço?Obrigado, abraços.
Tem uma coisa engraçada ai, eu só uso a camada de serviços em casos extremos…
A minha ideia é simples, cada classe tem um nome, esse nome diz o que ela faz. Se tem algum método fazendo algo que contradiz com aquele nome, ele é movido para alguma classe que faça sentido ou ele ganha uma classe só para ele…
A galera tenta economizar a criação de classes, eu acho isso horrível, quanto mais classes BEM FEITAS, mais específico estão suas classes, mais fácil de testar e de dar manutenção…
É comum eu criar muitas classes para problemas pequenos, algumas vezes o código fica tão bem separado que eu consigo fazer funcionalidades completamente genéricas.
Resumindo: eu corro de Services, Utils, POJO, Classes grandes, métodos com mais de 10 linhas, métodos que fazem mais de 1 coisa.
Existe uma colinha bem legal: se o nome da classe/método precisar de um E, está na hora de separar… Um exemplo tosco:
public void validaESalva(ClasseMarota cm) {
// Implementa o código de validação
// Manda o hibernate salvar no banco de dados
}
public void valida(ClasseMarota cm) {// Esse cara fica na classe que faz sentido tê-lo... Eu faria na própria entidade...
// Implementa o código de validação
}
public void salva(ClasseMarota cm) {
// Chama o valida
// Manda o hibernate salvar no banco de dados
}
Resumindo: eu corro de Services, Utils, POJO, Classes grandes, métodos com mais de 10 linhas, métodos que fazem mais de 1 coisa.
Isso me leva a perguntar, você trabalha com o que mesmo?
Resumindo: eu corro de Services, Utils, POJO, Classes grandes, métodos com mais de 10 linhas, métodos que fazem mais de 1 coisa.
Isso me leva a perguntar, você trabalha com o que mesmo?
Com Java… É Orientação à Objetos…
Usar Services, Utils e POJOs “burros” só significa que o código está errado de alguma forma… Mas é lógico que existem exceções.
O clássico StringUtils, por exemplo, nós precisamos usá-lo pois não podemos extender String e fazer com que implemente esses métodos para nós.
Repare que a maioria dos métodos “utils” da vida são static… Se está usando static, também significa que o código está errado de alguma forma. O static força você a voltar para o procedural.
Existem vários Design Patterns que auxiliam a gente a fazer um código decente colocando as regras de negócio em classes decentes.
Por exemplo, você deixaria um método no Service cheio de ifs ou preferiria usar um strategy para eliminar esses ifs?
Resumindo: eu corro de Services, Utils, POJO, Classes grandes, métodos com mais de 10 linhas, métodos que fazem mais de 1 coisa.
Isso me leva a perguntar, você trabalha com o que mesmo?
Com Java… É Orientação à Objetos…Usar Services, Utils e POJOs “burros” só significa que o código está errado de alguma forma… Mas é lógico que existem exceções.
O clássico StringUtils, por exemplo, nós precisamos usá-lo pois não podemos extender String e fazer com que implemente esses métodos para nós.
Repare que a maioria dos métodos “utils” da vida são static… Se está usando static, também significa que o código está errado de alguma forma. O static força você a voltar para o procedural.
Existem vários Design Patterns que auxiliam a gente a fazer um código decente colocando as regras de negócio em classes decentes.
Por exemplo, você deixaria um método no Service cheio de ifs ou preferiria usar um strategy para eliminar esses ifs?
Pergunto pois suas respostas me levam a crer que você jamais teve que dar manutenção em código legado.
Ou até, nunca teve de desenvolver um sistema onde as regras de negócio possuem complexidades extremas.
Já tive, como tenho.
Estou cheio de classes com regras de negócio complexas ao extremo, como sistemas de faturamentos…
Consegui graças ao TDD… Sim, eu faço testes.
Quanto ao código legado, é só começar a escrever testes para eles, refatorar e eles deixam de ser legados. Que é uma das boas práticas ao dar manutenção em código legado (leia-se código sem testes)…
Além de estarmos falando sobre maneiras corretas de fazer algo, e não maneiras legadas/fáceis/faz como dá…
Ou seja, Data Transfer Object. É importante que você tenha 1 DTO para cada FUNCIONALIDADE, ou seja, uma mesma entidade pode ter vários DTOs.
Rafael Guerreiro, então eu deixaria de usar o objeto que era POJO e coloco o DTO no model disponibilizado pra página?
Um exemplo - pegando um objeto da classe Conta e exibindo numa jsp:
public class Conta{
private String numero;
private double saldo;
public Conta() {
}
public void sacar(double quantia) {
if (quantia <= saldo) {
saldo = saldo - quantia;
}
}
public void depositar(double quantia) {
saldo = saldo + quantia;
}
//nada de getters e setters que já não são mais necessários para o framework
}
Eu não entendi como ficaria o DTO para cada funcionalidade. Seria um DTO para o método sacar e outro para depositar?
Quanto aos cursos das Caelum, quero fazer o fj21 ainda esse ano, me parece realmente muito bom. Concordo contigo, isso é investimento.
Muito obrigado pela atenção, abraços.
Rafael Guerreiro, usando seu exemplo:
public class User { // Entidade
private String username;
private String password;
private String name;
// Métodos que sabem o que fazer com cada DTO dos listados abaixo...
}
public class SignInUser { // DTO para a funcionalidade de login
private String username;
private String password;
}
public class UpdateUser { // DTO para a funcionalidade de alteração de dados cadastrais
private String nome;
}
public class ChangePasswordUser { // DTO para a funcionalidade de trocar de senha
private String oldPassword;
private String newPassword;
private String confirmNewPassword;
// Aqui faz validações de senha
}
Onde e como eu colocaria os métodos para exibir o nome e user name do usuário numa jsp?
Obrigado, abraços.
As classes ervece não fazem mais ou menos isso também?
Se você estiver 2 telas separadas, por exemplo, eu classifico como 2 funcionalidades, então sim, são 2 funcionalidades separadas…
Nesse caso eu uso o POJO mesmo, somente em casos onde eu serializo para JSON que eu uso DTO.
Eu me preocupo com 2 coisas: objetos preenchidos pelos dados que o usuário colocou no form e com serialização JSON…
Então, eu não me preocuparia com os getters (se fizerem sentido para você) na entidade, visto que estes não mudam o seu objeto (tome cuidado com a mutabilidade).
Mas então a minha lógica na classe Conta iria ser prejudicada. E se uso DTO com getters e setters, pra que o DTO? Acho que não entendi algo.
Agora acho que entendi, getter pode deixar pq não vai alterar o estado do objeto, portanto, não interfere nas regras de negócio. Mas mesmo assim ainda deixa um buraco: eles estão lá apenas pro framework - no meu caso - então a classe tem mais de uma responsabilidade - deixar os seus campos visíveis com os getters para o framework. O que você acha?
Acho que ainda não entendeu o principal ponto, vou fazer um exemplo clássico aqui:
public class Pessoa {
private String nome;
private String sobrenome;
public String getNomeCompleto(){
return nome + " " + sobrenome;
}
}
Na hora de pegar esse objeto na JSP vc faz assim:
Ou seja, o ponto é que VOCE precisa desse getter e não o framework…
Agora entendi! O objeto precisa ter a responsabilidade de retornar o nome dele, é isso mesmo?
Só mais uma coisa:
Eu nunca usei classes service, mas pelo pouco que vi, me parece que elas fazem mais ou menos o que os seus DTOs fazem: validação. Tem diferença entre os dois?
Já vi alguns tutoriais na internet com classes do tipo ClienteService, que faziam a validação do Cliente antes de inserir no banco ou qualquer outra coisa.
Nesse exemplo:
public class User { // Entidade
private String username;
private String password;
private String name;
// Métodos que sabem o que fazer com cada DTO dos listados abaixo...
}
public class SignInUser { // DTO para a funcionalidade de login
private String username;
private String password;
}
public class UpdateUser { // DTO para a funcionalidade de alteração de dados cadastrais
private String nome;
}
public class ChangePasswordUser { // DTO para a funcionalidade de trocar de senha
private String oldPassword;
private String newPassword;
private String confirmNewPassword;
// Aqui faz validações de senha
}
Não seria melhor, isso?
public class SignInUser { // DTO para a funcionalidade de login
private User user;
}
Não tem diferença olhando apenas esse ponto.
Os meus DTOs são usados para as validações… Mas, se fizer sentido, ele pode validar-se sim…
O ponto do Service e do Utils é que são classes “faztudo”, então, muitas vezes vc coloca métodos lá que não fazem sentidos.
Olhe a diferença entre 2 Services:
public class UserValidator {
// valida os dtos referentes aos usuários
}
public class UserService {
// valida os dtos referentes aos usuários
}
O NOME da segunda classe te diz que ela pode fazer muito mais que apenas validações. ESSE é o real problema.
A gente pode ter Utils, mas dê um nome decente à ele que diga que ele só pode fazer determinada ação.
O problema é que vc vai precisar implementar alguma coisa e vai tacar no UserService por que ele faz de tudo mesmo… Ai vc tem uma classe gigante e lotada de dependências, ou seja, uma classe mal planejada.
Eu acho que entendi. Vejamos:
DTO - ou Data Transfer Object - não o que eu pensava: um objeto usado apenas para pegar os dados - de um DAO, por exemplo - para disponibilizar para as jsp. Quem tem a responsabilidade de disponibilizar os valores dos seus campos é a própria classe - através dos métodos getters.
Tudo isso trata mais de conceito do que implementação mesmo? Tipo, eu devo separar melhor o que cada classe minha faz? Se preciso validar um login de usuario, crio uma classe LoginValidator, se preciso de validação pra alteração de senha, crio uma classe AlteracaoDeSenhaValidator?
Por um lado acho bem interessante, mas você percebeu que tudo isso trata apenas da parte estrutural de um sistema, não tendo nada a ver com o negócio?
E mais uma pergunta: nos meus controllers eu não devo nunca usar uma entidade (classe que tenha regras de negócio) diretamente, sempre usar um DTO pra validar quando os dados vem do usuário?
E se não vier do usuário, posso usar uma entidade (classe que tenha regras de negócio) diretamente?
Não seria melhor, isso?
public class SignInUser { // DTO para a funcionalidade de login private User user; }
Não… Visto que eu posso setar qualquer propriedade do user que está dentro do DTO… Se você for fazer isso, é melhor que nem tenha o DTO…
Eu acho que entendi. Vejamos:DTO - ou Data Transfer Object - não o que eu pensava: um objeto usado apenas para pegar os dados - de um DAO, por exemplo - para disponibilizar para as jsp. Quem tem a responsabilidade de disponibilizar os valores dos seus campos é a própria classe - através dos métodos getters.
Tudo isso trata mais de conceito do que implementação mesmo? Tipo, eu devo separar melhor o que cada classe minha faz? Se preciso validar um login de usuario, crio uma classe LoginValidator, se preciso de validação pra alteração de senha, crio uma classe AlteracaoDeSenhaValidator?
Por um lado acho bem interessante, mas você percebeu que tudo isso trata apenas da parte estrutural de um sistema, não tendo nada a ver com o negócio?
Sim, está tudo certo. Sim, é parte estrutural mesmo, é uma questão de organização de classes.
Sim, eu faço isso.
Sim, também. Desde que você saiba que quem está mexendo nessa entidade não vá estragar tudo…
Rafael Guerreiro,
Muito obrigado pela aula! Tirou todas as minhas dúvidas!
Grande abraço.
Rafael Guerreiro,
Já usou o Spring MVC? Ele usa os métodos setters para fazer o binding da visão com o modelo. Nesse caso sou obrigado a mudar de framework?
Abraços.
Segue um artigo sobre o assunto: http://www.arquiteturajava.com.br/livro/cuidado-com-o-modelo-anemico.pdf
Muito bom!