VRAPTOR: Como ele comporta com relacionamento N N com atributos

Galera,

como o VRaptor funcionaria com um Relacionamento N-N com atributo?
O atributo seria do tipo boolean e viria como default false.

Eu criei outro tópico para saber como que ele pegaria do multiselect o ids
e me ajudaram falando que era só colocar [] no name do componente.
Tudo aí beleza… Mas de acordo com um artigo que estava lendo sobre este tipo
de relcionamento no hibernate eu teria que criar duas classes a mais:
DepartamentoCurso
DepartamentoCursoPK

Onde a DepartamentoCursoPK iria contar o Departamento e o Curso…
e DepartamentoCurso iria conter um atributo do tipo DepartamentoCursoPK, e o boolean que eu preciso.

Como ficaria no Vraptor?
:frowning:

Isso fica invaiavel né?

Para fazer um N-N com o Hibernate, você só precisa de duas listas nos seus modelos.

dai com o Vraptor, você popula as listas igualzinho o multiselect.

Você vai precisar de uma terceira tabela no banco de dados (não precisa criar uma classe para ela) onde será feito o relacionamento.

[quote=Rafael Guerreiro]Para fazer um N-N com o Hibernate, você só precisa de duas listas nos seus modelos.

dai com o Vraptor, você popula as listas igualzinho o multiselect.

Você vai precisar de uma terceira tabela no banco de dados (não precisa criar uma classe para ela) onde será feito o relacionamento.[/quote]

vlw pela resposta.
O relacionamento n-n ja esta funcionando.
O problema é n-n com atributos.
Vc leu o que eu postei?

¬¬

Lógico que eu li, você quer setar os atributos na view ou pegar ja setado?

Para setar na view: name=lista[0].atributo
para pegar setado do banco: this.session.get(id);

Você pode até registrar um converter no VRaptor que recebe seu dao e já faz o session.get(Long.parseLong(value));

Assim, você coloca no name: lista[0]
e passa só o id para a requisição, dai o ID vai cair no converter e o converter vai devolver a instancia toda preenchida para voce.

mas eu realmente teria q criar as outras duas classes né?

cara, vou explicar melhor.
to tentando imitir o email…

entao tenho classe

Mensagem
que possui N-N com:
Funcionario
Professor
Aluno

correto?
Gerei mensagens_do_professor
mensagens_do_aluno
mensagens_do_professor

para mapear isto.
Só que eu tinha um atributo
boolean lida na classe mensagem.
Só agora q percebi que nao funcionaria, já que é uma mensagem compartilhada com varios destinatarios.

Por tanto o boolean lida deveria ser uma coluna de mensagens_do_“professor/aluno/funcionario”

Só que criando as 6 classes:

MensagemProfessor
MensagemAluno
MensagemFuncionario
MensagemProfessorPK
MensagemAlunoPK
MensagemFuncionarioPK

eu passaria de:

@Post
@Path(/mensagem/save)
public void save(Mensagem mensagem){
//...
}

para outra coisa q nao sei como ficaria.
entendeu?

Não… Foi isso que eu disse no primeiro post.

Vamos supor as duas entidades A e B (as duas se relacionam de muitos pra muitos):

@Entity
@Table(name="TB_A")
public class A {
   @Id
   @Column(name="A_ID")
   private Long id;

   @Column(name="NAME", length = 255, nullable = false)
   private Long name;

   @JoinTable(name="TB_A_B", joinColumn = @JoinColumn(name="A_ID", nullable = false), inverseJoinColumn = @JoinColumn(name="B_ID", nullable = false))
   @ManyToMany
   private List<B> bs;
// getters e setters
}

@Entity
@Table(name="TB_B")
public class B {
   @Id
   @Column(name="B_ID")
   private Long id;

   @Column(name="NAME", length = 255, nullable = false)
   private Long name;

   @JoinTable(name="TB_A_B", joinColumn = @JoinColumn(name="B_ID", nullable = false), inverseJoinColumn = @JoinColumn(name="A_ID", nullable = false))
   @ManyToMany
   private List<B> bs;
// getters e setters
}

Lembrando que na tabela TB_A_B você não precisa criar um modelo para ela e que as duas colunas (A_ID e B_ID) que ela vai ter não podem ser chaves e nem unique.

vixi cara,
vc não entendeu.

o N-N esta resolvido…

        //Mensagem.java
	@ManyToMany(fetch=FetchType.LAZY)
	@JoinTable(name="mensagens_do_professor",
	joinColumns=@JoinColumn(name="id_mensagem"),
	inverseJoinColumns=@JoinColumn(name="id_professor"))
	private Collection<Professor> professores;
      
       //Professor.java
	@ManyToMany(fetch=FetchType.EAGER)
	@JoinTable(name="mensagens_do_professor",
	joinColumns=@JoinColumn(name="id_professor"),
	inverseJoinColumns=@JoinColumn(name="id_mensagem"))
	private List<Mensagem> mensagens;

Correto? Agora quero saber, como que eu adiciono um atributo:

na entidade mensagens_do_professor???

Por que você não cria uma entidade email que vai receber o assunto, a mensagem (a classe mensagem relacionamento N emails para 1 mensagem) e um boolean lido ou não.
Então, cada pessoa recebe um email (relacionamento 1 pessoa para N emails).

Então, mas não precisa criar as classes, é só você receber a entidade na tela, mudar o que precisar mudar e fazer um merge no banco.
Faz assim:
Quando o cara abrir o e-mail você faz uma requisição ajax (está usando jquery?) passando o id do cara e o id da mensagem.

Lá você vai ter uma lógica que vai pegar esse id vindo da requisição e troca o boolean para true. e devolve http status 200 se der tudo certo.

Ou o seu problema é aonde colocar esse atributo lido? Se for esse, considera em criar aquela classe email que eu disse em cima.

[quote=Rafael Guerreiro]Por que você não cria uma entidade email que vai receber o assunto, a mensagem (a classe mensagem relacionamento N emails para 1 mensagem) e um boolean lido ou não.
Então, cada pessoa recebe um email (relacionamento 1 pessoa para N emails).[/quote]

Que ideia interessante.
Tipo assim:

@Entity
public class Email{
    @Id
    private Integer id;
    private Mensagem m;
    private boolean lido = false;

   //lista de professores, alunos e funcionarios
}

Aí as entidades com o relacionamento:

@Entity
public class Professor{
//...
@ManyToMany(fetch=FetchType.EAGER)  
@JoinTable(name="emails_do_professor",  
joinColumns=@JoinColumn(name="id_professor"),  
inverseJoinColumns=@JoinColumn(name="id_email"))  
private List&lt;Email&gt; emails;  

}

Outra coisa… quando eu for fazer o save, eu vou ter que salvar tanto uma Mensagem tanto quanto um Email…
Como ficaria isto no vraptor?

public void save(Mensagem m, Email e){
   Mensagem nova = mensagemDao.save(m);
   e.setMensagem(nova);
   emailDao.save(e);
}

tipo assim?

Não, cada e-mail vai ter 1 pessoa, ou seja, um email é do professor e outro é do aluno, ids diferentes, mas a mesma mensagem.

Olha lá o relacionamento que eu falei: N Emails para 1 Mensagem e 1 pessoa para N emails.

Para salvar tudo junto, dentro de e-mail:

@Entity  
public class Email{  
    @Id  
    private Integer id;  
    @ManyToOne(cascade = CascadeType.ALL) // Ou seja, remove a mensagem (se não tiver mais ninguem usando) quando este email for removido. Salva a mensagem quando o email for salvo, altera a mensagem quando o email for alterado. (assim você usa o dao só de email. só um session.save(email) já vai salvar a mensagem dentro dele)
    private Mensagem m;  
    private boolean lido = false;  
  
   //lista de pessoa (superclasse de professor, aluno e funcionário)
} 

[quote=Rafael Guerreiro]Não, cada e-mail vai ter 1 pessoa, ou seja, um email é do professor e outro é do aluno, ids diferentes, mas a mesma mensagem.
Olha lá o relacionamento que eu falei: N Emails para 1 Mensagem e 1 pessoa para N emails.
[/quote]

Se for N para 1 pessoa aí complicou…
pq tipo não uso herença nas entidades.

Teria q fazer 3 entidades diferentes?

EmailProfessor
EmailAluno
EmailFuncionario?

pq aí

EmailProfessor
ManyToOne Professor professor
Mensagem mensagem

Professor
OneToMany
List<Email>

Até pode fazer. Mas fica feio demais.

Me mostra as 3 entidades (professor, funcionario e aluno) para eu ver.

[code]@Entity
@Table(name=“professores”)
public class Professor extends AbstractBaseEntity< Integer > implements Autenticavel{

@Entity
@Table(name=“alunos”)
public class Aluno extends AbstractBaseEntity implements Comparable, Autenticavel{
[/code]

Este projeto já peguei em andamento. :frowning:
Tenho que implementar o sistema de mensagens…

Qndo tava tudo pronto…percebi que havia colocado o Boolean lida como
atributo de “Mensagem”. Assim se eu tiver 10 destinatários e 1 deles ler a mensagem,
vai aparecer para todos os outros 9, que a mensagem ja foi lida. :frowning:

OPAAA

posso usar o @Any para o destinatário!!! :smiley:

Me ajuda a esboçar as classes usando a solução que vc propos?

A minha ideia era voce ter 1 classe só chamada Pessoa.

E dentro dela você teria uma ENUM com os tipos de Pessoa:

[code]
public class Pessoa{
private Long id;
private String name;
private List<Email> emails;

@Enumerated(EnumType.STRING) // Salva o .name() da enum
@Enumerated(EnumType.ORDINAL) // Salva o .ordinal() da enum
private TipoPessoa tipo;
}
public enum TipoPessoa {
PROFESSOR, ALUNO, FUNCIONARIO
}[/code]

nao precisa,

é só uaar o ANY

me ajuda a esboçar as classes?

(para vc ver o any funcionando:


	@Any(metaColumn = @Column(name = "tipo_autenticavel"), fetch=FetchType.EAGER,  optional = false	)
	@AnyMetaDef(idType = "integer", metaType = "string", metaValues =
	{
			@MetaValue(value = "A", targetEntity = Aluno.class),
			@MetaValue(value = "P", targetEntity = Professor.class),
			@MetaValue(value = "F", targetEntity = Funcionario.class) })
	@JoinColumn(name = "codigo_autenticavel")
	private Autenticavel remetente;

)

ajuda com o esboço?

por favor,
ver continuação deste tópico em:

http://guj.com.br/java/276432-vraptor–modelagem–hibernate