Persistir atributos privados

[quote=jprogrammer]Aí não vira uma gambi medonha.
O ideal é o hibernate persistir a classe em si, não o hashmap.[/quote]

Nao sei se eu perdi o fio da meada, mas o problema existe NAO utilizando o Hibernate. Com Hibernate voce pode persistir os atributos privados mesmo (ou seja la o que for que voce queira utilizar :D).

Marcio Kuchma

Equanto utilizar o hibernate não temos mais dúvidas.
Mas vamos supor que a persistencia é não relacional.

Porque o hashmap traz perda de performance tão grande ?

Usando o hashmap você fica dependente do desempenho do algoritmo de classificação que você esta implementando mo método hashcode de suas classes persistentes.

Talvez seja isso? É isso mesmo?

Abraços!
Thiago

Pegando embalo com o shoes…
E a possibilidade de ter várias implementações


abstract class Funcionario
{ 
    private int id;
    protected void setId(int id) { //omite codigo }
    public int getCodigo() {}

    public void salvar()
    {
        if (id == 0) {} // validacao e regras de negocio
     }
}

class FuncionarioHibernate extends Funcionario
{
    public void salvar()
   {
      setId(geraId()); 
     super.salvar();
      session.save(this);
   }
 
}

class FuncionarioOutraCoisa extends Funcionario
{
    public void salvar()
   {
      setId(geraId()); 
     super.salvar();
   }
}

class FuncionarioFactory
{
    public Funcionario getFuncionario()
    {
        return new FuncionarioHibernate();
    }
}

Funcionario f  = FuncionarioFactory.getgetFuncionario();
f.salvar();

Na minha opinião é muito mais limpo que DAOs. E fica melhor ainda com IoC ao invés de factories.

Mas aí acho que deve doer para controlar transações e evitar a proliferação de chamadas ao banco. Spring ajuda nisso?

Não vejo porque isso traria muitas chamadas ao banco.
Posso ter um factory global e controlar conexao e transação a partir dele.

Mas o que eu acho esquisito de classes que tem métodos de negócios é quando eu tenho agregação.


class Funcionario
{
   private Departamento departamento;
   public Departamento getDepartamento() {};

   public void salvar()
}

class Departamento 
{
   public void salvar()
}

Funcionario f = getFuncionario();
f.salvar().
f.getDepartamento().salvar() // esse método esquisito

Isso fica estranho ou é só frescura (rs…) ?

Tá estranho sim! Não seria melhor que dentro do método salvar de funcionario tivesse uma chamada para salvar o departamento?

Hmm, isso depende de como você quer implementar a semântica de cascateamento.

Se salvar o funcionario implica em salvar o departamento, sim.

Eu acho que manter o código que faz pensistencia no mesmo lugar que está o negocio uma caca.

E se a implementação de persistencia ficar toda separada em um objeto separado e se usar agregação/herança para dar acesso a esses dados no modelo.

O código não ficar mais claro com isso já que java não suporta herança múltipla nem visibilidade de herança (herança privada do c++ faz muita falta :cry: ).

No caso não estou salvando o departamento, apenas estou mostrando que ao agregar a classe Departamento a Funcionario o método de salvar
departamento também fica disponível.

Esse é o assunto do outro tópico.
Pelo conceito OO as operaçoes devem ficar juntas com os dados.
Se quisermos programar OO deve ficar mais ou menos parecido com isso.

Estão vendo como é difícil programar OO com relacional.
Várias coisas não se batem. São duas coisas que não se encaixam.
O pessoal meteu o pau no artigo da java magazine.

editado:
Tem outra coisa na classes que fazem as operações.
Os métodos de consulta.
É muito estranho criar uma instancia para depois obter instancias.
O ideal seria usar métodos estáticos para consulta.
Só que a herança já quebra.
Pois há somente “ocultação” não sobreposição.
ex:


class Funcionario
{
   public static Funcionario consultar() {}
}

class FuncionarioHibernate
{
   public static Funcionario consultar() { // oculta}
}

Mas exemplifique sua ideia louds.


class PersistentFuncionacio {
  private int xxx;
  private String yyy;

  //Setter/getters com bound properties
}


class Funcionario {
 private final PersistentFuncionacio f = new PersistentFuncionacio ();//ou via construtor


 public double salarioLíquito() {
   return f.getSalarioBruto * (1 - f.getDescontos());
 }
}

Para que isso? Bom, usando bound properties evitamos precisar chamar save/update explicitamente e delete em alguns casos. Além disso toda lógica e dados para falar com o banco de dados fica em lugar só.

E se eu quiser acessar diretamente um atributo que é pesistível como Nome (por ex) teria que duplicar sua declaração nas duas classes não é.

Pensei nisso. Vejam se é tosco !


package teste.funcionario;

abstract class Funcionario
{
   protected void setId(int id);
   public int getId() { return this.id } ;

   public void salvar() {
     // regras de negocio
   }
}


abstract class FuncionarioFactory
{
  public abstract Funcionario createNew();
  public abstract Funcionario find(int id);
  public static final FuncionarioFactory getInstance()
  {
    return new teste.funcionario.jdbc.FuncionariosJDBCFactory();
  }
}


package teste.funcionario.jdbc;

class FuncionariosJDBCFactory extends FuncionarioFactory
{
   public Funcionario createNew() {
      return new FuncionarioJDBC();
   }

   public Funcionario find(int id)
   {
     ResultSet rs = ....

     FuncionarioJDBC  f = new FuncionarioJDBC ();
     f.setId(rs.getInt("ID");
   }
}

class FuncionarioJDBC extends Funcionario
{
   protected void setId(int id) { super.setId(id) }

   public void salvar() {
      setId(geraId());
      super.salvar();
      insert into ....
   }
}

FuncionarioFactory fc = FuncionarioFactory.getInstance();
Funcionario f = fc.find(1);

// faz de conta que tem
f.setNome("Maria");
f.salvar();