Faz insert e depois o update da mesmas tabelas envolvidas

12 respostas
guilhermebhte

Analisando o log

Quando mando inserir, ele faz o insert nas tabelas OK e depois faz o Update das mesmas, o que não deveria.

Hibernate: insert into tab_empresa (ts_movimentacao, ip_movimentacao, cd_login_movimentacao, tp_operacao, ts_cadastro, st_registro, nr_versao, st_situacao, ds_celular_responsavel, ds_cnpj, ds_email_empresa, ds_email_responsavel, ds_nome, ds_nome_responsavel, ds_telefone_empresa, ds_telefone_responsavel, pk_empresa) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2020-07-11 16:09:35.825 DEBUG 54316 --- [  XNIO-1 task-1] org.hibernate.SQL                        : insert into tab_empresa_marketplaces (ts_movimentacao, ip_movimentacao, cd_login_movimentacao, tp_operacao, ts_cadastro, st_registro, nr_versao, st_situacao, fk_empresa, fk_marketplaces, nr_porcentagem, pk_empresa_marketplaces) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into tab_empresa_marketplaces (ts_movimentacao, ip_movimentacao, cd_login_movimentacao, tp_operacao, ts_cadastro, st_registro, nr_versao, st_situacao, fk_empresa, fk_marketplaces, nr_porcentagem, pk_empresa_marketplaces) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2020-07-11 16:09:35.832 DEBUG 54316 --- [  XNIO-1 task-1] org.hibernate.SQL                        : insert into tab_empresa_marketplaces (ts_movimentacao, ip_movimentacao, cd_login_movimentacao, tp_operacao, ts_cadastro, st_registro, nr_versao, st_situacao, fk_empresa, fk_marketplaces, nr_porcentagem, pk_empresa_marketplaces) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into tab_empresa_marketplaces (ts_movimentacao, ip_movimentacao, cd_login_movimentacao, tp_operacao, ts_cadastro, st_registro, nr_versao, st_situacao, fk_empresa, fk_marketplaces, nr_porcentagem, pk_empresa_marketplaces) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2020-07-11 16:09:35.834 DEBUG 54316 --- [  XNIO-1 task-1] org.hibernate.SQL                        : update tab_empresa set ts_movimentacao=?, ip_movimentacao=?, cd_login_movimentacao=?, tp_operacao=?, ts_cadastro=?, st_registro=?, nr_versao=?, st_situacao=?, ds_celular_responsavel=?, ds_cnpj=?, ds_email_empresa=?, ds_email_responsavel=?, ds_nome=?, ds_nome_responsavel=?, ds_telefone_empresa=?, ds_telefone_responsavel=? where pk_empresa=? and nr_versao=?
Hibernate: update tab_empresa set ts_movimentacao=?, ip_movimentacao=?, cd_login_movimentacao=?, tp_operacao=?, ts_cadastro=?, st_registro=?, nr_versao=?, st_situacao=?, ds_celular_responsavel=?, ds_cnpj=?, ds_email_empresa=?, ds_email_responsavel=?, ds_nome=?, ds_nome_responsavel=?, ds_telefone_empresa=?, ds_telefone_responsavel=? where pk_empresa=? and nr_versao=?
2020-07-11 16:09:35.843 DEBUG 54316 --- [  XNIO-1 task-1] org.hibernate.SQL                        : update tab_empresa_marketplaces set ts_movimentacao=?, ip_movimentacao=?, cd_login_movimentacao=?, tp_operacao=?, ts_cadastro=?, st_registro=?, nr_versao=?, st_situacao=?, fk_empresa=?, fk_marketplaces=?, nr_porcentagem=? where pk_empresa_marketplaces=? and nr_versao=?
Hibernate: update tab_empresa_marketplaces set ts_movimentacao=?, ip_movimentacao=?, cd_login_movimentacao=?, tp_operacao=?, ts_cadastro=?, st_registro=?, nr_versao=?, st_situacao=?, fk_empresa=?, fk_marketplaces=?, nr_porcentagem=? where pk_empresa_marketplaces=? and nr_versao=?
2020-07-11 16:09:35.847 DEBUG 54316 --- [  XNIO-1 task-1] org.hibernate.SQL                        : update tab_empresa_marketplaces set ts_movimentacao=?, ip_movimentacao=?, cd_login_movimentacao=?, tp_operacao=?, ts_cadastro=?, st_registro=?, nr_versao=?, st_situacao=?, fk_empresa=?, fk_marketplaces=?, nr_porcentagem=? where pk_empresa_marketplaces=? and nr_versao=?
Hibernate: update tab_empresa_marketplaces set ts_movimentacao=?, ip_movimentacao=?, cd_login_movimentacao=?, tp_operacao=?, ts_cadastro=?, st_registro=?, nr_versao=?, st_situacao=?, fk_empresa=?, fk_marketplaces=?, nr_porcentagem=? where pk_empresa_marketplaces=? and nr_versao=?

Código está assim:

Empresa

package br.com.ghnetsoft.ctrmarketplacestrategy.domain.empresa;

import static lombok.AccessLevel.PROTECTED;
import static org.hibernate.annotations.CacheConcurrencyStrategy.NONSTRICT_READ_WRITE;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

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

import br.com.ghnetsoft.ctrmarketplacestrategy.domain.pai.Principal;
import br.com.ghnetsoft.ctrmarketplacestrategy.domain.pai.auditoria.AuditableBase;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

/**
 * Classe do banco de dados de empresa
 * 
 * @author Guilherme C Lopes
 */
@Entity
@Setter
@Getter
@Builder
@Table(name = "TAB_EMPRESA", uniqueConstraints = {
		@UniqueConstraint(columnNames = { "DS_CNPJ" }, name = "U1_TAB_EMPRESA") }, indexes = {
				@Index(columnList = "ST_REGISTRO", name = "I1_TAB_EMPRESA"),
				@Index(columnList = "DS_CNPJ", name = "I2_TAB_EMPRESA") })
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor(access = PROTECTED)
@Cache(usage = NONSTRICT_READ_WRITE)
@Audited
@AuditOverride(forClass = AuditableBase.class)
public class Empresa extends Principal {

	private static final long serialVersionUID = 3629606672280321002L;

	@Id
	@Column(name = "PK_EMPRESA", updatable = false, unique = true, nullable = false)
	@GeneratedValue(generator = "UUID")
	@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
	private String id;
	@Column(name = "DS_NOME", nullable = false)
	private String nome;
	@Column(name = "DS_CNPJ", length = 14, nullable = false)
	private String cnpj;
	@Column(name = "DS_TELEFONE_EMPRESA", length = 10)
	private String telefoneEmpresa;
	@Column(name = "DS_EMAIL_EMPRESA", nullable = false)
	private String emailEmpresa;
	@Column(name = "DS_NOME_RESPONSAVEL", nullable = false)
	private String nomeResponsavel;
	@Column(name = "DS_TELEFONE_RESPONSAVEL", length = 10)
	private String telefoneResponsavel;
	@Column(name = "DS_CELULAR_RESPONSAVEL", length = 11)
	private String celularResponsavel;
	@Column(name = "DS_EMAIL_RESPONSAVEL", nullable = false)
	private String emailResponsavel;
}

EmpresaMarketPlaces

package br.com.ghnetsoft.ctrmarketplacestrategy.domain.empresamarketplaces;

import static lombok.AccessLevel.PROTECTED;
import static org.hibernate.annotations.CacheConcurrencyStrategy.NONSTRICT_READ_WRITE;
import static org.hibernate.envers.RelationTargetAuditMode.NOT_AUDITED;

import java.math.BigDecimal;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.ForeignKey;
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 javax.persistence.UniqueConstraint;

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

import br.com.ghnetsoft.ctrmarketplacestrategy.domain.empresa.Empresa;
import br.com.ghnetsoft.ctrmarketplacestrategy.domain.marketplaces.MarketPlaces;
import br.com.ghnetsoft.ctrmarketplacestrategy.domain.pai.Principal;
import br.com.ghnetsoft.ctrmarketplacestrategy.domain.pai.auditoria.AuditableBase;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

/**
 * Classe do banco de dados de Market Places por empresa
 * 
 * @author Guilherme C Lopes
 */
@Entity
@Setter
@Getter
@Builder
@Table(name = "TAB_EMPRESA_MARKETPLACES", uniqueConstraints = { @UniqueConstraint(columnNames = { "FK_EMPRESA",
		"FK_MARKETPLACES" }, name = "U1_TAB_MARKETPLACES_EMPRESA") }, indexes = {
				@Index(columnList = "ST_REGISTRO", name = "I1_TAB_MARKETPLACES_EMPRESA"),
				@Index(columnList = "FK_EMPRESA", name = "I2_TAB_MARKETPLACES_EMPRESA"),
				@Index(columnList = "FK_MARKETPLACES", name = "I3_TAB_MARKETPLACES_EMPRESA") })
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor(access = PROTECTED)
@Cache(usage = NONSTRICT_READ_WRITE)
@Audited
@AuditOverride(forClass = AuditableBase.class)
public class EmpresaMarketPlaces extends Principal {

	private static final long serialVersionUID = -4423665309182124888L;

	@Id
	@Column(name = "PK_EMPRESA_MARKETPLACES", updatable = false, unique = true, nullable = false)
	@GeneratedValue(generator = "UUID")
	@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
	private String id;
	@Audited(targetAuditMode = NOT_AUDITED)
	@ManyToOne(targetEntity = Empresa.class)
	@JoinColumn(name = "FK_EMPRESA", nullable = false, foreignKey = @ForeignKey(name = "FK_EMPRESA"))
	private Empresa empresa;
	@Audited(targetAuditMode = NOT_AUDITED)
	@ManyToOne(targetEntity = MarketPlaces.class)
	@JoinColumn(name = "FK_MARKETPLACES", nullable = false, foreignKey = @ForeignKey(name = "FK_MARKETPLACES"))
	private MarketPlaces marketPlaces;
	@Column(name = "NR_PORCENTAGEM", nullable = false, length = 25, precision = 2)
	private BigDecimal porcentagem;
}

Salvar está salvando empresa e depois EmpresaMarketPlaces, dentro do serviço de Empresa assim:

/**
	 * Metodo que salva uma Empresa
	 * 
	 * @param empresa
	 * @param empresasMarketsPlacesIncluir
	 * @param empresasMarketsPlacesExcluir
	 * @return
	 */
	private EmpresaDTO salvar(Empresa empresa,
			Collection<EmpresaMarketPlacesIncluirAlterarDTO> empresasMarketsPlacesIncluir,
			Collection<EmpresaMarketPlacesIncluirAlterarDTO> empresasMarketsPlacesExcluir) {
		log.info("Metodo que salva uma Empresa");
		aplicacaoAuditoria(empresa);
		empresa = repository.save(empresa);
		Collection<EmpresaMarketPlaces> empresasMarketsPlaces = empresaMarketPlacesService
				.incluirPorEmpresa(empresasMarketsPlacesIncluir, empresa);
		return new EmpresaDTO(empresa, empresasMarketsPlaces);
	}

Pois no log, nunca tem um INSERT

O que pode ser ?

12 Respostas

staroski

Esse repository é uma instância de EntityManager?
Caso afirmativo, utilize o método persist ao invés de save.

guilhermebhte
@Repository
interface EmpresaRepository extends JpaRepository<Empresa, String> {
Lucas_Camara

O que o método incluirPorEmpresa faz? Manda o código dele.

guilhermebhte
@Transactional
	@Override
	public Collection<EmpresaMarketPlaces> incluirPorEmpresa(
			Collection<EmpresaMarketPlacesIncluirAlterarDTO> empresasMarketsPlacesIncluir, Empresa empresa) {
		log.info("Metodo que inclui EmpresaMarketPlaces pelo formulario de empresa");
		Collection<EmpresaMarketPlaces> empresasMarketsPlaces = new ArrayList<>();
		if (empresasMarketsPlacesIncluir != null && !empresasMarketsPlacesIncluir.isEmpty()) {
			for (EmpresaMarketPlacesIncluirAlterarDTO emp : empresasMarketsPlacesIncluir) {
				log.info("MarketPlaces com id: " + emp.getIdMarketPlaces());
				EmpresaMarketPlaces empresaMarketPlaces = EmpresaMarketPlaces.builder().build();
				empresaMarketPlacesPreencher.preencherPorEmpresa(empresaMarketPlaces, emp.getIdMarketPlaces(),
						emp.getPorcentagem(), empresa);
				aplicacaoAuditoria(empresaMarketPlaces);
				empresasMarketsPlaces.add(empresaMarketPlaces);
			}
			empresasMarketsPlaces = repository.saveAll(empresasMarketsPlaces);
		}
		return empresasMarketsPlaces;
	}
Lucas_Camara

Para testes, comente o @Audited e veja se esse update ainda é executado?

guilhermebhte

E entidades normais que não tenho outra envolvida, ele cadastra normal.

Tenho esta classe também

package br.com.ghnetsoft.ctrmarketplacestrategy.domain.pai.auditoria;

import static br.com.ghnetsoft.ctrmarketplacestrategy.enuns.OperacacoBancoLogEnum.ALTERACAO;
import static br.com.ghnetsoft.ctrmarketplacestrategy.enuns.OperacacoBancoLogEnum.INCLUSAO;
import static lombok.AccessLevel.PROTECTED;

import java.util.Date;

import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.apachecommons.CommonsLog;

/**
 * Classe de Auditoria de banco de dados
 * 
 * @author Guilherme C Lopes
 */
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor(access = PROTECTED)
@CommonsLog
class Auditor {

	private AuditMetadata auditData = new AuditMetadata();

	/**
	 * Audita a inclusao
	 * 
	 * @param entidade
	 */
	@PrePersist
	public void auditaInclusao(AuditableBase entidade) {
		auditData.setTipoOperacao(INCLUSAO);
		audita(entidade);
	}

	/**
	 * Audita a alteracao
	 * 
	 * @param entidade
	 */
	@PreUpdate
	public void auditaAlteracao(AuditableBase entidade) {
		auditData.setTipoOperacao(ALTERACAO);
		audita(entidade);
	}

	/**
	 * Preenche a aufitoria da entidade para salvar
	 * 
	 * @param entidade
	 */
	private void audita(AuditableBase entidade) {
		auditData.setDataHoraMovimentacao(new Date());
		auditData.setIpMovimentacao(entidade.getMetadadoAuditoria().getIpMovimentacao());
		auditData.setLoginMovimentacao(entidade.getMetadadoAuditoria().getLoginMovimentacao());
		log.info(getClass().getName() + ": " + entidade.getClass().getName());
		entidade.setMetadadoAuditoria(auditData);
	}
}

Eu acho que a questão é o save em uma transação somente. porque neste caso ele exeuta o método auditaInclusao e auditaAlteracao.

Se eu tenho uma classe que quando salvo só uma, na inserção ela não executa auditaAlteracao.

guilhermebhte

Alguma novidade ?

guilhermebhte

Alguma novidade ?

javaflex

Faz o insert/update sob seu controle com jdbctemplate. Além de ser mais leve, não vai ficar uma semana lidando com esses e outros enigmas do jpa/hibernate.

Outra coisa só como dica, em empresas sérias difícilmente é aceito o sistema auditar a si mesmo. Ideal é ser por trigger em um schema com acesso mais restrito. Claro que se nao for algo crítico, pode fazer de qualquer forma.

guilhermebhte

Colocar logs em outro schema até acho melhor. E vou fazer isso. Boa idéia.

O envers já faz o papel do envers. Acho que já ouvi algo aqui sobre isso. Já trabalhei projetos em empresas grandes que utilizam o envers para isso, mas realmente em schema diferentes.

javaflex

Se esse “envers” for da própria aplicação o programador pode burlar a auditoria.

guilhermebhte

Entendi o que vc quis dizer

Criado 11 de julho de 2020
Ultima resposta 20 de jul. de 2020
Respostas 12
Participantes 4