Pessoal,
estou tentando atualizar um objeto no banco, mas dá o seguinte erro:
org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1
Esse objeto tem alguns atributos primitivos e um arraylist, mapeado assim:
<list name="umArrayList" table="tabela" inverse="false" cascade="all">
<key column="sala" />
<list-index column="indice" />
<one-to-many class="a classe dos objetos do array list" />
</list>
A mudança no objeto que estou querendo persistir foi a adição de mais um elemento no arraylist.
Alguém com mais experiência com o hiber pode me dar uma dica do que pode ser esse erro, ou um link onde eu possa pesquisar erros comuns do hibernate. (ahhh, eu já tentei o google
)
Valeu.
Coloca o código entre a abertura da session ou transaction e o fim dela.
[quote=LIPE]
Coloca o código entre a abertura da session ou transaction e o fim dela.[/quote]
Taí ele:
public boolean atualiza(SalaDeReunioes sala)
{
Session sessao = HibernateUtil.getSessao();
Transaction t = sessao.beginTransaction();
System.out.println("GRAVAR: "+sala);
sessao.update(sala);
t.commit();
HibernateUtil.fechaSessao();
return true;
}
O System.out.println imprime o conteúdo esperado do objeto.
O HibernateUtil é igual ao do manual do hibernate, faz um tratamento das sessoes com ThreadLocal.
Quanto a isso:
Eu preciso recuperar o objeto de novo para mandar fazer o update? Como?
No teste que está dando o erro, esse objeto acabou de ser carregado do banco, logo ele existe e está “fresquinho”. Ou não?
Valeu.
Pera, você tem um objeto persistente e mesmo assim faz session.update() nele?
Posta o código que chama o método atualiza(), principalmente a parte em que você pega o objeto SalaDeReuniao do banco.
[quote=LIPE]Pera, você tem um objeto persistente e mesmo assim faz session.update() nele?
Posta o código que chama o método atualiza(), principalmente a parte em que você pega o objeto SalaDeReuniao do banco.[/quote]
Não, estou fechando a sessão assim que eu pego o objeto:
[code]public List getSalas()
{
String consulta = “select s from SalaDeReunioes as s”;
Session sess = HibernateUtil.getSessao();
//busca das salas no bd
Transaction t = sess.beginTransaction();
Query q = sess.createQuery(consulta);
List salas = q.list();
t.commit();
sess.flush();
HibernateUtil.fechaSessao();
return salas;
}[/code]
Mas não funciona… estou há horas buscando alternativas, mas não consigo fazer nenhuma funcionar…
Estou quase apelando para o velho e bom jdbc… 
Agora me veio uma idéia, será que eu tenho que atualizar toda a lista? Na realidade, ela está dentro de um objeto PoolDeSalas, eu preciso atualizar todo o Pool? Esse pool é simplesmente o conjunto de todas as salas manipuladas pela app.
Valeu.
Estou mais perto do erro, mas não consigo descobrir o que é…
Dentro da sala, existe um array de objetos LinhaDeDiscussao. Fazendo um teste a parte para gravação só de uma linha de discussão, verifiquei que o erro aparece nela. Quando crio uma LinhaDeDiscussao e seus objetos manualmente, o tabela das linhas de discussão é atualizada, mas os relacionamentos não. O mapeamento está assim:
Em LinhaDeDiscussao.hbm
<list name="mensagens" table="mensagens" inverse="true" cascade="all" lazy="false" >
<key column="linha" />
<list-index column="indice" />
<one-to-many class="opacote.Mensagem" />
</list>
e em Mensagem.hbm está assim:
<many-to-one name="linha"
class="opacote.LinhaDeDiscussao"
column="linha" />
Alguém consegue ver algo errado com esses mapeamentos?
Valeu…
Opa, não foi esse método que eu pedi para você postar.
Preciso que você mostre o método que chama
atualiza(SalaDeReunioes sala)
para entender o estado do objeto SalaDeReunioes passado.
e dica: ao invés de usar query no caso do método getSalas(), basta fazer assim:
Session sess = HibernateUtil.getSessao();
List l = sess.createCriteria( SalaDeReunioes.class ).list();
HibernateUtil.fechaSessao();
Mais simples e, por não envolver Strings, ajuda bastante caso precise mudar o nome.
Lipe,
dei uma refatorada no código, e consegui fazer a gravação, mas forçando uma barrinha… :oops:
O problema agora é esse… http://www.guj.com.br/posts/list/23870.java
[quote=LIPE]e dica: ao invés de usar query no caso do método getSalas(), basta fazer assim:
Session sess = HibernateUtil.getSessao();
List l = sess.createCriteria( SalaDeReunioes.class ).list();
HibernateUtil.fechaSessao();
Mais simples e, por não envolver Strings, ajuda bastante caso precise mudar o nome.[/quote]
Valeu a dica! Está incorporado!
quer dizer, quase tudo… onde é que eu fecho a session? a app só funciona se eu não fechar essa sessao…
Como e que eu forço o hiber a recuperar todos os objetos da lista por inteiro para poder fechar a sessao? já tentei sessao.flush, transacao.commit, separados e juntos, mas não colou…
Valeu mesmo!
Procure por FETCH_MODE na documentação.
Lipe,
fui lá, pesquisei e tentei o seguinte:
session.createCriteria(SalaDeReunioes.class).setFetchMode("aLista", FetchMode.JOIN).list();
Não vai… Acho que é porque as salas tem outra lista (aLista) de objetos dentro…
Para ver o meu programa rodar e o meu trabalho ir para frente, tive que fazer uma gracinha: mandar imprimir todas as salas da lista… :oops:
Enquanto isso, vou lendo o manual do hibernate desde o início, para ver se entendendo melhor o funcionamento dele eu consigo tirar essa gambiarra do meu código…
Valeu a ajuda (se vc ainda tiver alguma idéia, pode mandar que eu continuo na esperança…)

Nunca tentei com listas, mas:
session.createCriteria( SalaDeReunioes.class )
.setFetchMode( "pessoas", FetchMode.JOIN )
.createAlias( "pessoas", "pessoa" ).setFetchMode( "cargos", FetchMode.JOIN).list();