[RESOLVIDO] Erro ao persistir objeto - JSF + Hibernate

Olá pessoal, estou com um problema, se alguém puder ajudar serei muito grato:

Tenho um xhtml que faz uma pesquisa simples, pelo ID do objeto REGISTRO:

	<h:form>
		<h:outputLabel value="Id do post: " for="id" />
		<h:inputText value="#{registroBean.registro.id}" id="id" />
		<br />
		<br />
		<h:commandButton action="#{registroBean.listar}" value="Buscar" />
	</h:form>

Ele retorna perfeitamente os dados para uma xhtml onde há um objeto rating do primefaces, para votação:

		<h:form id="formVotacao">
			<h:outputText value="ID do Registro: " />
			<h:outputText value="#{registroBean.registro.id}" />
			<br />
			<br />
			<h:outputText value="ID do Rating: " />
			<h:outputText value="#{registroBean.registro.rating.id}" />
			<br />
			<br />
			<h:outputLabel value="Título: " for="titulo" />
			<h:outputText value="#{registroBean.registro.titulo}" id="titulo" />
			<br />
			<br />
			<h:outputLabel value="Descrição: " for="descricao" />
			<h:outputText value="#{registroBean.registro.descricao}" id="descricao" />
			<br />
			<br />
			<h:outputLabel value="Imagem: " for="imagem" />
			<br />
			<h:graphicImage id="imagem" library="imagens" name="#{registroBean.registro.imagem}" />
			<br />
			<br />
			<p:rating value="#{ratingBean.star}" />
			<br />
			<br />
			<h:commandButton action="#{ratingBean.salvar}" value="Votar" />
		</h:form>

O problema é que, o objeto REGISTRO tem uma relação OneToOne com o objeto RATING, mas o ManagedBean do objeto Rating não carrega os valores do banco e quando o botão dispara a ação salvar, o Hibernate retorna :

SEVERE: org.hibernate.TransientObjectException: The given object has a null identifier: com.matrix.modelo.rating.Rating
javax.faces.el.EvaluationException: org.hibernate.TransientObjectException: The given object has a null identifier: com.matrix.modelo.rating.Rating

Alguém saberia me dar alguma dica de como resolver isso?

O erro é objeto null.

posta seu manegedBean(Backingbean).

Então luan_gazin, o problema é que não entendo como fazer para carregar um objeto RATING a partir do que est[a contido no objeto REGISTRO.

meu backing bean registroBean:

@ManagedBean(name="registroBean")
@SessionScoped
public class RegistroBean {

	private Registro registro = new Registro();
	private static String caminho;
	
	
	
	public String salvar(){
		registro.setImagem(caminho);
		
		Rating rating = new Rating();
		rating.setStar1(0);
		rating.setStar2(0);
		rating.setStar3(0);
		rating.setStar4(0);
		rating.setStar5(0);
		RatingRN ratingRN = new RatingRN();
		ratingRN.salvar(rating);
		
		registro.setRating(rating);
		
		RegistroRN registroRN = new RegistroRN();
		registroRN.salvar(registro);
		System.out.println("Salvando...");
		return "preview";
	}
	
	public String alterar(){
		RegistroRN registroRN = new RegistroRN();
		registroRN.alterar(registro);
		System.out.println("Atualizando...");
		return "sucesso";
	}

	public String listar(){
		RegistroRN registroRN = new RegistroRN();
		registro = registroRN.buscarRegistroPorId(registro);
		
		return "votacao";
	}
	
	
	public Registro getRegistro() {
		return registro;
	}


	public void setRegistro(Registro registro) {
		this.registro = registro;
	}

Backing bean RatingBean:

@ManagedBean(name="ratingBean")
@SessionScoped
public class RatingBean {

    private Rating rating = new Rating();
    private Integer star = 0;
    
    public void onrate(RateEvent rateEvent) {  
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Rate Event", "You rated:" + ((Integer) rateEvent.getRating()).intValue());  
  
        FacesContext.getCurrentInstance().addMessage(null, message);  
    }  
      
    public void oncancel() {  
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cancel Event", "Rate Reset");  
  
        FacesContext.getCurrentInstance().addMessage(null, message);  
    }

    public String salvar(){
    	System.out.println("### Salvando rating ###");
    	Integer valorStar = 0;
 
    	if (star == 1){
    		valorStar = rating.getStar1();
    		rating.setStar1(valorStar + 1);
    	} else if (star == 2){
    		valorStar = rating.getStar2();
    		rating.setStar2(valorStar + 1);
    	} else if (star == 3){
    		valorStar = rating.getStar3();
    		rating.setStar3(valorStar + 1);
    	} else if (star == 4){
    		valorStar = rating.getStar4();
    		rating.setStar4(valorStar + 1);
    	} else if (star == 5){
    		valorStar = rating.getStar5();
    		if (valorStar == null || valorStar == 0){
    			System.out.println("### valor do banco está nulo ###");
    			rating.setStar5(1);
    		} else {
    			System.out.println("### valor de star no banco: " + valorStar + " ###");
    			rating.setStar5(valorStar + 1);
    		}
    	}
    	
    	
		RatingRN ratingRN = new RatingRN();
		ratingRN.alterar(rating);
		return "sucesso";
	}
    
    
	public Rating getRating() {
		return rating;
	}

	public void setRating(Rating rating) {
		this.rating = rating;
	}

	public Integer getStar() {
		return star;
	}

	public void setStar(Integer star) {
		this.star = star;
	}

Acredito que o seu problema é que está tentando fazer um update de um objeto Rating que não existe na base de dados, já que ele está com id null. O correto seria você carregar o Rating do banco ou fazer um persist, o que geraria vários Ratings inúteis (dependendo da sua lógica de negócio).

Vinicius, o caso realmente é esse: eu faço uma busca que retorna um objeto Registro. Ele tem uma relação 1-1 com um objeto Rating e então tem um objeto Rating ligado à ele. Como eu poderia fazer para carregar no backing bean RatingBean o objeto com o ID correspondente ao que retornou na busca do objeto Registro? Eu consigo fazer isso, mas colocando todo o código no RegistroBean o que acaba misturando toda a lógica e fica praticamente uma gambiarra.

Alguma idéia num caso como esse?

Então o seu RegistroBean vai ter que ter uma referência para o RatingBean e chamar o setter do Rating quando carregar o registro do banco. Se estiver usando JSF 2.0, pode utilizar a injeção de managed beans pela anotação @ManagedProperty(value="#{registroBean}").

Vou fazer um teste conforme sua indicação e depois posto no que deu.

Você teria algum exemplo simples do uso dessa anotação @ManagedProperty?

obrigado!!

Aqui tem um exemplo: http://www.mkyong.com/jsf2/injecting-managed-beans-in-jsf-2-0/

Vinicius, funcionou perfeitamente da forma que você sugeriu, referenciando um bean pelo outro:

public String salvarRatingTeste(){
		RatingBean ratingBean = new RatingBean();
		ratingBean.setRating(registro.getRating());
		ratingBean.setStar(star);
		ratingBean.salvar();
		return "sucesso";
	}

Vou dar uma estudada agora na anotação de injeção.

Muito obrigado pela ajuda!