Erro ao salvar filho de uma classe - resolvido

17 respostas Resolvido
jpahibernatespringjava
G

Analisando passo a passo pelo debug, o objeto arquivoImagem, está preenchido.

Mapeamento pai para filho:

@NotAudited
	@OneToMany(mappedBy = "contaPagarReceber", cascade = {CascadeType.PERSIST,
			CascadeType.MERGE, CascadeType.DETACH})
	public Set<ContaPagarReceberArquivoImagemEntity> getContasPagarReceberArquivosImagens() {
		return contasPagarReceberArquivosImagens;
	}

Preeenchimento

Set<ContaPagarReceberArquivoImagemEntity> cprai = new LinkedHashSet<>();
		for (ContaPagarReceberArquivoImagemEntity arqImg : entidade.getContasPagarReceberArquivosImagens()) {
			aplicacaoAuditoria(arqImg);
			if(entidadeGravar instanceof ContaPagarEntity){
				arqImg.setContaPagarReceber((ContaPagarEntity) entidadeGravar);
			} else {
				arqImg.setContaPagarReceber((ContaReceberEntity) entidadeGravar);
			}
			arqImg.setArquivoImagem(arqImg.getArquivoImagem());
			cprai.add(arqImg);
		}
		entidadeGravar.setContasPagarReceberArquivosImagens(cprai);

Método genérico de persist

private void persist(Object objeto) throws Exception {
		EntityManager em = JPAUtility.getEntityManager();
		try {
			EntityTransaction et = em.getTransaction();
			try {
				((Session) em.getDelegate()).setDefaultReadOnly(false);
				et.begin();
				em.detach(objeto);
				em.persist(objeto);
				em.flush();
				et.commit();
			} catch (PersistenceException e) {
				trataErrosDePersistenciaAntes(em, e);
				et.rollback();
			} catch (Exception e) {
				et.rollback();
				throw new RuntimeExceptionDao(e);
			} finally {
				((Session) em.getDelegate()).setDefaultReadOnly(true);
			}
		} finally {
			em.close();
		}
	}

Erro:

08:26:42,119 WARN  [org.hibernate.action.internal.UnresolvedEntityInsertActions] (default task-16) HHH000437: Attempting to save one or more entities that have a non-nullable association with an unsaved transient entity. The unsaved transient entity must be saved in an operation prior to saving these dependent entities.
	Unsaved transient entity: ([br.eti.netsoft.erp.modelo.arquivoimagem.ArquivoImagemEntity#<null>])
	Dependent entities: ([[br.eti.netsoft.erp.modelo.financeiro.ContaPagarReceberArquivoImagemEntity#511c085f-165f-4438-a3ce-e4fe1a1d3c05]])
	Non-nullable association(s): ([br.eti.netsoft.erp.modelo.financeiro.ContaPagarReceberArquivoImagemEntity.arquivoImagem])
08:26:42,119 WARN  [org.hibernate.action.internal.UnresolvedEntityInsertActions] (default task-16) HHH000437: Attempting to save one or more entities that have a non-nullable association with an unsaved transient entity. The unsaved transient entity must be saved in an operation prior to saving these dependent entities.
	Unsaved transient entity: ([br.eti.netsoft.erp.modelo.arquivoimagem.ArquivoImagemEntity#<null>])
	Dependent entities: ([[br.eti.netsoft.erp.modelo.financeiro.ContaPagarReceberArquivoImagemEntity#151decc8-73cb-4b8b-a278-35c2bfd08902]])
	Non-nullable association(s): ([br.eti.netsoft.erp.modelo.financeiro.ContaPagarReceberArquivoImagemEntity.arquivoImagem])
08:26:42,120 ERROR [br.eti.netsoft.dao.GHDAO] (default task-16) Erro  ao gravar objeto: br.eti.netsoft.dao.exception.RuntimeExceptionDao: java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : br.eti.netsoft.erp.modelo.financeiro.ContaPagarReceberArquivoImagemEntity.arquivoImagem -> br.eti.netsoft.erp.modelo.arquivoimagem.ArquivoImagemEntity

O que pode ser este erro ?

17 Respostas

L

Como é a estratégia de obter id da classe ArquivoImagemEntity?

G

Gerado automaticamente pelo banco de dados, um GUID

L

Pelo erro, você deve está tentando salvar um valor valor inválido em uma coluna not null (provavelmente um valor nulo).

G

Nesta classe: ContaPagarReceberArquivoImagemEntity ?

D

Não, o erro se refere ao fato de:

  • Ele estár inserindo um objeto em que ao menos um atributo é um objeto e esse objeto ainda não foi persistido
  • Ele estar atualizando um objeto que tenha uma lista e ao menos um elemento desta lista é novo.
  • Ele estar adicionando um objeto que tenha uma lista e esta lista possui elementos não salvos.

Ou seja. ele precisa salvar todos os atributos do objeto ou, no caso de coleção, os elementos da coleção.
Provavelmente, o mapeamento que ele está usando não contém a propriedade CASCADE.

L

O pior eh que tem um cascade. Bom, talvez esteja configurado errado.

D

Parece que o erro se refere a outro atributo da classe em questão.

L

Como teste, coloque um Cascade.ALL, pra ver o que acontece. =)

G

Estou inserindo um objeto que tem uma lista de outros objetos, com , cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.DETACH})

G

Vou testar

G

Vou analisar e vejo se a algum campo que está null

D

Com apenas estes trechos do código fica difícil ter uma visão maior.
Ainda mais que o erro se refere a um atributo cujo getter deveria ser

getArquivoImagem()

O que é diferente do que você apresentou aí, não é mesmo?

G

Isto é uma lista de imagens para uma contas

D

Cara, posta a classe ContaPagarReceberArquivoImagemEntity completa

G
package br.eti.netsoft.erp.modelo.financeiro;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.envers.AuditOverride;
import org.hibernate.envers.Audited;
import org.hibernate.envers.RelationTargetAuditMode;

import br.eti.netsoft.erp.modelo.ErpEntity;
import br.eti.netsoft.erp.modelo.arquivoimagem.ArquivoImagemEntity;
import br.eti.netsoft.modelo.auditoria.AuditableBaseEntity;
import br.eti.netsoft.util.anotacao.ExclusaoLogica;

/**
 * @description Modelo para arquivos ou imagems para a contas pagar ou receber
 * @author GH SISTEMAS
 */
@Entity
@Table(name = "TB_CON_PAG_REC_IMG_ARQ", schema = "FINANCEIROS", indexes = {
		@Index(columnList = "ST_REGISTRO", name = "I1_CON_PAG_REC_IMG_ARQ"),
		@Index(columnList = "FK_CONTA_PAGAR_RECEBER", name = "I2_CON_PAG_REC_IMG_ARQ"),
		@Index(columnList = "FK_ARQUIVO_IMAGEM", name = "I3_CON_PAG_REC_IMG_ARQ")})
@Audited
@AuditOverride(forClass = AuditableBaseEntity.class)
@ExclusaoLogica
public class ContaPagarReceberArquivoImagemEntity extends ErpEntity {

	private static final long serialVersionUID = -7273641592040911533L;

	private ContaPagarReceberEntity contaPagarReceber;
	private ArquivoImagemEntity arquivoImagem;

	@Id
	@Override
	@Column(name = "PK_CON_PAG_REC_IMG_ARQ")
	@GeneratedValue(generator = "system-uuid")
	@GenericGenerator(name = "system-uuid", strategy = "uuid2")
	public String getId() {
		return super.getId();
	}

	@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
	@ManyToOne(targetEntity = ContaPagarReceberEntity.class)
	@JoinColumn(name = "FK_CONTA_PAGAR_RECEBER", nullable = false)
	public ContaPagarReceberEntity getContaPagarReceber() {
		return contaPagarReceber;
	}

	public void setContaPagarReceber(ContaPagarReceberEntity contaPagarReceber) {
		this.contaPagarReceber = contaPagarReceber;
	}

	@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
	@ManyToOne(targetEntity = ArquivoImagemEntity.class)
	@JoinColumn(name = "FK_ARQUIVO_IMAGEM", nullable = false)
	public ArquivoImagemEntity getArquivoImagem() {
		return arquivoImagem;
	}

	public void setArquivoImagem(ArquivoImagemEntity arquivoImagem) {
		this.arquivoImagem = arquivoImagem;
	}
}
package br.eti.netsoft.erp.modelo.financeiro;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.envers.AuditOverride;
import org.hibernate.envers.Audited;
import org.hibernate.envers.RelationTargetAuditMode;

import br.eti.netsoft.erp.modelo.ErpEntity;
import br.eti.netsoft.erp.modelo.arquivoimagem.ArquivoImagemEntity;
import br.eti.netsoft.modelo.auditoria.AuditableBaseEntity;
import br.eti.netsoft.util.anotacao.ExclusaoLogica;

/**
 * @description Modelo para arquivos ou imagems para a contas pagar ou receber
 * @author GH SISTEMAS
 */
@Entity
@Table(name = "TB_CON_PAG_REC_IMG_ARQ", schema = "FINANCEIROS", indexes = {
		@Index(columnList = "ST_REGISTRO", name = "I1_CON_PAG_REC_IMG_ARQ"),
		@Index(columnList = "FK_CONTA_PAGAR_RECEBER", name = "I2_CON_PAG_REC_IMG_ARQ"),
		@Index(columnList = "FK_ARQUIVO_IMAGEM", name = "I3_CON_PAG_REC_IMG_ARQ")})
@Audited
@AuditOverride(forClass = AuditableBaseEntity.class)
@ExclusaoLogica
public class ContaPagarReceberArquivoImagemEntity extends ErpEntity {

	private static final long serialVersionUID = -7273641592040911533L;

	private ContaPagarReceberEntity contaPagarReceber;
	private ArquivoImagemEntity arquivoImagem;

	@Id
	@Override
	@Column(name = "PK_CON_PAG_REC_IMG_ARQ")
	@GeneratedValue(generator = "system-uuid")
	@GenericGenerator(name = "system-uuid", strategy = "uuid2")
	public String getId() {
		return super.getId();
	}

	@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
	@ManyToOne(targetEntity = ContaPagarReceberEntity.class)
	@JoinColumn(name = "FK_CONTA_PAGAR_RECEBER", nullable = false)
	public ContaPagarReceberEntity getContaPagarReceber() {
		return contaPagarReceber;
	}

	public void setContaPagarReceber(ContaPagarReceberEntity contaPagarReceber) {
		this.contaPagarReceber = contaPagarReceber;
	}

	@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
	@ManyToOne(targetEntity = ArquivoImagemEntity.class)
	@JoinColumn(name = "FK_ARQUIVO_IMAGEM", nullable = false)
	public ArquivoImagemEntity getArquivoImagem() {
		return arquivoImagem;
	}

	public void setArquivoImagem(ArquivoImagemEntity arquivoImagem) {
		this.arquivoImagem = arquivoImagem;
	}
}
package br.eti.netsoft.erp.modelo.financeiro;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.envers.AuditOverride;
import org.hibernate.envers.Audited;
import org.hibernate.envers.RelationTargetAuditMode;

import br.eti.netsoft.erp.modelo.ErpEntity;
import br.eti.netsoft.erp.modelo.arquivoimagem.ArquivoImagemEntity;
import br.eti.netsoft.modelo.auditoria.AuditableBaseEntity;
import br.eti.netsoft.util.anotacao.ExclusaoLogica;

/**
 * @description Modelo para arquivos ou imagems para a contas pagar ou receber
 * @author GH SISTEMAS
 */
@Entity
@Table(name = "TB_CON_PAG_REC_IMG_ARQ", schema = "FINANCEIROS", indexes = {
		@Index(columnList = "ST_REGISTRO", name = "I1_CON_PAG_REC_IMG_ARQ"),
		@Index(columnList = "FK_CONTA_PAGAR_RECEBER", name = "I2_CON_PAG_REC_IMG_ARQ"),
		@Index(columnList = "FK_ARQUIVO_IMAGEM", name = "I3_CON_PAG_REC_IMG_ARQ")})
@Audited
@AuditOverride(forClass = AuditableBaseEntity.class)
@ExclusaoLogica
public class ContaPagarReceberArquivoImagemEntity extends ErpEntity {

	private static final long serialVersionUID = -7273641592040911533L;

	private ContaPagarReceberEntity contaPagarReceber;
	private ArquivoImagemEntity arquivoImagem;

	@Id
	@Override
	@Column(name = "PK_CON_PAG_REC_IMG_ARQ")
	@GeneratedValue(generator = "system-uuid")
	@GenericGenerator(name = "system-uuid", strategy = "uuid2")
	public String getId() {
		return super.getId();
	}

	@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
	@ManyToOne(targetEntity = ContaPagarReceberEntity.class)
	@JoinColumn(name = "FK_CONTA_PAGAR_RECEBER", nullable = false)
	public ContaPagarReceberEntity getContaPagarReceber() {
		return contaPagarReceber;
	}

	public void setContaPagarReceber(ContaPagarReceberEntity contaPagarReceber) {
		this.contaPagarReceber = contaPagarReceber;
	}

	@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
	@ManyToOne(targetEntity = ArquivoImagemEntity.class)
	@JoinColumn(name = "FK_ARQUIVO_IMAGEM", nullable = false)
	public ArquivoImagemEntity getArquivoImagem() {
		return arquivoImagem;
	}

	public void setArquivoImagem(ArquivoImagemEntity arquivoImagem) {
		this.arquivoImagem = arquivoImagem;
	}
}
D
Solucao aceita

Aqui você não tem o cascade.

P.S.: Não gosto de usar anotações nos getters, fico perdido vendo esse código amontoado.

G

É mesmo. Acho que o problema é este, correto ?

Vou testar e informo aqui.

Criado 14 de fevereiro de 2019
Ultima resposta 15 de fev. de 2019
Respostas 17
Participantes 3