Diego Adriano:
Segue os mapeamentos:
TreinoGeral
@OneToMany(mappedBy = "treinogeral")
private List<DadosExercicio> dadostreino;
DadosExercicio
@ManyToOne(cascade =CascadeType.ALL)
@JoinColumn(name="treinogeral")
private TreinoGeral treinogeral;
Eu deveria colocar o Cascade em TreinoGera tb ??
se você quer que a sua variavel tg gere um update, ela deve estar gerenciada pelo seu provedor de jpa, com um id preenchido e existente. Se você quer que com isso os dadosTreino seja atualizados também, então na TreinoGeral você deve colocar o cascade na anotação da sua lista dadosTreino (e se for ALL, quando você excluir o TreinoGeral vai excluir também os DadosExercicio por exemplo), e ai o loop do código que você botou no primeiro post seria desnecessário.
Uma explicação mais detalhada, peço aos mais experientes ou aos certificados que me corrijam caso eu esteja falando alguma besteira ai no meio:
Primeiro vejamos o que o merge faz:
O JPA tem um "cache" dos objetos das entidades, quando você busca alguma entidade(s), seja via alguma ejbql, via get passando o id, quando você pega o objeto dessa forma o objeto passa a ser "gerenciado" pelo cache do JPA (do seu provedor de JPA, da implementação que você ta usando).
Então: se você da um merge em um objeto não gerenciado, o retorno do merge é uma cópia desse seu objeto porém essa cópia é gerenciada (o objeto que você passou não), quando eu quero por exemplo excluir um objeto mas ele não está gerenciado eu costumo dar o merge antes só para ter certeza que irei trabalhar com um objeto gerenciado (e passar para o em.remove o retorno do merge). Que eu me lembre (não tenho certeza), isso é necessário. Caso esse objeto seja gerenciado ja, o entity manager vai dar o update quando você der um commit ou flush na linha da tabela com o mesmo id do seu objeto, passando os dados do objeto. Se você simplesmente obter um objeto gerenciado, mudar alguma coisa dele setando algo e dando o commit, então um update vai ser feito na base mesmo que você não tenha dado o merge.
"SE" algum relacionamento desse objeto tiver cascades preenchidos, então o merge também será replicado para os objetos referenciados nos relacionamentos.
Se o seu objeto não contém um id eu não tinha certeza se o insert era feito. Pelo que você disse eu deduzo que faça o insert sim (se o id tivesse preenchido com um objeto ja existente ele daria update e se você tentar inserir um objeto com um id que ja existe daria uma exceção acho que NonUniqueObjectException é o nome... se deu o insert eu imagino que OU seu id não esteja preenchido e você tenha um gerador automatico pra isso, ou o id seja preenchido na mão e esteja com um valor que não existe na base).
Eu te diria para evitar ficar dando flush assim a torto e a direito, você não precisa disso, quando você der o commit tudo será inserido/atualizado/etc... eu teria que confirmar se um rollback funcionaria para desfazer o que ja tivesse sido feito quando você tiver dado o flush...tenho duvidas quanto a isso.
Esse é um exemplo clássico de como JPA facilita nosso trabalho, escrevemos menos código e código mais simples, mas se você não conhecer a especificação você pode ter uns erros "estranhos", que você não vai saber por quê está acontecendo...