Erro com JPA

13 respostas
G

Boa Tarde Pessoal…
Estou estudando JPA e não estou conseguindo entender o erro em meu programa.
Procurei muito a solução e até o momento não consegui fazer funcionar. Espero que alguém possa me ajudar por aqui.
Estou usando Mysql como bd.
Segue abaixo a criação das tabelas no banco.

Tabela Cadastro

CREATE TABLE  `Teste`.`Cadastro` (
  `Id` int(10) unsigned NOT NULL auto_increment,
  `testeCadastro` varchar(100) default NULL,
  PRIMARY KEY  (`Id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=latin1

Tabela Pessoa

CREATE TABLE  `Teste`.`Pessoa` (
  `IdCadastro` int(10) unsigned NOT NULL,
  `teste` varchar(50) default NULL,
  PRIMARY KEY  (`IdCadastro`),
  CONSTRAINT `new_fk_constraint` FOREIGN KEY (`IdCadastro`) REFERENCES `Cadastro` (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Minhas Entidades geradas pelo NetBeans:
Cadastro

package model;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
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.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "Cadastro")
@NamedQueries({@NamedQuery(name = "Cadastro.findAll", query = "SELECT c FROM Cadastro c"), @NamedQuery(name = "Cadastro.findById", query = "SELECT c FROM Cadastro c WHERE c.id = :id"), @NamedQuery(name = "Cadastro.findByTesteCadastro", query = "SELECT c FROM Cadastro c WHERE c.testeCadastro = :testeCadastro")})
public class Cadastro implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "Id")
    private Integer id;
    @Column(name = "testeCadastro")
    private String testeCadastro;
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "cadastro", fetch = FetchType.LAZY)
    private Pessoa pessoa;

    public Cadastro() {
    }

    public Cadastro(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTesteCadastro() {
        return testeCadastro;
    }

    public void setTesteCadastro(String testeCadastro) {
        this.testeCadastro = testeCadastro;
    }

    public Pessoa getPessoa() {
        return pessoa;
    }

    public void setPessoa(Pessoa pessoa) {
        this.pessoa = pessoa;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Cadastro)) {
            return false;
        }
        Cadastro other = (Cadastro) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "model.Cadastro[id=" + id + "]";
    }

}

Pessoa

package model;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "Pessoa")
@NamedQueries({@NamedQuery(name = "Pessoa.findAll", query = "SELECT p FROM Pessoa p"), @NamedQuery(name = "Pessoa.findByIdCadastro", query = "SELECT p FROM Pessoa p WHERE p.idCadastro = :idCadastro"), @NamedQuery(name = "Pessoa.findByTeste", query = "SELECT p FROM Pessoa p WHERE p.teste = :teste")})
public class Pessoa implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "IdCadastro")
    private Integer idCadastro;
    @Column(name = "teste")
    private String teste;
    @JoinColumn(name = "IdCadastro", referencedColumnName = "Id", insertable = false, updatable = false)
    @OneToOne(optional = false, fetch = FetchType.LAZY)
    private Cadastro cadastro;

    public Pessoa() {
    }

    public Pessoa(Integer idCadastro) {
        this.idCadastro = idCadastro;
    }

    public Integer getIdCadastro() {
        return idCadastro;
    }

    public void setIdCadastro(Integer idCadastro) {
        this.idCadastro = idCadastro;
    }

    public String getTeste() {
        return teste;
    }

    public void setTeste(String teste) {
        this.teste = teste;
    }

    public Cadastro getCadastro() {
        return cadastro;
    }

    public void setCadastro(Cadastro cadastro) {
        this.cadastro = cadastro;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (idCadastro != null ? idCadastro.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Pessoa)) {
            return false;
        }
        Pessoa other = (Pessoa) object;
        if ((this.idCadastro == null && other.idCadastro != null) || (this.idCadastro != null && !this.idCadastro.equals(other.idCadastro))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "model.Pessoa[idCadastro=" + idCadastro + "]";
    }

}

Meu arquivo de configuração:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="teste" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>model.Pessoa</class>
    <class>model.Cadastro</class>
    <properties>
      <property name="eclipselink.jdbc.password" value="root"/>
      <property name="eclipselink.jdbc.user" value="root"/>
      <property name="eclipselink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
      <property name="eclipselink.jdbc.url" value="jdbc:mysql://localhost:3306/Teste"/>
    </properties>
  </persistence-unit>
</persistence>

E finalmente meu programa:

import controller.Controlador;
import model.Cadastro;
import model.Pessoa;

public class Main {
    public static void main(String[] args) {

        Cadastro cad = new Cadastro();
        cad.setTesteCadastro("teste cadastro");

        Pessoa pes = new Pessoa();
        pes.setTeste("teste pessoa");

        cad.setPessoa(pes);
        pes.setCadastro(cad);

        Controlador c = new Controlador();
        c.create(cad);

    }
}

O erro que ocorre é este:

[EL Info]: 2009.04.12 12:54:01.303--ServerSession(22293109)--EclipseLink, version: Eclipse Persistence Services - 1.0.1 (Build 20080905)
[EL Info]: 2009.04.12 12:54:01.708--ServerSession(22293109)--file:/home/gilson/Desktop/JavaApplication6/src/-teste login successful
[EL Warning]: 2009.04.12 12:54:02.078--UnitOfWork(7860099)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 1.0.1 (Build 20080905)): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'IdCadastro' cannot be null
Error Code: 1048
Call: INSERT INTO Pessoa (IdCadastro, teste) VALUES (?, ?)
        bind => [null, teste pessoa]
Query: InsertObjectQuery(model.Pessoa[idCadastro=null])
javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 1.0.1 (Build 20080905)): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'IdCadastro' cannot be null
Error Code: 1048
Call: INSERT INTO Pessoa (IdCadastro, teste) VALUES (?, ?)
        bind => [null, teste pessoa]
Query: InsertObjectQuery(model.Pessoa[idCadastro=null])
        at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)
        at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
        at controller.Controlador.create(Controlador.java:24)
        at javaapplication6.Main.main(Main.java:20)
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 1.0.1 (Build 20080905)): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'IdCadastro' cannot be null
Error Code: 1048
Call: INSERT INTO Pessoa (IdCadastro, teste) VALUES (?, ?)
        bind => [null, teste pessoa]
Query: InsertObjectQuery(model.Pessoa[idCadastro=null])
        at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:313)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:757)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:823)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:557)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:500)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeCall(AbstractSession.java:855)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:204)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:190)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:325)
        at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:163)
        at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:178)
        at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:465)
        at org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:80)
        at org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:90)
        at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:290)
        at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
        at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:666)
        at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:585)
        at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:114)
        at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:86)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2587)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1178)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1162)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1108)
        at org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:254)
        at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsForClassWithChangeSet(CommitManager.java:229)
        at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:185)
        at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:3129)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1241)
        at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:478)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1330)
        at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:159)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1002)
        at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:84)
        ... 3 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'IdCadastro' cannot be null
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
        at com.mysql.jdbc.Util.getInstance(Util.java:381)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3491)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3423)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2542)
        at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1734)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2019)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1937)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1922)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:748)
        ... 35 more
Exception in thread "main" java.lang.IllegalStateException: 
Exception Description: No transaction is currently active
        at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.rollback(EntityTransactionImpl.java:122)
        at controller.Controlador.create(Controlador.java:28)
        at javaapplication6.Main.main(Main.java:20)
Java Result: 1
BUILD SUCCESSFUL (total time: 1 second)

Por favor, já estou ficando louco com isso, e o pior é que deve ser algo muito simples. Espero que vocês possam me dar uma luz.

Obrigado

13 Respostas

E

Na classe Pessoa esta faltando o

@GeneratedValue(strategy = GenerationType.IDENTITY)

no atributo idCadastro

@Column(name = "IdCadastro") private Integer idCadastro;

da uma olhada no erro :

esta tentando adicionar null em um campo que esta marcado para nãp ser null

G

Boa tarde edilson_x,

Testei sua sugestão e mesmo assim não deu certo.

Este campo deve ser o mesmo gerado pela classe Cadastro, ou seja, um relacionamento do tipo onetoone. Na tabela pessoa ele não é identity e sim fk da tabela cadastro.

Tem alguma outra sugestão?

Obrigado pela resposta

R

Tenta mudar para o GenerationType para Auto…

GenerationType.AUTO

G

Boa tarde rdgms
Já testei também AUTO e nada.

Tem mais alguma idéia?
Obrigado pela resposta

R

Como que esta o campo IdCadastro no banco de dados???

G

Na tabela cadastro ele é pk e identity e na tabela pessoa é pk e possui relacionamento com a tabela cadastro

G

Ninguém mais pode dar uma dica? Eu quero que ao gerar o campo identity na tabela de cadastro, o mesmo também seja atribuido na tabela Pessoa.

Obrigado

G

Pesquisando um pouco sobre JPA, me parece que não está sendo muito bem aceito no mercado. Vocês concordam com isso?

W

[color=darkblue]
Faz o seguinte… em vez de AUTO ou IDENTITY, use SEQUENCE…

o meu funcionou… 8)[/color]

R

alguem sabe como fazer o handle de MySQLIntegrityConstraintViolationException?
Ou melhor, tratar a internal exception da RollbackException?

A

me diga uma coisa, essas classes foram criadas na mão ou foi alguma ferramenta que gerou pra vc?

R

Descobri como fazer:

public void create(EntityUsuario u) {

try{

em.getTransaction().begin();

em.persist(u);

em.getTransaction().commit();

}catch(RollbackException rollback_error){

Throwable t;

t=rollback_error.getCause();              /// t=oracle.toplink.essentials.exceptions.DatabaseException

if(t.getCause() instanceof MySQLIntegrityConstraintViolationException){

System.out.println(Tratar erro aqui);

}

}

}
A

muito bem, agora coloque no topico como resolvido.
Edite o seu primeiro post e coloca ao final o ou começo do titulo do topico [RESOLVIDO]…

Criado 12 de abril de 2009
Ultima resposta 26 de abr. de 2010
Respostas 13
Participantes 6