CASCADE e geraçao de chave primaria

7 respostas
renanreismartins

Pessoal, tenho uma entidade Empresa que possui uma entidade contrato, que por sua vez possui um anexo.

seguem os mapeamentos:

public class Empresa implements Serializable {
           @OneToOne(mappedBy = "empresa", cascade = CascadeType.ALL)
	private Contrato contrato;
}
public class Contrato implements Serializable {
            @OneToOne(mappedBy = "contrato", cascade = CascadeType.ALL)
	private Anexo anexo;

            @OneToOne(optional = false)
	@JoinColumn(name = "ID_EMPRESA", unique = true)
	private Empresa empresa;
}
public class Anexo implements Serializable {
            @OneToOne
	@JoinColumn(name = "ID_CONTRATO")
	private Contrato contrato;
}

como podem observar utilizo do atributo cascade = CascadeType.ALL.

quando faço

getEm().persist(empresa);
empresa.getContrato.getAnexo().getId();

a empresa é salva, logo o contrato tambem e consequentemente o anexo e é exibido o id do anexo.

porém quando executo a operação de update na empresa meu obtenho uma NullPointerException na linha que chama o id do anexo.

getEm().merge(empresa);
empresa.getContrato.getAnexo().getId(); // exceção

alguem sabe pq o comportamento nao esta sendo o mesmo para o metodo persist uma vez que utilizo CascadeType.ALL?

abrasssssssssssssssssss

7 Respostas

alanbrasil1984

como seu id de contrato ta mapeado?

renanreismartins
@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE)
	@Column(name = "ID_CONTRATO")
	private Long id;

todos usam as 3 anotacoes, mudando apenas o nome da coluna

abrasss

alanbrasil1984
@SequenceGenerator(name="NOMEUSADONO ATRIBUTO_SEQUENCE",sequenceName="NOMENOBANCO_SEQ")
@Table (name="CONTRATO")
public class Contrato implements Serializable{

	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="CONTRATO_SEQUENCE")
	@Column(name="CODIGO")
        private Long codigo;

ou Use strategy=GenerationType.AUTO

acredito que possa ser isso ele não pegar a sequence.

TiagoW

Bem, o mais óbvio seria ver se o objeto Empresa que está se fazendo o merge possui realmente um Contrato e esse Contrato possui realmente um Anexo.

Visto isso, você pode tentar o seguinte:
empresa = em.merge(empresa);

O merge não altera o objeto que foi passado por parâmetro. Ao invés disso ele cria um novo objeto com status MANAGED, copia os dados do objeto passado para ele e então devolve o novo objeto.

Outro detalhe importante é que as alterações só são propagadas para o SGBD ao fim da transação.

Quando eu comecei a estudar JPA, achava que o MERGE era para operações de UPDATE e o PERSIST para INSERT, mas na verdade não funciona assim.
Para um entity ser persistido ele têm de estar no status MANAGED, dentro do contexto de persistência. O que na prática significa que há duas instâncias em memória do mesmo entity, uma com os dados originais e outra com os dados atuais do objeto.
Dessa forma, ao fim da transação o JPA compara os dois e sabe que uma alteração foi feita, disparando então uma operação de UPDATE ou INSERT no caso dele identificar que é um objeto NEW.
Então o ID de um objeto NEW pode não estar disponível logo após o merge, e sim, apenas depois do COMMIT.

Era isso, não sou nenhum especialista em JPA mas espero ter ajudado.

alanbrasil1984

levando em consideração que o contrato não tenha anexo irá mesmo dar null pointer…

caso não tenha se der o merge ele não irá atualizar nada mais se vc der o new jogar no anexo ele persistirá…

renanreismartins

Prezados Srs, mto obrigado pela colaboração este erro estava me matando!!! vou ler a api do EntityManager novamente.

TiagoW:
Bem, o mais óbvio seria ver se o objeto Empresa que está se fazendo o merge possui realmente um Contrato e esse Contrato possui realmente um Anexo.

sim neste caso empresa sempre tem contrato e contrato tem anexo.

aqui vc matou a charada

muito obrigado mesmo!!!

alanbrasil1984 mto obrigado tb… e está pra existir um site de agencia web mais show que este na sua assinatura. PQP!!! parabens!

grande abrassss pessoal

renanreismartins

obs a documentação tb nao fala q ao chamar o metodo merge a entidade nao eh atualizada… podre… x(

abrasss

Criado 18 de agosto de 2009
Ultima resposta 18 de ago. de 2009
Respostas 7
Participantes 3