Resolvido Many To Many com atributo

8 respostas
D

Boa tarde galera,
estou precisando de uma ajuda na seguinte situação.
Criei uma associação Many to Many com atributo usando e Embedded e tudo mais dessa maneira:

@Entity
@Table(name = "A")
public class A implements Serializable {
         @Id
         @Column(name = "aID", nullable = false, length = 10)
         private String aID;

         @OneToMany(fetch = FetchType.LAZY)
         @JoinColumn(name="aID")  
         private List<C> c;
}

@Entity
@Table(name = "B")
public class B implements Serializable {
           @Id
           @Column(name = "bID", nullable = false, length = 10)
           private String bID;

           @OneToMany(fetch = FetchType.LAZY)
           @JoinColumn(name="bID")  
           private List<C> c;
}

@Embeddable
public class CPK implements Serializable{

	@ManyToOne
        @JoinColumn(name = "aID")
	private A a;

	@ManyToOne
        @JoinColumn(name = "bID")
	private B b;

}

@Entity
public class C implements Serializable {

         @EmbeddedId
         private CPK chaveComposta;

            @Column(name = "periodos", nullable = false, length = 10)
            private String periodos;

}

O problema é que eu preciso inserir varios períodos para a mesma associação.
Ex:

classe A            classe C              Classe B
         1                [telefone removido]              1
                          [telefone removido]
                          [telefone removido]
         
         2                [telefone removido]              1
                          [telefone removido]              
         
         1                [telefone removido]              2
                          [telefone removido]

mas quando mando salvar o hibernate da um updade do valor antigo ao invés de inserir.
como posso resolver esse problema ?

Obrigado.

8 Respostas

A

cara … o que vc quis explicar é uma relação de muitos pra muito entre tabela A e B? sendo a tabela C a relação?

D

Ola alves.Felipe
a relacao seria muitos para muitos com atributo.

M

Como assim? como vc esta salvando?. Não seria apenas salvar a classe A, depois a B e depois salvar a classse C com os objetos A e B que foram salvos?

D

Sim mas quando eu salvo ele sobrescreve o antigo periodo. Bom desisti do Embeddable e criei um generator id na classe C assim ele cria somente uma instancia para cada periodos.

D

Bom galera tentei novamente mas ainda não consegui. O meu problema é o seguinte criei uma relacionamento ManyToMany com atributo usando o Embeddable mas quando insiro ele apaga os outros valores e salva apenas a ultima data. gostaria que ficasse assim na minha classe C.

periodo       A_FK      B_FK
01/10/2010     a1          b1
02/10/2010     a1          b1
03/10/2010     a1          b1

Só que quando insiro as 3 datas ele apaga as outras duas primeiras e salva só a ultima:

periodo           A_FK      B_FK 
       0003/10/2010         a1        b1

Valeu.

D

Bom gente ja tentei de tudo sei que é questão de lógica mas não estou conseguindo.
O meu problema é o seguinte eu tenho uma classe Projetos e seus atributos e uma classe Item e seus atributos. Onde eu posso ter, por exemplo, o projeto A com as datas 01/10/2010,02/10/2010 e 05/10/2010 para o item 1,o mesmo projeto A com as datas 03/10/2010 e 10/10/2010 com o item 2 e/ou projeto B com as datas 01/10/2010 e 05/10/2010 para o item 1 (ManyToMany).Só que nunca posso ter dois itens para o mesmo projeto com a mesma data ex.( projeto A com a data 01/10/2010 para o item 1 e 2) . Como posso implementar isso usando JPA 2 e Hibernate ?
Valeu

A
resolveu seu problema? cara.. hj eu precisei fazer a mesma coisa..Minhas classes são: Solicitacao - > ItemSolicitacao<- Produto onde, ItemSolicitacao seria a tabela de junção, então eu fiz assim: na minha classe ItemSolicitacao eu criei um id de chave composta (uma classe Embeddable) ItemSolicitacaoPk :
@Embeddable
public class ItemSolicitacaoPk implements Serializable
{
	/**
	 * 
	 */
	private static final long serialVersionUID = -5704404103720777829L;
	@Column(name="ep_prod_id")
	private Integer idProduto;
	@Column(name="eps_id")
	private Integer idSolicitacaoCotacao;
public ItemSolicitacaoPk(Integer idProduto, Integer idSolicitacaoCotacao)
	{
		super();
		this.idProduto = idProduto;
		this.idSolicitacaoCotacao = idSolicitacaoCotacao;
	} ...
minha classe ItemSOlicitacao:
@Entity
@Table(name="ep_solicitacao_produtos")
public class ItemSolicitacao implements Serializable
{

	@EmbeddedId
	private ItemSolicitacaoPk id = new ItemSolicitacaoPk();
               @ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="ep_prod_id",insertable=false,updatable=false )
	private Produto produto = new Produto();
	
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name="eps_id",referencedColumnName="eps_id",insertable=false,updatable=false )
	private SolicitacaoCotacao solicitacaoCotacao;...
e minha classe Solicitacao ficou assim:
@Entity
@org.hibernate.annotations.Entity(dynamicUpdate = true, dynamicInsert = true)
@Table(name="ep_solicitacao")
public class SolicitacaoCotacao implements Serializable
{
	@Id
	@Column(name="eps_id")
//	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer id;
                @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "solicitacaoCotacao")
	private Set<ItemSolicitacao> itensSolicitacao  = new HashSet<ItemSolicitacao>();
o único problema que eu tive, foi que, na minha classe Solicitação eu estava usando um sequencia pro ID e não consegui fazer funcionar assim... eu tive que pegar o id antes de cadastrar...para setar no ItemSolicitacaoPk....
D

bom galera consegui agora não sei se é o certo mas pelo menos funciona. valeu
Minha classe A

@Entity
@Table(name = "A")
public class A implements Serializable {

	private static final long serialVersionUID = 1L;

	@Id
	private String aID;

	@OneToMany(fetch = FetchType.LAZY, mappedBy = "a",cascade = { CascadeType.ALL })
	@Cascade(value = { org.hibernate.annotations.CascadeType.ALL })
	@LazyCollection(value = LazyCollectionOption.EXTRA)
	@Fetch(value = FetchMode.SUBSELECT)
	private Set<C> c;
}

classe B

@Entity
@Table(name = "B")
public class B implements Serializable {

	private static final long serialVersionUID = 1L;

	@Id
	@Column(name = "B", nullable = false, length = 10)
	private String bID;

	@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.b",cascade = { CascadeType.ALL })
	@Cascade(value = { org.hibernate.annotations.CascadeType.ALL })
	@LazyCollection(value = LazyCollectionOption.EXTRA)
	@Fetch(value = FetchMode.SUBSELECT)
	private Set<C> c;
}

classe de relacionamento

@Entity
@Table(name = "C")
@AssociationOverride(name = "pk.b", joinColumns = @JoinColumn(name = "bID"))
@AttributeOverride(name = "periodo", column = @Column(name = "PERIODO"))
public class C{

        @EmbeddedId
	public CId pk = new CId ();

        @ManyToOne(fetch = FetchType.LAZY, optional = false)
	@Cascade(value = { org.hibernate.annotations.CascadeType.PERSIST,
			org.hibernate.annotations.CascadeType.MERGE })
	@LazyToOne(value = LazyToOneOption.PROXY)
	@Fetch(value = FetchMode.SELECT)
	public A a;


        public CId getPk() {
		return pk;
	}

	public void setPk(CId  pk) {
		this.pk = pk;
	}

	public A getA() {
		return a;
	}

	public void setA(A a) {
		this.a = a;
	}


       @Transient
	public B getB() {
		return getPk().getB();
	}

	public void setB(B b) {
		getPk().setB(b);
	}

	@Transient
	public String getPeriodo() {
		return getPk().getPeriodo();
	}

	public void setPeriodo(String Periodo) {
		getPk().setPeriodo(Periodo);
	}
}

a classe id usando o periodo e a classe B.

@Embeddable
public class CId implements Serializable {

	private static final long serialVersionUID = 9143273696872669609L;

	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	public B b;

	@Column(name = "PERIODO", length = 10)
	public String Periodo;
}

Dao salvando os periodos por B e salva tambem automaticamente a classe A caso nao exista.

A a = new A();
a.setID(1);
a.setDescricao("produto");
for(String periodos : getPeriodos().split(",")){
	C ch = new C();
	ch.setA(a);
	ch.setB(b);
	ch.setPeriodo(periodos);
	cService.salvar(ch);
}

Resultado

b1 01/01/2010 a1
b1 03/01/2010 a1
b1 04/01/2010 a2
b2 01/01/2010 a1
...

Assim nunca tenho a classe A duplicada para o mesmo periodo na mesma classe B. :smiley:

Criado 23 de agosto de 2010
Ultima resposta 31 de ago. de 2010
Respostas 8
Participantes 3