Duvida com relacionamentos - Hibernate

Pessoal,

Estou com uma grande duvida, ja dei uma pesquisada na net, mas até agora não encontrei nada muito esclarecedor nem consegui evoluir.
Eu nao estou conseguindo persistir meus dados quando tenho um relacionamento ManyToOne, no meu caso, eu quero persistir os dados de um usuario do sistema, esse usuario tem nome, login, senha e tipo 9que é um TipoUsuario).
Fiz as classes Usuario e TipoUsuario, coloquei uma coleção na minha classe TipoUsuario e um atributo do TipoUsuario na minha classe Usuario, tambem fiz as anotações de persistencia, mas nao sei se fiz corretamente e tenho bastante duvida na hora de persistir: como vou pegar o tipo de usuario que vem como int (apenas o codigo) do form html e persistir os dados de usuario e depois como vou listar esse usuario mostrando o seu tipo? Algo assim…

Usuario.java:

package catalogo.modelo;

import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.Fetch;

@Entity
@Table(name = "usuario", schema = "catalogo")
public class Usuario implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_usuario")
    private int id;
    
    @Column(name = "nome")
    private String nome;
    
    @Column(name = "login")
    private String login;

    @Column(name = "senha")
    private String senha;

    @ManyToOne(fetch = FetchType.EAGER, optional = false)
    @JoinColumn(name = "id_tipo_usuario", referencedColumnName = "id_tipo_usuario", insertable = true, updatable = true)
    @Fetch(org.hibernate.annotations.FetchMode.JOIN)
    @Cascade(org.hibernate.annotations.CascadeType.ALL)
    @Column(name = "id_tipo_usuario")
    private TipoUsuario tipoUsuario;

    //setter e getters
}

TipoUsuario.java:
[/code]
package catalogo.modelo;

import java.io.Serializable;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = “tipo_usuario”)
public class TipoUsuario implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_tipo_usuario")
private int id;

@Column(name = "tipo")
private String tipo;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "tipoUsuario", fetch = FetchType.LAZY)
private Collection<Usuario> usuarioCollection;

//getters e setters

}

[code]

Alguem pode me ajudar? Me mostrar o que devo melhorar, onde estou errando, etc.

vc inverteu
ficaria assim

Usuario

 @OneToMany(mappedBy="usuario" fetch = FetchType.LAZY)  
 @Cascade(CascadeType.ALL)  
  private Collection<TipoUsuario> tipoUsuario;  

TipoUsuario

@ManyToOne(fetch = FetchType.EAGER)
@JoinColum(name="id_usuario")
@Fetch(FetchMode.JOIN)
@Cascade(CascadeType.ALL)
private Usuario usuario

fiz assim com base nos nomes,mas acho q a relacao de usuario para o seu tipo seria OneToOne a nao ser q ele possa ter mais de um ai sim.

Desconfiei que estaria invertendo hehehe
Não fui eu que modelei o sistema, tambem acho que poderia ser OneToOne. Se for OneToOne eu vou poder ter um perfil administrador e outro usuario, mas com logins diferentes né? Seria isso?
A minha duvida agora nao eh nem com hibernate e anotações, é com OO mesmo, como eu apenas com o codigo do tipo de usuario (que vem atraves do form html) vou persistir o meu usuario, ja que o meu atributo tipoUsuario da classe Usuario eh do tipo TipoUsuario e nao int?

Pessoal,

Porque nao estou conseguindo colocar a anotação assim: @Fetch(FetchMode.JOIN)
Só assim: @org.hibernate.annotations.Fetch(org.hibernate.annotations.FetchMode.JOIN)
O Cascade ficou assim:
@Cascade(org.hibernate.annotations.CascadeType.ALL)

Porque estou tendo que colocar o org.hibernate… na frente?

Alguem sabe porque?

vc em o .jar para annotations no seu projeto? Lembre-se das diferenças entre as anotacoes do hibernate e annotations em sim.

Acabei de ver as bibliotecas do meu projeto e tem o jar das anotações - hibernate-annotations.jar - tanto tem que algumas anotações eu nao preciso colocar o caminho completo, só nessa que exemplifiquei acima.
Muito estranho isso, mas isso é o de menos. A minha maior dúvida ainda continua sendo como salvar o usuario, sendo que este tem um atributo TipoUsuario?

Fiz assim, mas ainda nao ta salvando:

IncluirUsuarioForm usuarioForm = (IncluirUsuarioForm) form;
        
        Usuario usuario = new Usuario();
        usuario.setNome(usuarioForm.getNome());
        usuario.setLogin(usuarioForm.getLogin());
        usuario.setSenha(usuarioForm.getSenha());

        TipoUsuario tipo = new TipoUsuario();
        tipo.setId(usuarioForm.getTipoUsuario());
        tipo.setUsuario(usuario);

        /*Collection tipoUsuarios = new ArrayList();
        tipoUsuarios.add(tipo);

        usuario.setTipoUsuario(tipoUsuarios);*/
        
        usuario.setTipoUsuario(new HashSet<TipoUsuario>());
        usuario.getTipoUsuario().add(tipo);

o problema com os nomes das classes é pq vc jah importou a classe que tem o mesmo nome, mas do JPA. (JPA e Hibernate tem classes com nomes identicos que fazem a mesma coisa…)

dá uma olhada nos seus imports…

Quanto a sua dúvida… o JPA só precisa da chave do “TipoUsuario” pra persistir ele… é isso que vc tá em dúvida?

Se for, instancia e “seta” a chave… e seja feliz… hehehehe

Abraço!

Poderia me exemplificar?

Eu nao consegui entender direito nem implementar como vou colcoar collections de tipo de usuarios no meu objeto usuario, mais ou menos isso a minha duvida.
Acho que fiz o mapeamento da minha relação correto:

Usuario:

    @OneToMany(mappedBy="usuario", fetch = FetchType.LAZY)
    @Cascade(CascadeType.ALL)
    private Collection<TipoUsuario> tipoUsuario;

TipoUsuario:

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name= "id_usuario", insertable=true, updatable=true)
    @Fetch(FetchMode.JOIN)
    @Cascade(CascadeType.SAVE_UPDATE)
    private Usuario usuario;

Ta certo o mapeamento e o relacionamento?

Na minha action fiz isso:

        IncluirUsuarioForm usuarioForm = (IncluirUsuarioForm) form;
        
        Usuario usuario = new Usuario();
        usuario.setNome(usuarioForm.getNome());
        usuario.setLogin(usuarioForm.getLogin());
        usuario.setSenha(usuarioForm.getSenha());

        TipoUsuario tipo = new TipoUsuario();
        tipo.setId(usuarioForm.getTipoUsuario());
        tipo.setUsuario(usuario);

           
        usuario.setTipoUsuario(new HashSet<TipoUsuario>());
        usuario.getTipoUsuario().add(tipo);
        
         request.setAttribute("usuario", usuario);
        request.setAttribute("tipoUsuario", tipo);

Do jeito que esta aqui nao esta salvando nada no BD, nao sei o que fazer

Pessoal,

Até agora não consegui resolver esse problema e fiquei com outra dúvida: eu criei a minha tabela corretamente, colocando o id do TipoUsuario dentro da tabela Usuario? Ou devo colocar o id do Usuario dentro de Tipo Usuario?
Pelo que pude perceber eu colocando o id_tipo_usuario dentro da tabela usuario, como foreign key, então o relacionamento inverte, fica como postei aqui no começo, ou seja, a minha entidade TipoUsuario vai ter uma collection de usuarios, e a minha classe Usuario vai ter um atributo do tipo TipoUsuario, com o relacionamento de muitos para um, estou enganado?

Pessoal,

Inverti aqui: coloquei uma coleção de usuarios na classe TipoUsuario, mas nao salvou nada no BD.
Nao eh possivel isso, ja olhei tudo e acho que ta certo, por favor, alguem me ajude, ja perdi tres dias nesse erro bobo e nao posso perder tempo com isso, nao sei mais o que fazer.
Meus codigos ficaram assim:

TipoUsuario:

    @OneToMany(mappedBy="tipoUsuario", fetch = FetchType.LAZY)
    @Cascade(CascadeType.ALL)
    private Collection<Usuario> usuarios;

Usuario:

@ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "id_tipo_usuario", insertable = true, updatable = true) @Fetch(FetchMode.JOIN) @Cascade(CascadeType.ALL) private TipoUsuario tipoUsuario;

Minha action:

[code] IncluirUsuarioForm usuarioForm = (IncluirUsuarioForm) form;

    TipoUsuario tipoUsuario = new TipoUsuario();
    tipoUsuario.setId(usuarioForm.getTipoUsuario());

    Usuario usuario = new Usuario();
    usuario.setNome(usuarioForm.getNome());
    usuario.setLogin(usuarioForm.getLogin());
    usuario.setSenha(usuarioForm.getSenha());

    tipoUsuario.setUsuarios(new HashSet<Usuario>());
    tipoUsuario.getUsuarios().add(usuario);

    usuario.setTipoUsuario(tipoUsuario);

    request.setAttribute("usuario", usuario);
    request.setAttribute("tipoUsuario", tipoUsuario);

    Session session = HibernateUtil.getSession();

    GenericDAO<TipoUsuario> dao = new GenericDAO(session, TipoUsuario.class);

    try
    {
        dao.Salvar(tipoUsuario);
        retorno = "sucesso";
    }
    catch (Exception e) {
        System.out.println(e.getMessage());
        retorno = "erro";
    }[/code]

Por favor, me ajudem. Espero que estejam entendendo a minha duvida e o erro.

Descobri porque não estava salvando no BD: o problema é que eu tenho um atributo tipo na minha classe TipoUsuario, e no action eu apenas seto o id da meu objeto TipoUsuario, se eu setar todos os dados do meu objeto Usuario e todos os dados do meu objeto TipoUsuario (nesse caso colocando id e tipo) ele persitr no BD, mas com um GRANDE PROBLEMA, ao fazer isso ele salva um novo tipo_usuario no BD e coloca esse novo id na minha tabela de usuario. Por exemplo, eu tenho na tabela tipo_usuario, usuario e administrador (codigo 1 e 2), se eu setar o atributo tipo no meu objeto com teste, ele vai salvar um novo tipo_usuario chamado teste, com o codigo 3 e na chave estrangeira da minha tabela usuario ele salva o codigo 3. Como contornar isso? Não quero que seja assim, quero que se o cara escolher no form html o tipo de usuario administrador(2), entao que salve na tabela usuario o codigo 2, deu pra entender?

Ja tentei inverter o relacionamento, colocando a collection na classe usuario, mas se eu fizer isso ele atualiza o tipo de usuario administrador para teste, por exemplo, se alguem souber onde estou errando ou como contornar isso, e puder me dá uma força, agradeço.

TipoUsuario:

    @OneToMany(mappedBy="tipoUsuario", fetch = FetchType.LAZY)
    @Cascade(CascadeType.SAVE_UPDATE)
    private Collection<Usuario> usuarios;

Usuario:

@ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "id_tipo_usuario", insertable = true, updatable = true) @Fetch(FetchMode.JOIN) @Cascade(CascadeType.ALL) private TipoUsuario tipoUsuario;

Action:

        TipoUsuario tipoUsuario = new TipoUsuario();
        tipoUsuario.setId(usuarioForm.getTipoUsuario());
        tipoUsuario.setTipo("teste");

        Usuario usuario = new Usuario();
        usuario.setNome(usuarioForm.getNome());
        usuario.setLogin(usuarioForm.getLogin());
        usuario.setSenha(usuarioForm.getSenha());

        tipoUsuario.setUsuarios(new HashSet<Usuario>());
        tipoUsuario.getUsuarios().add(usuario);

        usuario.setTipoUsuario(tipoUsuario);

        request.setAttribute("usuario", usuario);
        request.setAttribute("tipoUsuario", tipoUsuario);

        Session session = HibernateUtil.getSession();

        GenericDAO<TipoUsuario> dao = new GenericDAO(session, TipoUsuario.class);

        try
        {
            dao.Salvar(tipoUsuario);
            retorno = "sucesso";
        }
        catch (Exception e) {
            System.out.println(e.getMessage());
            retorno = "erro";
        }

Alguem pode me ajudar?

Tem como eu alterar isso? Por que eu preciso sempre setar e meu atributo tipo do meu objeto TipoUsuario? Se eu setar com qualquer coisa ele vai atualizar na minha tabela, não quero isso, to fazendo umas alterações aqui pra trazer o tipo do BD e depois atualizar no BD tambem, mas to achando que ta errado, eh assim que tenho que fazer: se quiser continuar com o tipo Administrador na tabela, tennho que caregar esse tipo do bd pro meu objeto pra que persista corretamente?