O Hibernate utiliza os gets e sets para poder ler e escrever os dados dos atributos.
Se o atributo for private, é impossível uma outra classe (como, por exemplo, o controlador do hibernate) acessar seus dados, nem mesmo usando Reflection (receberiamos algo como IllegalAccessException).
Não li o tópico do link fornecido mas estava lendo os posts do pessoal e vi que muitos não tem conhecimento do que eh OO realmente (pelo menos no que diz respeito apenas ao encapsulamento, já que OO não se resume a isso e ficaria muito grande - mais do que já está - falar sobre isso agora). Sugerir que seja feito acesso direto a atributos de uma classe é algo inaceitável. Fornecer apenas get/set não garante o total encapsulamento de uma classe, mas, como já foi dito, pelo menos encapsula a estrutura interna da classe. Quando outras classes só tem acesso aos métodos de uma classe, ela não sabe nem mesmo se realmente existe um atributo (poderia ter um metodo getIdade() sem nem sequer ter um atributo idade, por exemplo)
Encapsulamento não é algo a ser aplicado apenas a uma classe… muitos pensam apenas em relação a classe… vendo o encapsulamento de uma classe, seria simplesmente vc manter o que diz respeito a classe visível a ela apenas. Mas tb existe encapsulamento de módulos… dependendo da modelagem, é possível termos classes com membros de acesso default (sem modificador de acesso) para que os mesmos sejam acessados por outras classes de um mesmo pacote… isso varia de projeto pra projeto (embora o grande uso na prática seja do encapsulamento de classe apenas)
Na verdade o fato de tornar membros privados e fornecer metodos publicos de acesso não é nem encapsulamento em si… isso é apenas o conceito de information hiding, onde escondemos a estrutura interna da classe, como o proprio nome sugere.
Para de fato encapsularmos a classe é necessário disponibilizarmos para fora apenas métodos que façam parte do serviços que a classe oferece. Assim sendo, a primeira coisa a se fazer eh esconder os atributos. A segunda coisa é só criar metodos de acesso para aqueles atributos que faça sentido serem visíveis para fora da classe.
Um exemplo clássico da desvantagem de utilizar os atributos como public foi o “bug do milênio”, onde os anos eram representados por uma estrutura de 2 digitos… essa informacao da estrutura da classe estava disponivel para todo mundo… todos acessavam o atributo ano que tem 2 digitos… quando o ano 99 estava para virar 00 se mantivesse do jeito q estava, seria como se fosse o ano 1900, entao tornou-se necessario mudar o tipo do dado para pelo menos 4 digitos… com essa mudanca, como tudo ao redor tinha conhecimento da implementacao, todos os aplicativos foram atingidos e por isso teve uma grande preocupacao para nao quebrar outros pontos de diversas aplicacoes…
Resumindo a historia do bug, se ao inves de termos algo equivalente a
*** nesse exemplo, não estou usando sintaxe de java… os colchetes não estão representando um array…
*** imagine que é um tipo numérico e entre colchetes é informado o tamanho de dígitos.
public int[2] ano;
tivéssemos:
private int[2] ano;
public int[2] getAno(){ ... }
public void setAno(int[2] ano){ ... }
quando houve a necessidade da mudanca, soh precisariamos ter feito a seguinte alteracao:
private int[5] ano; //mudou aqui, mas isso fica interno e nao afeta nada la fora.
//mantém o método que todas as aplicações estavam chamando
public void setAno(int[2] ano){
//inclui logica pra converter o ano de 2 digitos pra 5 digitos
//ex. algo como this.ano = Integer.parseInt("019" + ano);
}
//mantém o método que todas as aplicações estavam chamando
public int[2] getAno(){
//inclui logica pra converter o ano de 5 digitos pra 2 digitos
}
//método a ser chamado após o ano 2000
public int[5] getAno(){ ... }
//método a ser chamado após o ano 2000
public void setAno(int[5] ano){ ... }
Tb é importante ressaltar que não é qualquer validação que deve ser colocada dentro dos sets. Apenas aquelas que são internas à classe. O ideal é fazer certos tipos de validação em um outro nível. Algo como se alguém chegou a chamar o setXXX é porque alguma camada acima já validou os dados e eu devo simplesmente atualizar o valor (mas muitas vezes isso é uma decisão de projeto).