Tenho uma tabela n para n onde tenho uma 3º tabela que serve como ponte entre as 2 possuindo o id da tabela 1(ex: ‘Estado’), e o id da tabela 2(ex: ‘Pais’) e também um 3º atributo que será a descrição, tenho um formulário que cadastra os itens da tabela 1 e também pode adicionar itens da tabela 2 pré-cadastrados junto com a descrição guardando esses dados em uma List que fica dentro do objeto da tabela 1, quando tento fazer um update em uma cadastro da tabela 1 e adiciona os itens da List tudo salva certinho na tabela 3, porém quando tento criar um novo cadastro e salvar com uma List(que contenha pelo menos 1 objeto), o seguinte erro ocorre:
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`teste`.`estado_pais`, CONSTRAINT `fk_estado` FOREIGN KEY (`id_estado`) REFERENCES `estado` (`id`))
Error Code: 1452
Call: INSERT INTO estado_pais (descricao, id_pais, id_estado) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: InsertObjectQuery(br.com.entity.EstadoPais[ estadoPaisPK=br.com.entity.EstadoPaisPK[ idPais=1, idEstado=0 ] ])
23/09/2011 10:02:20 br.com.persistence.BaseDAO create
SEVERE: null
javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`teste`.`estado_pais`, CONSTRAINT `fk_estado` FOREIGN KEY (`id_estado`) REFERENCES `estado` (`id`))
Error Code: 1452
Call: INSERT INTO estado_pais (descricao, id_pais, id_estado) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: InsertObjectQuery(br.com.entity.EstadoPais[ estadoPaisPK=br.com.entity.EstadoPaisPK[ idPais=1, idEstado=0 ] ])
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 br.com.persistence.BaseDAO.create(BaseDAO.java:48)
at teste2jpa.Teste2JPA.main(Teste2JPA.java:40)
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`teste`.`estado_pais`, CONSTRAINT `fk_estado` FOREIGN KEY (`id_estado`) REFERENCES `estado` (`id`))
Error Code: 1452
Call: INSERT INTO estado_pais (descricao, id_pais, id_estado) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: InsertObjectQuery(br.com.entity.EstadoPais[ estadoPaisPK=br.com.entity.EstadoPaisPK[ idPais=1, idEstado=0 ] ])
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:798)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:864)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:583)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:526)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1729)
at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:234)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:207)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:193)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:342)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:162)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:177)
at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:469)
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:291)
at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:808)
at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:711)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2842)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1521)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1503)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1463)
at org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:224)
at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsForClassWithChangeSet(CommitManager.java:191)
at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:136)
at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:3766)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1404)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:616)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1511)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:264)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1130)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:84)
... 3 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`teste`.`estado_pais`, CONSTRAINT `fk_estado` FOREIGN KEY (`id_estado`) REFERENCES `estado` (`id`))
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:409)
at com.mysql.jdbc.Util.getInstance(Util.java:384)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1041)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3566)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3498)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2113)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2113)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2409)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2327)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2312)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:789)
... 36 more
O erro reclama de eu não ter colocado um ‘id_estado’ que ainda não existe já que estava salvando o estado junto com a List que está dentro dele, tem como o framework de persistencia fazer essa tarefa por mim(alguma configuração ou propriedade)? ou preciso fazer separadamente para salvar a List(que representa a tabela 3)?
Uso o EclipseLink 2.2(também pode ser Hibernate) e gero meus ‘Entitys’ pelo Netbeans e para salvar uso o seguinte método genérico:
public void create(T obj) throws Exception{
EntityManager em = getEMF().createEntityManager();
try {
em.getTransaction().begin();
em.persist(obj);
em.getTransaction().commit();
} catch (Exception e) {
Logger.getLogger(BaseDAO.class.getName()).log(Level.SEVERE, null, e);
try{
em.getTransaction().rollback(); //voltar
}catch(Exception e2){
Logger.getLogger(BaseDAO.class.getName()).log(Level.SEVERE, null, e2);
}
throw new Exception(Mensagens.ERRO_SALVAR);
} finally {
em.close();
emf.close();
}
}