Hibernate - transient instance

6 respostas
C
Buenas. Tenho uma classe Chamado que tem um mini histórico de chamados, feito pela classe Historico. Segue os mapeamentos: Chamado:
@OneToMany(mappedBy = "chamadoReferente")
	private List<Historico> historicoChamado;
Historico:
@ManyToOne
	@JoinColumn(name = "cod_chamado")
	private Chamado chamadoReferente;
Tenho um xhtml que lista chamados, onde nesse tem um botão: historico, que manda pra outra xhtml. codigo:
<p:commandButton ajax="false" action="#{chamadoBean.abrirHistorico}" value="Historico" >
						<f:setPropertyActionListener target="#{chamadoBean.chamado}" value="#{chamado}" />
						</p:commandButton>
bean (abrirChamado)
public String abrirHistorico() {
		return "historico";
	}
Quando eu vou salvar um historico, aparece o erro:
GRAVE: Servlet.service() for servlet [Faces Servlet] in context with path [/webchamado] threw exception [javax.servlet.ServletException: object references an unsaved transient instance - save the transient instance before flushing: webchamado.chamado.Chamado] with root cause
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: webchamado.chamado.Chamado
bean de salvar historico:
public void salvarHistorico() {
		ContextoBean cb = new ContextoBean(); //pra pegar o usuario que está logado
		this.historico.setDataHistorico(Calendar.getInstance());
		this.historico.setUsuarioEscreveu(cb.getUsuarioLogado().getNome());
		this.historico.setChamadoReferente(this.chamado);
		HistoricoRN histRN = new HistoricoRN();
		histRN.salvar(this.historico);
		this.listaHistorico = null;
		this.historico = new Historico();

	}

pelo q eu entendi, quando eu chamo o historico o chamado fica carregado pelo hibernate
já tentei dar cascade all, mas ae ele salva com um codigo de chamado novo e cria um novo chamado, lol
hj tá brabo... erro erro erro... e o tcc é em dezembro :/

6 Respostas

G

O que parece ser seu problema é que o Chamado não está acoplado a sessão do Hibernate. O que pode ser é que você deixou ele na HttpSession e fechou a Session do hibernate. Na hora que você vai salvar o histórico, ele reclama que o this.chamado que você está usando não faz mais parte da sessão.

C

Ou ele acha que eu tenho que salvar o chamado junto ?
Se alguém puder me ajudar eu agradeço, estou pensando em desistir de implementar o histórico no sistema já…

Os passos pra chegar no histórico são:

Usuario loga no sistema;

Usuario clica para ver os chamados;

Usuario clica em HISTORICO em algum chamado (botão no panel, dento de um datagrid);

Sistema redireciona para a página de histórico, carregando o chamado na parte superior, no meio fica um datagrid com cada historico referente ao chamado, e em baixo fica um form pra ele adicionar outro histórico;

O Historico nada mais é que uma atualização do chamado, tipo (entrei em contato com o cliente blablabla) escrita pelo proprio usuario, o sistema pega a data e posta, como se fosse um post simples;

Quando vou salvar o historico, eu  queria na verdade o chamado pra pegar o codigo do chamado

É ai que entra o erro!

HELP!

D

O chamado ao qual o histórico está referenciado não está salvo na sessão.
Mapeie na anotação de Chamado em histórico utilize Cascade.All para o cascadetype, ou salve antes o histório na sessão.

C

se eu ponho cascade all ele cria um novo chamado e salva lá :frowning:

alguem ajuda please!

C

eu acho q sei oq está acontecendo.
coloquei um System.out no metodo do Bean que salva o historico pra ver se ele está pegando o chamado, e voltou null!

oq será que estou fazendo errado ? vou colocar os codigos

abertos.xhtml (aqui lista os chamados)
...

<ui:composition template="/templates/interna.xhtml">
	<ui:define name="titulo">
	    Meus Chamados
	</ui:define>
	<ui:define name="corpo">
		<h:form>
			<p:dataGrid value="#{chamadoBean.listaChamadosUsuarioAbriu}"
				var="chamado" columns="1" effect="true" styleClass="painel"
				style="border:1" paginator="true" rows="5">
				<p:column>
					<p:panel styleClass="painel">
						<f:facet name="header">
							<h:graphicImage library="imagens"
								name="fechado_#{chamado.fechado}.png" />
							<p:spacer height="0" width="10"></p:spacer>
							<h:outputText value="#{chamado.tipoChamado}"
								style="vertical-align: 8px" />
						</f:facet> 
						Para: <b> <h:outputText
								value="#{chamado.usuarioRecebeuChamado.nome}" /> </b>
						em 
						<h:outputText value="#{chamado.dataAberturaChamado.time}">
							<f:convertDateTime timeZone="BRT" pattern="dd/MM/yyyy - HH:mm" />
						</h:outputText>
						<br />

						<p:separator />
						Descrição:<br />
						<h:outputText value="#{chamado.descricao}" escape="false" />
						<p:separator />
//botao que abre o historico do chamado
						<p:commandButton ajax="false"
							action="#{chamadoBean.abrirHistorico}" value="Historico">
							<f:setPropertyActionListener target="#{chamadoBean.chamado}"
								value="#{chamado}" />
						</p:commandButton>
					</p:panel>
				</p:column>
			</p:dataGrid>
		</h:form>
	</ui:define>
</ui:composition>
</html>

historico.xhtml (aqui ele mostra o chamado, mostra um datagrid com os historicos, e depois um editor pra adicionar outro comentário)

...

<ui:composition template="/templates/interna.xhtml">
	<ui:define name="titulo">
	    Histórico
	</ui:define>
	<ui:define name="corpo">
		<h:form id="descricao">
			<p:panel styleClass="painel">
				<f:facet name="header">
					<h:graphicImage library="imagens"
						name="fechado_#{chamadoBean.chamado.fechado}.png" />
					<p:spacer height="0" width="10"></p:spacer>
					<h:outputText value="#{chamadoBean.chamado.tipoChamado}"
						style="vertical-align: 8px" />
				</f:facet> 
						Para: <b> <h:outputText
						value="#{chamadoBean.chamado.usuarioRecebeuChamado.nome}" /> </b>
						em 
						<h:outputText
					value="#{chamadoBean.chamado.dataAberturaChamado.time}">
					<f:convertDateTime timeZone="BRT" pattern="dd/MM/yyyy - HH:mm" />
				</h:outputText>
				<br />

				<p:separator />
						Descrição:<br />
				<h:outputText value="#{chamadoBean.chamado.descricao}"
					escape="false" />
				
			</p:panel>
			<br />
		</h:form>
		<h:form id="historico">
			<p:dataGrid value="#{chamadoBean.listaHistorico}" var="historico"
				columns="1" effect="true" styleClass="painel" style="border:1"
				rendered="true">
				<p:column>
					<p:panel styleClass="painel">
						<f:facet name="header">
						Escrito por: <h:outputText value="#{historico.usuarioEscreveu}" />
						</f:facet>
						<h:outputText value="#{historico.descricao}"
							style="vertical-align: 8px" />
					</p:panel>
				</p:column>
			</p:dataGrid>
		</h:form>
		Responder:
		<h:form id="novohist">
			<p:editor value="#{chamadoBean.historico.descricao}" />
			<p:commandButton action="#{chamadoBean.salvarHistorico}"
				value="Salvar" immediate="true">
			</p:commandButton>
			
		</h:form>
	</ui:define>
</ui:composition>
</html>
ChamadoBean (vou tirar oq nao precisa)
imports...
@ManagedBean(name = "chamadoBean")
@RequestScoped
public class ChamadoBean {
	public Chamado chamado = new Chamado();
	public Historico historico = new Historico();

	private List<String> tipoChamado;
	private List<Chamado> listaChamadosUsuarioAbriu;
	private List<Chamado> listaChamadosUsuarioRecebeu;
	private List<Historico> listaHistorico;
	private Integer chamadosQueAbriuEmAberto;

	public String salvar() {
		ContextoBean cb = new ContextoBean();
		this.chamado.setUsuarioAbriuChamado(cb.getUsuarioLogado());
		this.chamado.setDataAberturaChamado(Calendar.getInstance());
		ChamadoRN chaRN = new ChamadoRN();
		chaRN.salvar(this.chamado);
		this.chamado = new Chamado();
		return "abertos";
	}

//metodo que redireciona pra historico.xhml 
	public String abrirHistorico() {
		return "historico";
	}

	// lista chamados q o usuario recebeu
	public List<Chamado> getListaChamadosUsuarioRecebeu() {
		ContextoBean cb = new ContextoBean();
		ChamadoRN chaRN = new ChamadoRN();
		this.listaChamadosUsuarioRecebeu = chaRN.listarPorUsuarioRecebeu(cb
				.getUsuarioLogado().getCodigo());
		return listaChamadosUsuarioRecebeu;
	}

	// lista chamados q o usuario abriu
	public List<Chamado> getListaChamadosUsuarioAbriu() {
		ContextoBean cb = new ContextoBean();
		ChamadoRN chaRN = new ChamadoRN();
		this.listaChamadosUsuarioAbriu = chaRN.listarPorUsuarioAbriu(cb
				.getUsuarioLogado().getCodigo());
		return listaChamadosUsuarioAbriu;
	}

	// salva o historico (ajax)
	public void salvarHistorico() {
		ContextoBean cb = new ContextoBean();
		this.historico.setDataHistorico(Calendar.getInstance());
		this.historico.setUsuarioEscreveu(cb.getUsuarioLogado().getNome());
		System.out.println(chamado.getDescricao()); //AQUI RETORNA NULL!!!!!!!!!!
		this.historico.setChamadoReferente(chamado);
		HistoricoRN histRN = new HistoricoRN();
		histRN.salvar(this.historico);
		this.listaHistorico = null;
		this.historico = new Historico();

	}

	public List<Historico> getListaHistorico() {
		if (this.listaHistorico == null) {
			HistoricoRN histRN = new HistoricoRN();
			this.listaHistorico = histRN.listarPorChamado(this.chamado
					.getCodChamado());
		}
		return listaHistorico;
	}
...

}
C

upa lelê;

Criado 25 de outubro de 2011
Ultima resposta 26 de out. de 2011
Respostas 6
Participantes 3