Ejb 3 + jpa

Pessoal,

De acordo com o relacionamento das entidades abaixo, como devo persitir a entidade Carona sem que ocorra o erro em questão?

[code]@Entity
public class Carona implements Serializable {

private static final long serialVersionUID = -8871187256700191219L;

/*
 * (non-javadoc)
 */
private Pessoa oferecedor = null;

/**
 * Getter of the property <tt>oferecedor</tt>
 *
 * @return Returns the oferecedor.
 * 
 */
@ManyToOne(optional=false, cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
@JoinColumn(name="idPessoa", referencedColumnName="idPessoa", nullable=false)
public Pessoa getOferecedor()
{
	return oferecedor;
}

/**
 * Setter of the property <tt>oferecedor</tt>
 *
 * @param oferecedor The oferecedor to set.
 *
 */
public void setOferecedor(Pessoa oferecedor ){
	this.oferecedor = oferecedor;
}

/**
 */
private Set<Pessoa> passageiros = new HashSet<Pessoa>();

/**
 * Getter of the property <tt>pessoa</tt>
 *
 * @return Returns the pessoa.
 *
 */
@ManyToMany(mappedBy="caronas")
public Set<Pessoa> getPassageiros() {
	Hibernate.initialize(passageiros);
	
	return passageiros;
}

/**
 * Setter of the property <tt>pessoa</tt>
 *
 * @param pessoa the pessoa to set.
 *
 */
public void setPassageiros(Set<Pessoa> pessoa){
	this.passageiros = pessoa;
}

}[/code]

[code]@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class Pessoa implements Serializable {

private static final long serialVersionUID = -7200710621590602711L;

private Set<Carona> caronas = new HashSet<Carona>();

private Set<Carona> caronasOferecidas = new HashSet<Carona>();

/**
 * Getter of the property <tt>carona</tt>
 *
 * @return Returns the carona.
 *
 */
@ManyToMany(cascade={CascadeType.ALL})
@JoinTable(name="Pessoa_Carona", joinColumns={@JoinColumn(name="idPessoa")}, inverseJoinColumns={@JoinColumn(name="idCarona")})
public Set<Carona> getCaronas()	{
	Hibernate.initialize(caronas);
		
	return caronas;
}

/**
 * Setter of the property <tt>carona</tt>
 *
 * @param carona the carona to set.
 *
 */
public void setCaronas(Set<Carona> carona){
	this.caronas = carona;
}


/*
 * (non-javadoc)
 */
private Integer idPessoa;

/**
 * Getter of the property <tt>id</tt>
 *
 * @return Returns the id.
 * 
 */
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
public Integer getIdPessoa()
{
	return idPessoa;
}

/**
 * Setter of the property <tt>id</tt>
 *
 * @param id The id to set.
 *
 */
public void setIdPessoa(Integer idPessoa){
	this.idPessoa = idPessoa;
}

/**
 * @return the caronasOferecidas
 */
@OneToMany(mappedBy="oferecedor")
public Set<Carona> getCaronasOferecidas() {
	Hibernate.initialize(caronasOferecidas);
	
	return caronasOferecidas;
}

/**
 * @param caronasOferecidas the caronasOferecidas to set
 */
public void setCaronasOferecidas(Set<Carona> caronasOferecidas) {
	this.caronasOferecidas = caronasOferecidas;
}

}[/code]

Teste para Persistir a carona:

[code]
public static void main(String[] args) {
try {
CadastroUsuarioRemote o = (CadastroUsuarioRemote) doServiceLocator(“CadastroUsuarioBean/remote”);
CadastroCaronaRemote o2 = (CadastroCaronaRemote) doServiceLocator(“CadastroCaronaBean/remote”);
Pessoa p = o.consultarPorId(Usuario.class, 1);

		Carona carona = new Carona();
		
		carona.setHoraPartida(new Date(2007, 06, 01, 9, 00));
		carona.setMaxPassageiro(3);
		carona.setObservacao("Carona 2");
		
		Trajeto trajeto = new Trajeto();
		trajeto.setDescrDestino("Destino 1");
		trajeto.setDescrOrigem("Origem 1");
		
		carona.setTrajeto(trajeto);
		carona.setOferecedor(p);
		
		o2.cadastrar(carona);
}[/code]

Exceção:

javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: br.com.carona.web.model.pessoa.usuario.Pessoa

Caused by: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: br.com.carona.web.model.pessoa.usuario.Pessoa

Um abraço!

tenta setar tb o pai no filho…

Então, além disso, eu fiz o seguinte:

Para o meu ‘CadastroCaronaBean’, eu tenho um metodo merge (é o EntityManager que faz a operação), ou seja, eu instancio uma carona, adiciono o seu ‘criador’, e depois chamo esse método merge, aí funciona numa boa.

Existe outras formas de se fazer isso? Ou com a modelagem que criei não dá?

Abraço

Existe uma dúvida que é peculiar ao meu negócio, no cenário que eu montei, uma pessoa pode oferecer carona e, obviamente, eu não posso permitir que essa pessoa se adicione como passageiro na sua própria carona.

Logo, gostaria de saber qual o jeito mais elegante pra fazer isso.

Eu ainda não descobri, pois as minhas Entidades, devem possuir um construtor sem argumentos default, então, não consigo forçar o programador a setar a entidade Pessoa como ‘owner’ da carona que ela quer criar para em seguida testar se o id dessa pessoa não é igual ao do ‘owner’ da carona…ou consigo?

Existe um Pattern para isso? Se sim, seria uma fábrica remota de Entidades?rs

Abraço

Alguém se habilita?

Obs: Estou estudando mais afundo EJB3 pelo livro ‘Enterprise Java Beans 3.0 - Bill Burke & …’, ele usa uma classe de domínio chamada de ClassDO para trafegar um ou mais objetos para o cliente, só que não sei qual é o padrão mais adequado para o meu caso.

Pessoal, vamos disseminar o conhecimento…na humildade!

Eu queria apenas uns palpites sobre as boas práticas de arquitetura distribuída, só isso!

Valeu