Hiberntate + Gravar imagem no banco + Out of Memory Java Heape

Bom dia!
Estou com um problema sério e não estou conseguindo resolver!

O objetivo do meu sistema é gravar fotos de cliente no banco de dados(Postgres 8.4)

Tenho duas classe Pessoa e Pessoa Fotos!

1 pessoa pode ter mais que uma FOTO

Segue as classes

PESSOA

[code]import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.Fetch;
/**
*

  • @author Nilodp
    */
    @Entity
    @Table(name = “PESSOA”)
    //@Inheritance(strategy = InheritanceType.JOINED)
    @SequenceGenerator(name = “sequencia_pessoa”, sequenceName = “sequencia_pessoa”, initialValue = 1, allocationSize = 1)
    public class Pessoa implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = “sequencia_pessoa”)
    private Long id;
    @Column(name = “DTNASC”)
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date dtNasc;
    @Column(name = “CPF”, length = 20)
    private String cpf;
    @Column(name = “RG”, length = 14)
    private String rg;
    @Column(name = “NOME”, length = 60)
    private String nome;
    @Column(name = “SEXO”, length = 1)
    private String sexo;
    @Column(name = “ENDERECO”, length = 50)
    private String endereco;
    @Column(name = “NRO”, length = 10)
    private String nro;
    @Column(name = “COMPLEMENTO”, length = 60)
    private String complemento;
    @Column(name = “CEP”, length = 12)
    private String cep;
    @JoinColumn(name = “CIDADE_ID”, referencedColumnName = “ID”)
    @ManyToOne(targetEntity = Cidade.class)
    private Cidade cidade;
    @Column(name = “BAIRRO”, length = 60)
    private String bairro;
    @Column(name = “FONE_FIXO”, length = 14)
    private String foneFixo;
    @Column(name = “FONE_MOVEL”, length = 14)
    private String foneMovel;
    @Column(name = “EMAIL”, length = 150)
    private String email;
    @Column(name = “PROFISSAO”, length = 150)
    private String profissao;
    @Column(name = “OBSERVACAO”, length = 700)
    private String observacao;
    @Column(name = “DH_CADASTRO”)
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date dhCadastro;
    @Column(name = “DH_ULT_ALTERACAO”)
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date dhUltAlteracao;
    @Column(name = “INATIVO”, length = 1)
    private String inativo;
    @OneToMany(mappedBy=“pessoa”, fetch = FetchType.EAGER)
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    @Fetch(org.hibernate.annotations.FetchMode.SELECT)
    private List pessoasFotos = new ArrayList();

    /Anamnese/[/code]

PESSOAFOTOS

[code]import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

/**
*

  • @author Danilo
    */
    @Entity
    @Table(name = “PESSOAFOTOS”)
    @SequenceGenerator(name = “sequencia_foto”, sequenceName = “sequencia_foto”, initialValue = 1, allocationSize = 1)
    public class PessoaFotos implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = “sequencia_foto”)
    private Long id;
    @ManyToOne(targetEntity = Pessoa.class, fetch=FetchType.LAZY)
    @Fetch(FetchMode.JOIN)
    @JoinColumn(name=“pessoa_id”)
    private Pessoa pessoa;
    @Column(name = “descricaofoto”)
    private String descricaoFoto;
    private byte[] foto;
    @Transient
    private Boolean visualizarFoto = new Boolean(false);
    [/code]

Bom vamos ao problema

As classes acima funciona perfeitamente!

O problema é que quando uma pessoa tem fotos com tamanhos GRANDES(3 ou 4 fotos de 2 megas cada) acontece o erro abaixo!

Ou quando eu tento excluir varias fotos ao mesmo tempo

Segue o código da EXCLUSÃO

[b]private void excluirFoto() { Object[] options = {"Sim", "Não"}; int op = JOptionPane.showOptionDialog(this, "Confirma exclusão da(s) foto(s) selecionada(s)?", "Excluir?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); if (op == JOptionPane.YES_OPTION) { try { /* O que ocorre é que uma lista não pode ser iterada e modificada ao mesmo tempo, quero dizer, você não pode alterar uma lista e depois chamar next() no Iterator. Isto porque o Iterator pode perder a consistência, repetindo o mesmo elemento ou pulando algum. Para resolver isso, você pode criar uma cópia da lista, e iterar esta cópia, enquanto faz as modificações na lista original: * */ List list = pessoa.getPessoasFotos(); Iterator i = new ArrayList(pessoa.getPessoasFotos()).iterator(); // cria o iterator a partir da cópia while (i.hasNext()) { PessoaFotos itens = (PessoaFotos) i.next(); if (itens.getVisualizarFoto() == true) { //compara a copia com a condição especificado, caso verdadeiro eu removo da lista original pessoa.getPessoasFotos().remove(itens); //list.remove(itens); controlePessoa.excluirFoto(itens); //controlePessoa.excluirFotosPost(itens); } } montaTabelaFotos(pessoa.getPessoasFotos()); TabelaConsultaFotos.updateUI(); list = null; i = null; } catch (Exception ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(this, "Erro ao excluir a foto " + ex, "Erro", JOptionPane.ERROR_MESSAGE); } } }[/b]

log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version). log4j:WARN Please initialize the log4j system properly. Exception occurred during event dispatching: java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:2882) at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:572) at java.lang.StringBuilder.append(StringBuilder.java:203) at java.util.AbstractMap.toString(AbstractMap.java:492) at org.hibernate.pretty.Printer.toString(Printer.java:82) at org.hibernate.pretty.Printer.toString(Printer.java:113) at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:120) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:49) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027) at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365) at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137) at br.com.blackline.utils.HibernateUtility.commitTransaction(HibernateUtility.java:78) at br.com.blackline.dao.DaoHibernateGenerico.delete(DaoHibernateGenerico.java:35) at br.com.blackline.controle.ControlePessoa.excluirFoto(ControlePessoa.java:60) at br.com.blackline.formulario.cadastros.FormularioPessoa.excluirFoto(FormularioPessoa.java:3035) at br.com.blackline.formulario.cadastros.FormularioPessoa.botaoExcluirfotoActionPerformed(FormularioPessoa.java:1852) at br.com.blackline.formulario.cadastros.FormularioPessoa.access$2100(FormularioPessoa.java:39) at br.com.blackline.formulario.cadastros.FormularioPessoa$20.actionPerformed(FormularioPessoa.java:1259) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236) at java.awt.Component.processMouseEvent(Component.java:6263) at javax.swing.JComponent.processMouseEvent(JComponent.java:3267) at java.awt.Component.processEvent(Component.java:6028) at java.awt.Container.processEvent(Container.java:2041) at java.awt.Component.dispatchEventImpl(Component.java:4630) at java.awt.Container.dispatchEventImpl(Container.java:2099) at java.awt.Component.dispatchEvent(Component.java:4460) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)

Então pessoal não sei oque esta causando esse erro!

Se é erro no mapiamento das classe pessoa com a pessoaFotos Usando o EAGER E O LAZY

Por favor alguém me ajude!

Obrigado!

Aparentemente a memoria da sua virtual machine acabou.

Tente aumentar o tamanho da memoria da VM.

Tente utilizar o fetch = FetchType.LAZY.

Realmente é necessario efetuar uma copia para iterar o objeto?

Tente efetuar essas pequenas mudanças e veja se funciona.

Abraço.

Aumente o heap space da sua JVM antes de tudo via:

-Xms256m -Xmx512m

Onde -Xms seria o espaço inicial de alocação de memória pela JVM e -Xmx o espaço máximo.