Object references an unsaved transient instance

Prezados,
estou tentando salvar os dados de um formulário no banco, só que ele me retorna essa mensagem “object references an unsaved transient instance - save the transient instance before flushing: … entity.CursoEspecializacao”

Dei umas olhadas nos post ai e diziam que tinha que colocar cascade = CascadeType.ALL, só que não adiantou.

Segue as entity e o save

Entity Pessoa

. . .
@OneToMany(mappedBy ="pessoa", fetch = FetchType.LAZY)
	private List<CursoEspecializacao> cursoEspecializacao;
. . . 

Entity CursoEspecializacao

. . .
	@ManyToOne
	@JoinColumn(name="Pessoa_idPessoa")
	private Pessoa pessoa = new Pessoa();
. . .

save

public void salvarPessoa(Pessoa pessoa) {
		try {
			entityManager.merge(pessoa);
			entityManager.flush();
		} catch (Exception e) {
		//TODO ...
		}
	}

Se alguem puder ajudar eu agradeço.

Como está a classe CursoEspecializacao? Pode posta-la por completo?

Segue a entity cursoEspecializacao

@Table(name = "CursoEspecializacao", schema = "SPL")
public class CursoEspecializacao implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "idCursoEspecializacao", unique = true, nullable = false)
	private Integer idCursoEspecializacao;
	
	@Column(name = "especializacao")
	private String especializacao;
	
	@Column(name = "nomeInstituicao")
	private String nomeInstituicao;
	
	@ManyToOne
	@JoinColumn(name="Pessoa_idPessoa")
	private Pessoa pessoa = new Pessoa();
//GETTERES AND SETTERES 
. . .

Segue a entity cursoEspecialização. Só não consta os getteres e setteres

@Table(name = "CursoEspecializacao", schema = "SPL")
public class CursoEspecializacao implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "idCursoEspecializacao", unique = true, nullable = false)
	private Integer idCursoEspecializacao;
	
	@Column(name = "especializacao")
	private String especializacao;
	
	
	@Column(name = "nomeInstituicao")
	private String nomeInstituicao;
	
	@ManyToOne
	@JoinColumn(name="Pessoa_idPessoa")
	private Pessoa pessoa = new Pessoa();

Cara, é EJB ou “na mão” mesmo ?
Tu não está presente em nenhum transação, por isso ele não consegue persistir, como se não houvesse um contexto.

eu acho que sua entidade CursoEspecializacao está detached na hora de persistir, portanto pode ser necessário buscar a referência dela novamente.
algo assim:public void salvarPessoa(Pessoa pessoa) { try { pessoa.setCursoEspecializacao(entityManager.getReference( CursoEspecializacao.class, pessoa.getCursoEspecializacao().getIdCursoEspecializacao())); entityManager.merge(pessoa); entityManager.flush(); } catch (Exception e) { //TODO ... } }

digaoneves, não entendi muito bem o que você, mas o meu método de salvar está assim:

action

public void salvarPessoa(){
this.pessoa.setCursoEspecializacao(listaCursoEspecializacao);
this.cadastroManager.salvarPessoa(pessoa)
}

save

    public void salvarPessoa(Pessoa pessoa) {  
            try {  
                entityManager.merge(pessoa);  
                entityManager.flush();  
            } catch (Exception e) {  
            //TODO ...  
            }  
        }  

[quote=nel]Cara, é EJB ou “na mão” mesmo ?
Tu não está presente em nenhum transação, por isso ele não consegue persistir, como se não houvesse um contexto.[/quote]
EJB mesmo

Adapte o código que eu passei de modo que possa tratar uma lista.

EDIT: Aliás, você tentou usar o persist ao invés do merge ?

[quote=david.jv][quote=nel]Cara, é EJB ou “na mão” mesmo ?
Tu não está presente em nenhum transação, por isso ele não consegue persistir, como se não houvesse um contexto.[/quote]
EJB mesmo[/quote]

[quote=digaoneves]Adapte o código que eu passei de modo que possa tratar uma lista.

EDIT: Aliás, você tentou usar o persist ao invés do merge ?[/quote]

Merge também funciona. Ele vai identificar que não tem uma chave primária e persiste.
Estou achando que ele está usando uma classe comum e tentando injetar um EntityManager nela…posta a classe por completo colega, a que executa a persistência.

[quote=digaoneves]Adapte o código que eu passei de modo que possa tratar uma lista.

EDIT: Aliás, você tentou usar o persist ao invés do merge ?[/quote]

Tentei, só que ele me retorna o erro dizendo que o idPessoa não pode ser null.

Segue a class

@Name("cadastroManager")
@SuppressWarnings("unchecked")
public class CadastroManager extends AbstractManager {

	//. . . outros métodos


	public void salvarPessoa(Pessoa pessoa) {
		try {
			entityManager.merge(pessoa);
			entityManager.flush();
		} catch (Exception e) {
			//TODO ...
		}
	}
}

[quote=david.jv]Segue a class

[code]
@Name(“cadastroManager”)
@SuppressWarnings(“unchecked”)
public class CadastroManager extends AbstractManager {

//. . . outros métodos


public void salvarPessoa(Pessoa pessoa) {
	try {
		entityManager.merge(pessoa);
		entityManager.flush();
	} catch (Exception e) {
		//TODO ...
	}
}

}
[/code][/quote]

O que eu disse né…onde isso é um EJB ? Cadê as anotações ? Stateless? Statefull ? Singleton? Estou vendo nenhuma anotação EJB.
Isso dai nada mais é que um classe qualquer aos olhos de um servidor de aplicação colega…

ah sim, como está configurada a PK da sua Pessoa ? e qual banco você usa ?

Na verdade isto vai ser adaptado para um EJB, esse teste está sendo feito na pq não consegui fazer essa ‘jossa’ funcionar.

A PK dele é essa:

@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "idCursoEspecializacao", unique = true, nullable = false) private Integer idCursoEspecializacao;

Eu faria duas mudanças ai:

1 - Tirar esse unique. Já tem o @Id, é óbvio que será unique.

2 - Trocaria o GenerationType.IDENTITY por GenerationType.AUTO. Já tive problemas com o modo IDENTITY, não é 100% confiável. E já testei com MySQL, Oracle, SQL Server…

Essa PK é de CursoEspecializacao

Mas faça o teste de forma coerente colega, senão isso não lhe trará os resultados esperados, e caso traga, pode ser apenas uma “enganação”. Se ele será um EJB, faça-o desde agora, é o correto.

Perfeito. É a entidade Pessoa, desculpe. De qualquer forma, a minha observação sobre usar GenerationType.AUTO continua.
Grato pela observação.

Mas faça o teste de forma coerente colega, senão isso não lhe trará os resultados esperados, e caso traga, pode ser apenas uma “enganação”. Se ele será um EJB, faça-o desde agora, é o correto.[/quote]
++
Concordo plenamente. Na sua situação esse teste sem utilizar o EJB pode mais atrapalhar do que ajudar.