Problema herança de Pessoa para Pessoa Física e Jurídica, usando Hibernate

4 respostas
BrunoGarciaDaSilva
BrunoGarciaDaSilva:
Galera to precisando de uma ajuda grande: Seguinte: tenho 3 classes, Pessoa, Pessoa Física e Pessoa Jurídica. Elas estão mapeadas corretamente nas minhas classes. Porém na hora que peço para salvar no banco de dados, dá o seguinte erro:
1016 [AWT-EventQueue-0] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 0, SQLState: 23502
1016 [AWT-EventQueue-0] ERROR org.hibernate.util.JDBCExceptionReporter - ERROR: null value in column "pes_nome" violates not-null constraint
1016 [AWT-EventQueue-0] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not insert: [classes.PessoaFisica]
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2295)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2688)
        at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
        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 DAOGenerico.DAOGenerico.inserirRegistro(DAOGenerico.java:29)
        at interfaces.telaCadClientes.salvarActionPerformed(telaCadClientes.java:822)
        at interfaces.telaCadClientes.access$900(telaCadClientes.java:31)
        at interfaces.telaCadClientes$10.actionPerformed(telaCadClientes.java:632)
        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.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:273)
        at java.awt.Component.processMouseEvent(Component.java:6038)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3260)
        at java.awt.Component.processEvent(Component.java:5803)
        at java.awt.Container.processEvent(Container.java:2058)
        at java.awt.Component.dispatchEventImpl(Component.java:4410)
        at java.awt.Container.dispatchEventImpl(Container.java:2116)
        at java.awt.Component.dispatchEvent(Component.java:4240)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
        at java.awt.Container.dispatchEventImpl(Container.java:2102)
        at java.awt.Window.dispatchEventImpl(Window.java:2429)
        at java.awt.Component.dispatchEvent(Component.java:4240)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Caused by: org.postgresql.util.PSQLException: ERROR: null value in column "pes_nome" violates not-null constraint
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1548)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1316)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:191)
Erro no método inserirRegistro: org.hibernate.exception.ConstraintViolationException: could not insert: [classes.PessoaFisica]
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:351)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:305)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2278)
        ... 40 more
org.hibernate.exception.ConstraintViolationException: could not insert: [classes.PessoaFisica]
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2295)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2688)
        at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
        at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
        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 DAOGenerico.DAOGenerico.inserirRegistro(DAOGenerico.java:29)
        at interfaces.telaCadClientes.salvarActionPerformed(telaCadClientes.java:822)
        at interfaces.telaCadClientes.access$900(telaCadClientes.java:31)
        at interfaces.telaCadClientes$10.actionPerformed(telaCadClientes.java:632)
        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.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:273)
        at java.awt.Component.processMouseEvent(Component.java:6038)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3260)
        at java.awt.Component.processEvent(Component.java:5803)
        at java.awt.Container.processEvent(Container.java:2058)
        at java.awt.Component.dispatchEventImpl(Component.java:4410)
        at java.awt.Container.dispatchEventImpl(Container.java:2116)
        at java.awt.Component.dispatchEvent(Component.java:4240)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
        at java.awt.Container.dispatchEventImpl(Container.java:2102)
        at java.awt.Window.dispatchEventImpl(Window.java:2429)
        at java.awt.Component.dispatchEvent(Component.java:4240)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Caused by: org.postgresql.util.PSQLException: ERROR: null value in column "pes_nome" violates not-null constraint
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1548)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1316)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:191)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:351)
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:305)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2278)
        ... 40 more
Acusa que o PES_NOME está com o valor nulo, mas foi digitado na tela da minha aplicação. Agora vou colcar o código de salvamento desses dados:
private void salvarActionPerformed(java.awt.event.ActionEvent evt) {                                       
        try
        {
            PessoaFisica pessoa = new PessoaFisica();
            pessoa.setPesNome(tfNomePessoa.getText());
            pessoa.setPesCadastro(ftfDataCadastro.getText());            
                                                                            
            pessoa.setPesFisCpf(ftfCpf.getText());            
            pessoa.setPesFisRg(ftfRg.getText());        
                      
            
            /*PessoaFisica pessoaFisica = new PessoaFisica();
            pessoaFisica.setPesNome(tfNome.getText());
            pessoaFisica.setPesCadastro(ftfDataCadastro.getText());
            pessoaFisica.setPesFisCpf(ftfCpf.getText());
            pessoaFisica.setPesFisRg(ftfRg.getText());            */
            
            Endereco endereco = new Endereco();
            endereco.setEndLogradouro(tfLogradouro.getText());
            endereco.setEndNumero(Integer.parseInt(tfNumero.getText()));
            endereco.setEndBairro(cbBairro.getSelectedItem().toString());
            endereco.setEndReferencia(tfReferencia.getText());
            endereco.setEndComplemento(tfComplemento.getText());
            endereco.setEndEstado(cbEstado.getSelectedItem().toString());
            endereco.setEndCep(ftfCep.getText());
            endereco.setEndCidade(cbCidade.getSelectedItem().toString());
            endereco.setPesEndereco(pessoa);
            
            Contato contato = new Contato();
            contato.setContTelContato(ftfTelContato.getText());
            contato.setContTelComercial(ftfTelComercial.getText());
            contato.setContCelular(ftfCelular.getText());
            contato.setContEmail(tfEmail.getText());
            contato.setPesContato(pessoa);
            
            //adicionando o valor do atributo endereço para a Classe pessoa
            pessoa.setEndPessoa(new HashSet<Endereco>());
            pessoa.getEndPessoa().add(endereco);
            
            //adicionando o valor do atributo contato para a Classe pessoa
            pessoa.setContPessoa(new HashSet<Contato>());
            pessoa.getContPessoa().add(contato);   
                        
            DAOGenerico daoPessoa = new DAOGenerico();
            daoPessoa.inserirRegistro(pessoa);  
            
            
            
            JOptionPane.showMessageDialog(null, "Cadastro salvo com sucesso!!!", "Mensagem", JOptionPane.INFORMATION_MESSAGE);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

Agora segue os mapeamentos feitos nas duas classes: Pessoa e Pessoa Física:

@Entity
@Table(name="pessoa")
@Inheritance(strategy=InheritanceType.JOINED)
@SequenceGenerator(name= "pessoa_pes_cod_seq", sequenceName="pessoa_pes_cod_seq", allocationSize=1)
public class Pessoa implements Serializable{
    
    //declaração das variáveis privadas    
    @Id    
    @GeneratedValue(generator="pessoa_pes_cod_seq")
    @Column(name="pes_cod")
    private int pesCodigo;
    
    @Column(name="pes_nome")
    private String pesNome; 
    
    @Column(name="pes_info_adicionais")
    private String pesInfoAdicionais;
    
    @Column(name="pes_data_cadastro")    
    private String pesCadastro;
    
    @OneToMany(mappedBy="pesEndereco", fetch=FetchType.LAZY)    
    @Cascade(CascadeType.ALL) 
    private Collection<Endereco> endPessoa;
    
    @OneToMany(mappedBy="pesContato", fetch=FetchType.LAZY)
    @Cascade(CascadeType.ALL) 
    private Collection<Contato> contPessoa;
@Entity
@Table(name="pessoafisica")
@PrimaryKeyJoinColumn(name="pes_cod")
public class PessoaFisica extends Pessoa implements Serializable{   
        
    //declaração das variáveis privada        
    @Column(name="pes_cod", insertable=false, updatable=false)
    private int pesCodigo;
    
    @Column(name="pes_fis_cpf")
    private String pesFisCpf;
    
    @Column(name="pes_fis_sexo")
    private String pesFisSexo;
    
    @Column(name="pes_fis_rg")
    private String pesFisRg;
    
    @Column(name="pes_fis_data_nasc")
    private String pesFisDataNasc;
    
    @Column(name="pes_fis_profissao")
    private String pesFisProfissao;

4 Respostas

Andre_JavaWorld

Ola,

Acho que voce deveria refatorar um pouco seu relacionamento, voce precisa realmente de uma tabela pessoa? sua classe pessoa esta apenas "abstraindo", eu pelo menos faço sempre pessoa como classe abstrata, assim minhas outras classes herdam os dados dela, mas ela em si nao vai para o banco de dados, eu nao quero uma pessoa la, quero funcionarios no banco, quero clientes, etc, porem, preciso de uma pessoa no projeto por orientacao a objetos, e para nao ter que repetir os campos em cada classe.

Abraços

André

T

também acho que não é necessario criar a tabela pessoa…

dexa ela mapedBySuperClass

e usa as outras classes sem ID… dai vc pega o id da pessoa!!!
flw

BrunoGarciaDaSilva

Valew pessoal, entendi o que vcs quiseram me dizer, mas minha tabela pessoa tem que existir, pq ela se relaciona com outras tabelas no meu modelo, como endereço e contato, que são também tabelas independentes no banco de dados. Por isso fiz o relacionamento, com a tabela pessoa, fisica, e juridica independentes. que é a herança por subclasses.

O Hibernate faz esse relacionamento, só não entendi o erro. Estranho. Vcs tem alguma idéia???

Obrigadão gente, valew.

Paulo_Silveira

Oi Bruno

O erro nao tem relacao com a heranca: o campo pes_nome nao esta sendo preenchido, e no schema do seu banco esta como NOT NULL. Entao popule-o antes do flush/commit.

abracos!

Criado 19 de setembro de 2009
Ultima resposta 20 de set. de 2009
Respostas 4
Participantes 4