Erro estranho ao excluir item de uma tabela com Hibernate

Tenho uma tabela principal (Cliente) com uma tabela de itens relacionada (ClienteParticao). Quando incluo ou altero registros em Particoes e dou um merge no Cliente, funciona normalmente, porém, quando excluo um item em Particoes e tento dar um merge no Cliente, ocorre um erro. Alguém sabe o que pode ser?
Os detalhes estão abaixo:

@Entity
@Table(name=“Clientes”)
public class Cliente implements Serializable
{
private int codigo = 0;
private List particoes = null;

@Id
public int getCodigo() 
{
	return codigo;
}

public void setCodigo(int valor) 
{
	codigo = valor;
}

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@JoinColumn(name="cliente", referencedColumnName="codigo")
public List<ClienteParticao> getParticoes()
{
	if (particoes == null)
		return new ArrayList<ClienteParticao>();
	else
		return particoes;
}

public void setParticoes(List<ClienteParticao> valor)
{
	particoes = valor;
}

}

@Entity
@Table(name=“ClientesParticoes”)
@IdClass(ClienteItemChave.class)
public class ClienteParticao implements Serializable
{
private int cliente = 0;
private short codigo = 0;

@Id
public int getCliente() 
{
	return cliente;
}

public void setCliente(int valor) 
{
	cliente = valor;
}

@Id
public short getCodigo() 
{
	return codigo;
}

public void setCodigo(short valor) 
{
	codigo = valor;
}

}

Erro:

org.hibernate.exception.GenericJDBCException: could not delete collection rows: [monienterprise.dados.cliente.Cliente.particoes#1]
at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:126)
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:114)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.persister.collection.AbstractCollectionPersister.deleteRows(AbstractCollectionPersister.java:1314)
at org.hibernate.action.CollectionUpdateAction.execute(CollectionUpdateAction.java:84)
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:170)
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 org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54)
at moni.cadastro.PadraoDao.alterar(PadraoDao.java:152)
at moni.cadastro.ControleCadastro.alterar(ControleCadastro.java:176)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at moni.cadastro.ControleCadastro.executar(ControleCadastro.java:149)
at monienterprise.ejb.CadastroBean.executar(CadastroBean.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.enterprise.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1011)
at com.sun.enterprise.security.SecurityUtil.invoke(SecurityUtil.java:175)
at com.sun.ejb.containers.BaseContainer.invokeTargetBeanMethod(BaseContainer.java:2920)
at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4011)
at com.sun.ejb.containers.EJBObjectInvocationHandler.invoke(EJBObjectInvocationHandler.java:203)
at com.sun.ejb.containers.EJBObjectInvocationHandlerDelegate.invoke(EJBObjectInvocationHandlerDelegate.java:117)
at $Proxy94.executar(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:233)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:152)
at com.sun.corba.ee.impl.presentation.rmi.bcel.BCELStubBase.invoke(BCELStubBase.java:225)
at monienterprise.ejb.__Cadastro_Remote_DynamicStub.executar(monienterprise/ejb/__Cadastro_Remote_DynamicStub.java)
at monienterprise.ejb._Cadastro_Wrapper.executar(monienterprise/ejb/_Cadastro_Wrapper.java)
at monienterprise.ComunicacaoFrontend.executarCadastro(ComunicacaoFrontend.java:106)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at flex.messaging.services.remoting.adapters.JavaAdapter.invoke(JavaAdapter.java:406)
at flex.messaging.services.RemotingService.serviceMessage(RemotingService.java:183)
at flex.messaging.MessageBroker.routeMessageToService(MessageBroker.java:1417)
at flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:878)
at flex.messaging.endpoints.amf.MessageBrokerFilter.invoke(MessageBrokerFilter.java:121)
at flex.messaging.endpoints.amf.LegacyFilter.invoke(LegacyFilter.java:158)
at flex.messaging.endpoints.amf.SessionFilter.invoke(SessionFilter.java:49)
at flex.messaging.endpoints.amf.BatchProcessFilter.invoke(BatchProcessFilter.java:67)
at flex.messaging.endpoints.amf.SerializationFilter.invoke(SerializationFilter.java:146)
at flex.messaging.endpoints.BaseHTTPEndpoint.service(BaseHTTPEndpoint.java:274)
at flex.messaging.MessageBrokerServlet.service(MessageBrokerServlet.java:377)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:427)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:315)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:287)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:218)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:98)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:222)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1096)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:166)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1096)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:288)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:647)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:579)
at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:831)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
Caused by: org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544347. validation error for column CLIENTE, value "*** null ***"
at org.firebirdsql.jdbc.AbstractPreparedStatement.internalExecute(AbstractPreparedStatement.java:730)
at org.firebirdsql.jdbc.AbstractPreparedStatement.executeUpdate(AbstractPreparedStatement.java:190)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.firebirdsql.pool.PooledPreparedStatementHandler.invoke(PooledPreparedStatementHandler.java:166)
at org.firebirdsql.pool.$Proxy99.executeUpdate(Unknown Source)
at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:46)
at org.hibernate.persister.collection.AbstractCollectionPersister.deleteRows(AbstractCollectionPersister.java:1283)
… 82 more
|#]

Como está o seu fluxo de exclusão ? Posta aí o código de onde você está chamando a excluão do registro… pois dependendo da ordem, pode dar esse erro…

É que estou usando o Flex no Frontend e é nele que o registro é excluído e enviado ao Java. Mas a princípio estou apenas dando um remove no item do List e logo em seguida tendando dar um merge. Mas o que vocês quis dizer com “dependendo da ordem, pode dar esse erro”?

Fiz um teste simples e deu o mesmo erro, olha aí o código fonte:

GrupoUsuarios grupo = entityManager.find(GrupoUsuarios.class, (short) 2);
grupo.getPermissoes().remove(0);
entityManager.getTransaction().begin();
entityManager.merge(grupo);
entityManager.getTransaction().commit();

Não trabalho muito com annotations mas tipo…

nao devia ser assim?

@Entity
@Table(name="Clientes")
public class Cliente implements Serializable
{
private int codigo = 0;
private List<ClienteParticao> particoes = null;

@Id
public int getCodigo()
{
return codigo;
}

public void setCodigo(int valor)
{
codigo = valor;
}

@OneToMany(mappedBy="cliente")
public List<ClienteParticao> getParticoes()
{
if (particoes == null)
return new ArrayList<ClienteParticao>();
else
return particoes;
}

public void setParticoes(List<ClienteParticao> valor)
{
particoes = valor;
}
}

@Entity
@Table(name="ClientesParticoes")
@IdClass(ClienteItemChave.class)
public class ClienteParticao implements Serializable
{
private Cliente cliente;
private short codigo = 0;

@Id
@ManyToOne
public Cliente getCliente()
{
return cliente;
}

public void setCliente(Cliente valor)
{
cliente = valor;
}

@Id
public short getCodigo()
{
return codigo;
}

public void setCodigo(short valor)
{
codigo = valor;
}
}

[quote=Requena]Não trabalho muito com annotations mas tipo…

nao devia ser assim?

[code]
@Entity
@Table(name=“Clientes”)
public class Cliente implements Serializable
{
private int codigo = 0;
private List particoes = null;

@Id
public int getCodigo()
{
return codigo;
}

public void setCodigo(int valor)
{
codigo = valor;
}

@OneToMany(mappedBy=“cliente”)
public List getParticoes()
{
if (particoes == null)
return new ArrayList();
else
return particoes;
}

public void setParticoes(List valor)
{
particoes = valor;
}
}

@Entity
@Table(name=“ClientesParticoes”)
@IdClass(ClienteItemChave.class)
public class ClienteParticao implements Serializable
{
private Cliente cliente;
private short codigo = 0;

@Id
@ManyToOne
public Cliente getCliente()
{
return cliente;
}

public void setCliente(Cliente valor)
{
cliente = valor;
}

@Id
public short getCodigo()
{
return codigo;
}

public void setCodigo(short valor)
{
codigo = valor;
}
}
[/code][/quote]

Do meu jeito o relacionamento é unidirecional e da sua forma é bidirecional, fiz um teste aqui e deu o mesmo erro.

Descobri a causa do problema. O Hibernate não apaga o registro, ele apenas seta null no campo do relacionamento, como este campo estava Not Null, estava dando erro, eu tirei o Not Null e não deu mais erro, mas o registro também não foi excluído.
Porque o Hibernate não exclui o registro?

Tipow… eu acho que como o relacionamento é unidirecional ao remover da lista do cliente a partição o hibernate apenas tenta remover o relacionamento, logo a chave estrangeira, então ele da um update na tabela da partição e da um set=null no cliente.

É exatamente isto que ocorre. No bidirecional ocorre o mesmo, como eu faço pro Hibernate excluir o item ao invés de simplesmente setar null no campo do relacionamento?

entao… é que no caso de um bidirecional N x N tem de ter uma tabela de relacionamento entre os dois objetos entao tipo

tabela A
tabela B

tabelaRelacionamentoAB

nesse caso quando vc der o remove da lista ele vai apagar o registro de dentro da tabelaRelacionamentoAB porém nao vai apagar o dado da tabela A nem da B só o relacionamento N x N…

fazendo da forma que vc esta fazendo mesmo colocando um bidirecional o relacionamento real continua sendo 1xN onde um cliente tem N partiçoes e 1 partição tem 1 cliente…
nesse caso ele nunca vai escluir a partição ele vai sempre dar update para null no id do cliente dentro da partição…
saco?

no caso de 1xN para excluir os dados da lista nao se da .remove no item da lista… a gente pega e colocar o cara em uma lista nova e depois remove a lista toda…
tipo…

List listaRemovidos = new ArrayList();
listaRemovidos.add(itemA.getLista.get(3));
listaRemovidos.add(itemA.getLista.get(5));

entityManager.removerLista(listaRemovidos);