Persistir Utilizando JPA com Many to Many

775 views
Skip to first unread message

alisson queiroga

unread,
May 20, 2013, 8:43:53 PM5/20/13
to pb...@googlegroups.com
Pessoal,

Estou com um problema, tenho duas entidades com relacionamento many to many, conforme exemplo abaixo:

public class A{

  private List<B> Bs;

}

public class B{

  private List<A> As;

}

Não estou conseguindo persistir B com vários A adicionados em sua lista, só estou conseguindo persistir A com vários B em sua lista, como eu faço para persistir Bidirecional, ou só poderei persistir por um lado? 

--
Alisson Diniz
Analista de Sistemas
Phone   +55 83 8707 5783
Skype   alisson.trial
Adress  Campina Grande, Brazil

Isaac Henrique

unread,
May 20, 2013, 9:26:40 PM5/20/13
to pb...@googlegroups.com


--
Você está recebendo esta mensagem porque se inscreveu no grupo "PBJug" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para pbjug+un...@googlegroups.com.
Para postar neste grupo, envie um e-mail para pb...@googlegroups.com.
Visite este grupo em http://groups.google.com/group/pbjug?hl=pt-BR.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.
 
 



--
________________________________
       Isaac Henrique Barbosa Nunes
  Analista e Desenvolvedor de Sistema

Luciano Logrado

unread,
May 20, 2013, 9:46:22 PM5/20/13
to pb...@googlegroups.com
Se não me engano, não se consegue com JPA persistência bidirecional numa relação many-to-many. No caso se precisa criar rotinas que atualizam a classes A quando se faz as atribuição a partir de B, somente desta forma se consegue algo parecido com bidirecional.
Luciano de Lima Logrado
Sun Certified Java Programmer

alisson queiroga

unread,
May 21, 2013, 7:53:48 AM5/21/13
to pb...@googlegroups.com
Isaac, eu fiz da forma que o link que você enviou mostra, eu só fiquei desconfiado que JPA não fazia persistência bidirecional, conforme Luciano falou, vou utilizar a persistência só por um lado mesmo, tenho como trabalhar dessa forma, valeu pessoal.

Matheus de Alencar

unread,
May 21, 2013, 7:58:51 AM5/21/13
to pb...@googlegroups.com
Veja se o cascade = CascadeType.ALL não resolve o seu problema
[]'s

Fred Farias

unread,
May 21, 2013, 7:41:59 AM5/21/13
to pb...@googlegroups.com
public class A{ @ManyToMany
@JoinTable(name="a_b", joinColumns={@JoinColumn(name="id_a")},
inverseJoinColumns = {@JoinColumn(name= "id_b")})
private List<B> Bs;
} public class B{
@ManyToMany(mappedBy="Bs", fetch=FetchType.EAGER)
private List<A> As;
} Dessa forma no banco será criado uma tabela auxiliar de nome "a_b", não é necessário criar essa entidade em seu projeto, a não ser que desejes guardar informações relacionadas ao relacionamento. Atente para a propriedade "mappedBy" o seu valor deve ser o mesmo nome da lista criada na class A.


Em 20 de maio de 2013 22:46, Luciano Logrado <luciano...@gmail.com> escreveu:

alisson queiroga

unread,
May 21, 2013, 1:29:07 PM5/21/13
to pb...@googlegroups.com
Fred,

Coloquei o mapeamento conforme está no seu email e depois executei esse main:

B b1 = new B();
B b2 = new B();

A a = new A();

a.getBs.add(b1);
a.getBs.add(b2);

entityManager.persist(a);


Eu recebo o seguinte erro: 

"org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing:"

Georgenes Lima

unread,
May 21, 2013, 1:45:19 PM5/21/13
to pb...@googlegroups.com
Alisson,

acho que você deve primeiro persistir b1 e b2, para depois persistir o a.
dá uma olhada na apostila k21, página 30, tem um exemplo ManyToMany.
Apostila K19 Treinamentos - Persistência com JPA2 e Hibernate.
boa sorte.

Georgenes

Georgenes Lima

unread,
May 21, 2013, 2:05:06 PM5/21/13
to pb...@googlegroups.com
Olha só Alisson,
Aqui tem um problema semelhante a este seu.
http://javafree.uol.com.br/topic-6592-Probleminha-no-hibernate.html

Diogo Medeiros

unread,
May 21, 2013, 2:01:33 PM5/21/13
to pb...@googlegroups.com
Alisson,
Dá uma sacada nesse link cara... acho que pode te ajudar.

GUJ - org.hibernate.TransientObjectException

Ou com o uso do session.flush();
Dá uma sacada pra ver se serve.

Abs


Em 21 de maio de 2013 14:45, Georgenes Lima <george...@gmail.com> escreveu:



--
Att,

Diogo Medeiros
Java Programmer
Fone (83) 8719-1693
"Não procure ser um homem com êxito, 
e sim um homem com valores." - Albert Einsten
-------------------------------------------------------

alisson queiroga

unread,
May 21, 2013, 9:26:41 PM5/21/13
to pb...@googlegroups.com
Pessoal, consegui resolver meu problema, eu já estava utilizando "cascade = CascadeType.ALL" no meu mapeamento, o problema estava ocorrendo porque quando eu dava merge, criei uma atributo que identifica uma alteração, assim o merge detectava uma alteração.

Fabrício Cabral

unread,
May 21, 2013, 10:56:22 PM5/21/13
to pb...@googlegroups.com
Alisson,

você poderia dar mais detalhes? Como era esse atributo que detectava a alteração?
Como foi configurado isto? Acharia interessante para o histórico da lista...

[]'s


2013/5/21 alisson queiroga <alisso...@gmail.com>



--
--fx

Fabrício Cabral

unread,
May 21, 2013, 11:02:07 PM5/21/13
to pb...@googlegroups.com
Alisson,

em tempo: eu não conheço o seu domínio, mas tem certeza que você precisa
de um relacionamento muitos para muitos? Segundo o que andei apurando
por aí:

1. Um relacionamento muitos para muitos só faz sentido (ou faz mais sentido)
quando os objetos das duas classes precisam existir simultaneamente;

2. Se você mudar a referência de um objeto em de uma classe, tem que
necessariamente, alterar a outra classe também, isto é: se na classe A
você removeu um objeto da classe B, também precisa remover aquela
referência de A na classe B;

3. Sair colocando relacionamento muitos para muitos sem muito critério e
nestes relacionamentos, sair colocando Lazy Loading, a longo prazo, pode
não ser uma boa ideia, devido a problemas de escalabilidade que podem
surgir.

[]'s


2013/5/21 alisson queiroga <alisso...@gmail.com>
Pessoal, consegui resolver meu problema, eu já estava utilizando "cascade = CascadeType.ALL" no meu mapeamento, o problema estava ocorrendo porque quando eu dava merge, criei uma atributo que identifica uma alteração, assim o merge detectava uma alteração.



--
--fx

alisson queiroga

unread,
May 22, 2013, 7:48:11 AM5/22/13
to pb...@googlegroups.com
public class Group implements Serializable {

/*


*/



@JoinTable(name = "group_permission", joinColumns = { @JoinColumn(name = "group_id", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "permission_id", referencedColumnName = "id") })
@ManyToMany
private List<Permission> permissions;

/**
* The dateUpdated.
*/
@Column(name = "date_updated")
@Temporal(TemporalType.TIMESTAMP)
private Date dateUpdated;

}

public class Permission implements Serializable {

/**
* The groups.
*/
@ManyToMany(cascade=CascadeType.ALL, mappedBy = "permissions", fetch = FetchType.LAZY)
private List<Group> groups;
}



alisson queiroga

unread,
May 22, 2013, 7:48:33 AM5/22/13
to pb...@googlegroups.com
Eu chamo esse método:

@Override
public void update(Group groupInstance){
groupInstance.setDateUpdated(new Date());
super.update(groupInstance);
}

alisson queiroga

unread,
May 22, 2013, 7:58:34 AM5/22/13
to pb...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages