Como salvar objeto de um campo digitado em um relacionamento m2m?

Obs: utilizo JSF + Hibernate (Jboss Seam).

Pessoal, na minha aplicação tenho a classe Operador que pode receber um ou muitos telefones, e esses telefones são digitados na hora de cadastrar um operador.

Qual a maneira mais correta de fazer isso?

Eu já utilizei m2m em outras áreas, mas eu não digitava nenhum valor e sim escolhia através de checkboxes, e isso é tranquilo.

Alguém com paciencia veja como estou tentando fazer:

Na classe de entidade Operador tenho um atributo que é uma lista de telefones e mapeei m2m operador-telefone:

[code]public class Operator {
private Integer operatorId;
private String name;
private List telephones;
}

@ManyToMany
@JoinTable(name = “operator_telephone”, joinColumns = @JoinColumn(name = “operator_id”), inverseJoinColumns = @JoinColumn(name = “telephone_id”))
public List getTelephones() {
return telephones;
}[/code]

Modelei uma classe OperadorTelefone (mapeando m2O telefone e m2O operador) da seguinte maneira:

[code]@Table(name = “operator_telephone”)
public class OperatorTelephone implements Serializable {

private Integer operatorTelephoneId;
private Operator operator;
private Telephone telephone;	

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "operator_telephone_id", unique = true, nullable = false)
public Integer getOperatorTelephoneId() {
	return this.operatorTelephoneId;
}	

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "operator_id", nullable = false)
@NotNull
public Operator getOperator() {
	return operator;
}	

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "telephone_id", nullable = false)
@NotNull
public Telephone getTelephone() {
	return this.telephone;
}

//setters	

}
[/code]

Na minha OperadorAction, tenho os seguintes métodos:
1 - getListTelephone(): cria uma lista do tipo Telefone, para que eu possa utilizar na view do JSF;
2 - saveOperator(): no método para salvar Operador, depois de persistir o mesmo eu crio um laço que, a cada iteração da listaTelefones, instancia um objeto OperadorTelefone e o persiste (ou deveria persistir, já que não funcionou). Segue o código:

[code]public String saveOperator() {
if (operator.getOperatorId() == null) {
entityManager.persist(operator);

	getListTelephone();
	for (int i = 0; i < listTelephone.size(); i++) {
		telephoneOperator = new OperatorTelephone();
		
		entityManager.persist(telephone);			
		telephoneOperator.setTelephone(listTelephone.get(i));
		telephoneOperator.setOperator(operator);
		entityManager.persist(telephoneOperator);				
	}		
} 
return "saveOperator";

}

@Factory(“listTelephone”)
public void getListTelephone() {
listTelephone = new ArrayList();
for (int i = 0; i < 2; i++) {
telephone = new Telephone();
listTelephone.add(i, telephone);
}
}

[/code]

View operador_edit:

<a:repeat value="#{listTelephone}" var="_lt" id="listTelephone"> <ui:define name="label">Telefone</ui:define> <h:inputText id="telephone" size="20" maxlength="10" value="#{telephone.number}" label="Telefone"> <a:support event="onblur" reRender="telephoneDecoration" bypassUpdates="true" ajaxSingle="true" /> </h:inputText> </a:repeat>

Tenho quase certeza que deve existir uma maneira melhor de se fazer isso, algo “mágico” que o Hibernate faça, mas não consegui achar nada, se alguém puder dar umas dicas agradeço.

Quando você diz que “não funcionou”, o que exatamente não funcionou? Ele simplesmente não persistiu nenhuma das entidades que você criou ? Nem o operator, nem o telephone, nem as telephoneOperator ?

E essa linha aqui, não faz muito sentido estar presente aqui:

Voce está tentando persistir várias vezes a mesma entidade…

Está dando flush() em algum lugar? Se não estiver, pode ser esse o problema… se estiver e mesmo assim não estiver funcionando, então seja bem-vindo ao maravilhoso mundo do Seam, onde a persistência é realizada através de métodos obscuros, e nada é o que parece ser (sim, eu odeio Seam pela sua falta de transparência…) :roll:

[quote=marcelo.bellissimo]Quando você diz que “não funcionou”, o que exatamente não funcionou? Ele simplesmente não persistiu nenhuma das entidades que você criou ? Nem o operator, nem o telephone, nem as telephoneOperator ?

E essa linha aqui, não faz muito sentido estar presente aqui:

Voce está tentando persistir várias vezes a mesma entidade…

Está dando flush() em algum lugar? Se não estiver, pode ser esse o problema… se estiver e mesmo assim não estiver funcionando, então seja bem-vindo ao maravilhoso mundo do Seam, onde a persistência é realizada através de métodos obscuros, e nada é o que parece ser (sim, eu odeio Seam pela sua falta de transparência…) :roll: [/quote]

E aí Marcelo, blz?

Então cara, agora está funcionando, refiz alguns métodos, criei uma lista de operadorTelefone ao invés de telefone (muita burrice não ter pensado nisso desde o início) e no método save() estou salvando de maneira correta também, de acordo com o indice da iteração, segue o que modifiquei:

[code]@Factory(“listOperatorTelephone”)
public void getListOperatorTelephone() {
listOperatorTelephone = new ArrayList<OperatorTelephone>();
for (int i = 0; i < 2; i++) {
OperatorTelephone operatorTelephone = new OperatorTelephone();
operatorTelephone.setTelephone(new Telephone());
listOperatorTelephone.add(i, operatorTelephone);
}
}

public String saveOperator() {
if (operator.getOperatorId() == null) {

	entityManager.persist(email);
	entityManager.find(Email.class, email.getEmailId());
	operator.setEmail(email);			
	entityManager.persist(operator);
	
	for (int i = 0; i &lt; listOperatorTelephone.size(); i++) {
		// salva o número de telefone em telefone
		listOperatorTelephone.get(i).getTelephone().setNumber(listOperatorTelephone.get(i).getTelephone().getNumber());
		entityManager.persist(listOperatorTelephone.get(i).getTelephone());
		
		// salva os telefones e o operador em operador-telefone
		listOperatorTelephone.get(i).setTelephone(listOperatorTelephone.get(i).getTelephone());
		listOperatorTelephone.get(i).setOperator(operator);
		entityManager.persist(listOperatorTelephone.get(i));				
	}			
} 
return &quot;saveOperator&quot;;

}

view JSF

<a:repeat value="#{listOperatorTelephone}" var="_telephone" id=“listTelephone”>
<s:decorate id=“telephoneDecoration” template="…/layout/edit.xhtml">
<ui:define name=“label”>Telefone</ui:define>
<h:inputText id=“telephone” size=“20” maxlength=“10"
value=”#{_telephone.telephone.number}" label=“Telefone”>
<a:support event=“onblur” reRender=“telephoneDecoration"
bypassUpdates=“true” ajaxSingle=“true” />
<rich:jQuery selector=”#telephone" query="mask(’(99) 9999-9999’)"
timing=“onload” />
</h:inputText>
</s:decorate>
</a:repeat>
[/code]

Mas mesmo assim imagino que deva ter uma maneira mais “correta” de fazer isso, de um jeito mais fácil.

Abraços