Boa Tarde.
Gostaria de saber se é possível salvar ou da um merge em um Objeto no hibernate, onde uma coluna na minha tabela é chave estrangeira, mas esta é opcional, logo o usuario não precisa preencher. Nos meus testes o hibernate salva e faz merge se estes campos estão preenchidos, mas se algum destes campo está vazio ele acusa o seguinte erro:
16:28:13,338 INFO [STDOUT] 16:28:13,338 ERROR [GenericDao] [SalvaPojo] object references an unsaved transient instance - save the transient instance before flushing: brd.sinfam.entidade.NotificacaoAmbiental
Vale lembrar que o objeto está com o construtor default, logo vazio, se eu seto o mesmo como null ele salva e faz merge, mas se o usuario atualiza esse campo nulo e adiciona um valor que existe na tabela, ele nao faz o merge.
package brd.sinfam.entidade;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@NamedQueries({
@NamedQuery(name="buscaPorNumeroAIA", query="SELECT A FROM AutoInfracaoAmbiental A WHERE A.autoInfracaoAmbientalNumero = :numero")
})
@Entity
@Table(name="auto_infracao")
@SequenceGenerator(name="seq_auto_infracao", sequenceName="seq_auto_infracao")
public class AutoInfracaoAmbiental implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(generator="seq_auto_infracao")
@Column(name="autin_codigo", nullable=false)
private Integer autoInfracaoAmbientalCodigo;
@OneToOne(fetch=FetchType.EAGER)
@JoinColumn(name="docto_codigo")
private Documento autoInfracaoAmbientalDocumento;
@Column(name="autin_numero", nullable=false)
private Integer autoInfracaoAmbientalNumero;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="autin_autuado", nullable=false)
private Pessoa autoInfracaoAmbientalAutuado;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="end_codigo", nullable=false)
private Endereco autoInfracaoAmbientalEndereco;
@Temporal(TemporalType.DATE)
@Column(name="autin_data_infracao", nullable=false)
private Date autoInfracaoAmbientalDataInfracao;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="cafis_codigo", nullable=false)
private CategoriaFiscalizacao autoInfracaoAmbientalCategoriaFiscalizacao;
@Column(name="autin_indicativo_multa_inicial", nullable=false, precision=2)
private BigDecimal autoInfracaoAmbientalMultaInicial;
@Column(name="autin_indicativo_multa_final", nullable=false, precision=2)
private BigDecimal autoInfracaoAmbientalMultaFinal;
@Column(name="autin_descricao", nullable=false)
private String autoInfracaoAmbientalDescricao;
@ManyToOne(fetch=FetchType.EAGER, optional=true)
@JoinColumn(name="notam_codigo", nullable=true)
private NotificacaoAmbiental autoInfracaoAmbientalNotificacaoAmbiental;
@Column(name="autin_aia_codigo")
private Integer autoInfracaoAmbientalCodigoNNA;
@Temporal(TemporalType.DATE)
@Column(name="autin_data_recebimento", nullable=false)
private Date autoInfracaoAmbientalDataRecebimento;
@OneToOne(fetch=FetchType.EAGER, optional=true)
@JoinColumn(name="autin_subtituido_por", referencedColumnName="autin_codigo", nullable=true)
private AutoInfracaoAmbiental autoInfracaoAmbientalSubstituicao;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="autin_autuado_preposto", nullable=false)
private Pessoa autoInfracaoAmbientalAutuadoPreposto;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="autin_testemunha1", nullable=false)
private Pessoa autoInfracaoAmbientalTestemunha1;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="autin_testemunha2", nullable=false)
private Pessoa autoInfracaoAmbientalTestemunha2;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="autin_agente_fiscal", nullable=false)
private Pessoa autoInfracaoAmbientalAgenteFiscal;
@OneToOne(fetch=FetchType.EAGER)
@JoinColumn(name="procf_codigo", nullable=true)
private ProcessoFiscalizacao autoInfracaoAmbientalProcessoFiscalizacao;
@Column(name="autin_observacao")
private String autoInfracaoAmbientalObservacao;
@ManyToMany(fetch=FetchType.EAGER,cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE})
@JoinTable(name="documento_enquadramento",
joinColumns={@JoinColumn(name="docto_codigo", nullable=false, referencedColumnName="docto_codigo")},
inverseJoinColumns={@JoinColumn(name="enqua_codigo", nullable=false)})
private List<Enquadramento> autoInfracaoAmbientalEnquadramentos;
public AutoInfracaoAmbiental() {
autoInfracaoAmbientalDocumento = new Documento();
autoInfracaoAmbientalAutuado = new Pessoa();
autoInfracaoAmbientalEndereco = new Endereco();
autoInfracaoAmbientalCategoriaFiscalizacao = new CategoriaFiscalizacao();
autoInfracaoAmbientalNotificacaoAmbiental = new NotificacaoAmbiental();
autoInfracaoAmbientalAutuadoPreposto = new Pessoa();
autoInfracaoAmbientalTestemunha1 = new Pessoa();
autoInfracaoAmbientalTestemunha2 = new Pessoa();
autoInfracaoAmbientalAgenteFiscal = new Pessoa();
autoInfracaoAmbientalProcessoFiscalizacao = new ProcessoFiscalizacao();
autoInfracaoAmbientalEnquadramentos = new ArrayList<Enquadramento>();
}