Erro ao gravar relacionamento @OneToMany /@ManyToOne

8 respostas
G

Boa noite a todos, tenho o seguinte cenário: uma cotação possui 1 ou vários pedidos. Para representar este relacionamento fiz o seguinte mapeamento nos beans:

Classe Cotacao.java:
@OneToMany(mappedBy="cotacao", targetEntity=PedidoCotacao.class, fetch=FetchType.LAZY, cascade=CascadeType.ALL)
	public List<PedidoCotacao> getPedidosCotacao() {
		return pedidosCotacao;
	}
	
	public void setPedidosCotacao(List<PedidoCotacao> pedidosCotacao) {
		this.pedidosCotacao = pedidosCotacao;
	}
Classe PedidoCotacao.java
@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="idCotacao", referencedColumnName="idCotacao")
	public Cotacao getCotacao() {
		return cotacao;
	}

	public void setCotacao(Cotacao cotacao) {
		this.cotacao = cotacao;
	}

E para salvar o mesmo, o seguinte bloco de comando:

Classe HibernateDAO.java
/**
	 * método para salvar a entidade;
	 */
	@Override
	public void salvar(T bean) {		
		session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();
		try{
			session.save(bean);
			tx.commit();
		} catch (RuntimeException e) {
			if (tx != null)
				tx.rollback();
			throw e;
		} finally {
			session.close();
		}
	}

O meu problema é o seguinte, em alguns casos eu consegui salvar normalmente, porém na maioria das vezes tive o erro logo a baixo. Eu não consegui detectar qual o cenário eu consegui gravar e o porquê de estar ocorrendo o erro na maioria das vezes que estou tentando salvar. Gostaria de manter essa implementação, que acho mais elegante do que salvar primeiramente a cotação e depois salvar a lista dos pedidos e por isto conto com a ajuda de vocês para compreender e contornar este erro. Desde já agradeço pela ajuda de todos.

Erro:

org.hibernate.exception.ConstraintViolationException: could not insert: [br.com.gpa.model.bean.Cotacao]
	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
	at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:64)
	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2186)
	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2666)
	at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
	at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)
	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
	at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
	at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
	at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:562)
	at org.hibernate.impl.SessionImpl.save(SessionImpl.java:550)
	at org.hibernate.impl.SessionImpl.save(SessionImpl.java:546)
	at br.com.gpa.persistence.HibernateDAO.salvar(HibernateDAO.java:42)
	at br.com.gpa.business.CotacaoBO.gravar(CotacaoBO.java:17)
	at br.com.gpa.controller.CotacaoMB.gravar(CotacaoMB.java:87)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
	at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
	at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
	at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
	at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
	at javax.faces.component.UICommand.broadcast(UICommand.java:315)
	at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:787)
	at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1252)
	at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:541)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:383)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:288)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
	at java.lang.Thread.run(Thread.java:722)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`gpa`.`cotacao`, CONSTRAINT `FK_COTACAO_CLIENTE` FOREIGN KEY (`idCliente`) REFERENCES `cliente` (`idCliente`))
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
	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:3562)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3494)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1960)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2114)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2696)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2105)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2398)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2316)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2301)
	at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:94)
	at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:57)
	... 49 more

8 Respostas

G

Alguém?

A

Bom dia, você está tentando salvar um pedido e a lista de cotações em cascata, correto ?

Se sim, verifique seu import do cascade. Se seu import for:

javax.persistence.CascadeType

altera o métdo de savar para session.persist

se o import for do hibernate, deveria funcionar. rs.

testa ai.

[]'s

G

Vlw pela dica, vou testar hoje a noite quando chegar em casa ehehe. Porém não tenho certeza que o problema seja este porquê em alguns casos ele salva corretamente!

A

Realmente, olhando mais atentamente (rs) o problema está na FK para o cliente (idCliente) não no idCotação como eu pensei.

Depois verifique o mapeamento para esse idCliente dentro do objeto cotação.

[]'s

G

Alguém mais?

G

Eu estava analisando e percebi que está gravando apenas quando o cliente é o Cliente 1 e o Fornecedor é o fornecedor 1 também! Na minha base tenho (dados relevantes):

Tabela cliente:
idCliente(PK)

Tabela Fornecedor:
idFornecedor(PK)

Tabela cotacao:
idCotacao(PK)
idCliente(FK)

Tabela pedido_cotacao:
idPedidoCotacao(PK)
idCotacao(FK)
idFornecedor(FK)

Os relacionamentos são:

  • Uma cotação possui 1 … N pedidos de cotação;
  • Uma cotação possui 1 cliente;
  • Um pedido de cotação possui 1 fornecedor;

Alguém consegui ver o porquê do erro Cannot add or update a child row: a foreign key constraint fails (gpa.cotacao, CONSTRAINT FK_COTACAO_CLIENTE FOREIGN KEY (idCliente) REFERENCES cliente (idCliente)) e também do erro Cannot add or update a child row: a foreign key constraint fails (gpa.pedido_cotacao, CONSTRAINT FK_PEDIDO_COTACAO_FORNECEDOR FOREIGN KEY (idFornecedor) REFERENCES fornecedor (idFornecedor)) ???

G

Alguém por favor!

G

Alguém por favor?

Criado 6 de março de 2012
Ultima resposta 12 de mar. de 2012
Respostas 8
Participantes 2