Pergunta

Eu corri para algumas perguntas semelhantes sobre StackOverflow, tentou as soluções, mas não encontrou uma resposta.

Eu estou usando uma estratégia JPA bastante comum para definir vezes modificado pela última vez em algumas entidades. Configurar as colunas e os campos, em seguida, marcar um método com @PreUpdate e deixá-lo colocá-las igual ao tempo atual.

O problema é que eu posso ver no depurador que o método está sendo chamado e que o campo está sendo atualizado, porém no meu DB registra eu só vejo uma chamada SQL para atualizar o campo alterado isso não inclui uma atualização para o campo timestamp.

Para complicar ainda mais as coisas @PrePersist funciona perfeitamente, exibits única @PreUpdate esse comportamento.

A explicação mais próximo que eu encontrei até agora é neste link .

perguntas semelhantes em: # 1725699 e # 1745890

Eu estou usando EclipseLink v2 e JPA v1 para compatibilidade com v2 GlassFish.

I têm tentado usando ambas as anotações directamente sobre os métodos da classe Entidade, bem como um EntityListener ligado à classe Entidade com a anotação @EntityListener.

Eu suspeito que isso é um erro no EclipseLink, mas eu não posso provar.

Bug ou não, eu gostaria muito esta operação simples de trabalho. Há algo de errado com essa implementação? É este um problema conhecido no EclipseLink? É este um problema conhecido no JPA? Existe uma maneira de contornar isso?

curta de ir para o banco de dados e usando gatilhos, existe um caminho alternativo para deixar meu código Java definir o timestamp updated_on?

Obrigado pelo conselho!

Código trechos acompanhamento.

campos de entidade:

@Column(name = "updated_on")
@Temporal(TemporalType.TIMESTAMP)
private Date updatedOn;
@Column(name = "created_on")
@Temporal(TemporalType.TIMESTAMP)
private Date createdOn;

métodos de atualização anotados:

@PreUpdate
public void setUpdatedOn(Timestamped object) {
    object.setUpdatedOn(new Date());
}

@PrePersist
public void setCreatedOn(Timestamped object) {
    if (object.getCreatedOn()==null) {
      object.setCreatedOn(new Date());
    }
}
Foi útil?

Solução

O link que você fornecer descreve exatamente sua situação: para a verificação sujo, campos atualizados são detectados antes que o método @PreUpdate é chamado e mudanças no método @PreUpdate não são detectados mais. Isso provavelmente é feito por razões de desempenho porque cheques sujos podem ser muito caros em grandes gráficos de objeto. Parece agora suas opções são para usar um mecanismo específico do provedor (DescriptorEvent) ou para mudar para o Hibernate.

Outras dicas

mybe um pouco tarde, mas para a integridade das informações este não é um bug, mas um comportamento documentado:

data ou calendário tipos são assumidos não para ser mutável por padrão, se se deseja chamar os métodos set sobre a data ou calendário, em seguida, o mapeamento deve ser definido para ser @Mutable.

Para os tipos de data e calendário da propriedade de persistência global "eclipselink.temporal.mutable" também pode ser definido como "true".

Assim, ou anotar

@Mutable
@Column(name = "updated_on")
@Temporal(TemporalType.TIMESTAMP)
private Date updatedOn;

ou definir

<property name="eclipselink.temporal.mutable" value="true" />

em persistence.xml

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top