@OneToOne

10 respostas
R

Olá,

Estou tentando fazer um relacionamento mas não está dando muito certo!

Tenho duas tabelas: ‘usuario’ e ‘disponibilidade’;

usuario:

id;(PK)

nome;
disponibilidade:

id;(PK)

usuario_id;(FK)

disponivel;

Preciso buscar um usuario e saber se ele está disponivel. Fiz o mapeamento + ou - assim:

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

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id")
	private int id;
	
	@OneToOne(mappedBy = "usuario", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	private Disponibilidade disponibilidades;

	@Column(name = "nome")
	private String nome;
        
        //getter e setter


@Entity
@Table(name = "disponibilidade", schema = "******")
public class Disponibilidade implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;
	
	@JoinColumn(name = "usuario_id")
	private Usuario usuario;
	
	@Column(name = "disponivel")
	private int disponivel;

        //getter e setter

e criei um metodo para buscar todos os registros.

E dá um erro que pelo que percebi algo está nulo.

Alguém poderia me ajudar?
Obrigado

10 Respostas

Vini_Fernandes

Cara, pelo o que entendi de seu codigo, voce deve ter um relacionamento de UM usuario para MUITAS disponilidades e nao UM para UM como voce esta modelando! Para ver isso basta realizar o seguinte select:

//pesquisando todas as disponibilidades do usuario com id = 1
select diponibilidade.id from usuario, disponibilidade where usuario.id = disponibilidade.usuario_id and usuario.id = 1

Consequentemente em seu Entity Bean voce deve substituir a atributo:

private Disponibilidade disponibilidades;

//substituindo por
private Collection<Disponibilidade> disponibilidades;

ate

R

O relacionamento no meu caso seria @OneToOne.
a disponibilidade citada teria apenas duas respostas: nulo ou x;

então preciso fazer uma consulta que liste o usuario e a sua disponibilidade daquele momento.

vc faz idéia da onde esteja o erro?

Vini_Fernandes

Cara, supondo que voce tenha um relacionamento one-to-one entao vejo dois possiveis erros em seu codigo:

public class Disponibilidade implements Serializable{   
  
    /**  
     *  
     */   
    private static final long serialVersionUID = 1L;   
       
    @Id   
    @GeneratedValue(strategy = GenerationType.IDENTITY)   
    //aqui deveria ter uma  @Column(name = "id")   
    private int id;   

    @JoinColumn(name = "usuario_id")   
    /*
     *como voce tem um on-to-one aqui voce deveria ter algo 
     *@OneToOne(mappedBy = "disponibilidade", cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
     *analogo ao que voce fez na classe usuario     
     */
    private Usuario usuario;

Outra coisa, veja se nao esta faltando um atributo foreign-key na annotation, por exemplo:
@OneToOne(mappedBy = “usuario”, cascade = CascadeType.ALL, fetch = FetchType.EAGER, foreign-key = “sua chave estrangeira”)
Veja se funciona, mas eu ainda acho que NAO se trata de um relacionamento one-to-one

Ate

otavio

Renato, dizer que deu um erro e pedir ajuda é muuuito vago. Coloque aqui a mensagem de erro e o stacktrace, assim fica bem mais fácil te ajudar.

R

Pois então, fiz um metodo utilizando apenas a tabela usuario e não me resultou erro nenhum, mas quando utilizei o relacionamento apresenta :

Exception in thread main java.lang.NullPointerException

at br.com.stenovoice.dao.HibernateTransactionUtils.getSession(HibernateTransactionUtils.java:51)

at br.com.stenovoice.dao.HibernateCRUDUtils.getById(HibernateCRUDUtils.java:99)

at br.com.stenovoice.dao.BaseDAO.getByPrimaryKey(BaseDAO.java:37)

at br.com.stenovoice.application.UsuarioService.getUsuarioPorId(UsuarioService.java:62)

at br.com.stenovoice.teste.UsuarioTeste.main(UsuarioTeste.java:22)

o que será?

otavio

Renato_natos:
Pois então, fiz um metodo utilizando apenas a tabela usuario e não me resultou erro nenhum, mas quando utilizei o relacionamento apresenta :

Exception in thread main java.lang.NullPointerException

at br.com.stenovoice.dao.HibernateTransactionUtils.getSession(HibernateTransactionUtils.java:51)

at br.com.stenovoice.dao.HibernateCRUDUtils.getById(HibernateCRUDUtils.java:99)

at br.com.stenovoice.dao.BaseDAO.getByPrimaryKey(BaseDAO.java:37)

at br.com.stenovoice.application.UsuarioService.getUsuarioPorId(UsuarioService.java:62)

at br.com.stenovoice.teste.UsuarioTeste.main(UsuarioTeste.java:22)

o que será?

o que tem nessa HibernateTransactionUtils.java:51?

R

Acontece que fiz o mapeamento da tabela usuario sem nenhuma relação e criei um método para buscar por id, e deu certo, e agora inclui a relação de um para um e pedi para buscar por id e deu errado.
Pelo que pude perceber o erro está no mapeamento das tabelas. Mas mesmo assim na linha 51 têm o seguinte código:
session = sessionFactory.openSession();

este programa já foi testado anteriormente e deu certo, mas não consigo tirar da cabeça que o erro é do mapeamento!!
Obrigado

otavio
<blockquote>Exception in thread “main” java.lang.NullPointerException

at br.com.stenovoice.dao.HibernateTransactionUtils.getSession(HibernateTransactionUtils.java:51)

at br.com.stenovoice.dao.HibernateCRUDUtils.getById(HibernateCRUDUtils.java:99) </blockquote>

O erro está nessa classe: HibernateTransactionUtils.java:51

Mande o código completo dela. Provavelmente o sessionFactory está null.

R
public class HibernateTransactionUtils {
	private static SessionFactory sessionFactory;
	
	private static Logger log = Logger.getLogger(HibernateTransactionUtils.class);;
	
	public HibernateTransactionUtils() {
		try {
			// Cria a instância da SessionFactory
			sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
			HibernateTransactionUtils.setSessionFactory(sessionFactory);
			
		} catch (Throwable ex) {
			// Não foi possível iniciar a SessionFactory - abortando a
			// inicialização da aplicação e logando o problema-
			log.fatal("\n\n\n\n\n\n\n>>>>>Criacao do SessionFactory falhou.\n" + ex);
			
		}	
	}
		
	/*
	 * Session Factory que gerencia as sessões do Hibernate
	 */
	private static final ThreadLocal<Session> tlSession = new ThreadLocal<Session> ();
	
		
	/**
	 * Método responsável por retornar uma sessão com o Hibernate 
	 * @return
	 * @throws HibernateException
	 */
	public static Session getSession() throws HibernateException {
		System.out.println("UTILD");
        Session session = (Session) tlSession.get();
        
        // Abre uma nova session caso esta Thread não tenha uma vinculada
        if (session == null || !session.isOpen()) {
        	session = sessionFactory.openSession();

            // Armazena na variável ThreadLocal
            tlSession.set(session);
        }
        HibernateTransactionUtils.getSFStatistics();
        return session;
    }
	
	/**
	 * Método responsável por fechar uma conexão com o Hibernate
	 * @throws HibernateException
	 */
	public static void closeSession() throws HibernateException {
        Session s = (Session) tlSession.get();
        if (s != null)
            s.close();
        tlSession.set(null);
    }
	
	/**
	 * Retorna uma referência para a SessionFactory
	 * @return
	 */
    public static SessionFactory getSessionFactory( ) {
      return sessionFactory;
    }
    
    /**
	 * Configura um SessionFactory SessionFactory
	 * @return
	 */
    public static void setSessionFactory(SessionFactory factory) {
    	sessionFactory = factory;
    	sessionFactory.getStatistics().setStatisticsEnabled(true); //Estatísticas de performance do Hibernate.
    }

    
    /**
     * Método responsável por realizar um rollback na transação aberta pelo Hibernate
     * 
     * @param transaction
     */
    public static void rollback(Transaction transaction) {
        if (transaction != null) {
            try {
                transaction.rollback( );
            }
            catch (HibernateException ex) {
                // Logar e retornar a execução de um rollback;
            	log.debug(">>>>>Não foi possível realizar o rollback");
            }
        }
    }

    /**
     * Método responsável por realizar um commit na transação aberta pelo Hibernate
     * 
     * @param transaction
     */
    public static void commit(Transaction transaction) {
        if (transaction != null) {
            try {
                transaction.commit( );
            }
            catch (HibernateException ex) {
            	log.debug(">>>>>Não foi possível realizar o commit.");
            }
        }
    }
    
    public static Map<String, String> getSFStatistics() {
    	Statistics stats = sessionFactory.getStatistics();
    	HashMap<String, String> statMap = new HashMap<String, String>();
    	statMap.put("open_sessions", Long.toString(stats.getSessionOpenCount()));
    	System.out.println("\n\n>>>>>>>>>>>>>>>>>Open Sessions => " + statMap.get("open_sessions"));
    	return null;
    }

	public static Transaction getTransaction() {
		return null;
	}

}
otavio
public HibernateTransactionUtils() {   
        try {   
            // Cria a instância da SessionFactory   
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();   
            HibernateTransactionUtils.setSessionFactory(sessionFactory);   
               
        } catch (Throwable ex) {   
            // Não foi possível iniciar a SessionFactory - abortando a   
            // inicialização da aplicação e logando o problema-   
            log.fatal("\n\n\n\n\n\n\n>>>>>Criacao do SessionFactory falhou.\n" + ex);   
               
        }     
}

Pelo que notei você está tentando chamar o método public static Session getSession() throws HibernateException. Note que ele é static, ou seja, NUNCA chama o construtor. Ou seja, tua sessionFactory SEMPRE será NULL, dando o NullPointerException.

Altere para um bloco estático:

static {   
        try {   
            // Cria a instância da SessionFactory   
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();   
            setSessionFactory(sessionFactory);   
               
        } catch (Exception ex) {   
            // Não foi possível iniciar a SessionFactory - abortando a   
            // inicialização da aplicação e logando o problema-   
            log.fatal("\n\n\n\n\n\n\n>>>>>Criacao do SessionFactory falhou.\n" + ex);   
        }     
}

Outra coisa, NUNCA use catch de Throwable, pois ela captura tanto exceptions como errors, sendo esses segundos basicamente não tratáveis.

Criado 10 de fevereiro de 2009
Ultima resposta 10 de fev. de 2009
Respostas 10
Participantes 3