Boa tarde,
tenho uma classe que possui alguns atributos que não são exibidos na tela e que são populados somente no momento do persist ou do merge, utilizando para isso os callbacks @PrePersist e @PreUpdate do JPA.
Vamos dar nomes resumidos para ficar fácil de escrever. Portanto, minha primeira classe vou chamar de X e a outra de Y, sendo que a classe X possui, tem, agrega, contém, uma lista de Y.
Quando eu crio um novo objeto X deixando Y NULL, ou seja, sem nenhum item, o X é persistido perfeitamente inclusive com os atributos acima mencionados (os populados pela aplicação no @PrePersist) com os valores corretos!
Se eu crio um objeto X e ao mesmo tempo populo Y com um ou mais objetos e mando persistir X, tudo é feito corretamente também, pois, eu tenho a regra de CASCADE no relacionamento com Y, portanto o provedor de persistência já faz tudo automaticamente e os atributos que são incluidos pela aplicação através dos métodos @PrePersist e @PreUpdate também são corretamente gravados tanto no X como no Y (pois ambos tem esses atributos).
O problema ocorre quando eu edito o objeto X mas incluo uma nova instância de Y. Executo o merge do X e o provedor de persistência faz o resto automático. Até aqui tudo bem, funciona numa boa, porém os atributos do novo objeto Y que deveriam ser populados pela aplicação através do @PrePersist não são gravados.
Ao realizar um DEBUG da ação de editar X incluindo um Y, eu percebi algo “estranho” que vou tentar relatar abaixo:
A primeira ação que ocorre quando eu executo o merge de X é a @PrePersist do objeto Y. O método que é vinculado ao @PrePersist é executado e TODA a rotina interna é realizada PERFEITAMENTE, inclusive os atributos que deveriam ser preenchidos pela aplicação, de fato são preenchidos. Porém logo que o método @PrePersist é finalizado eu notei que o construtor da classe Y é executado e nesse momento os atributos preenchidos pela aplicação são todos NULL, sendo que os outros atributos preenchidos pelo usuário permanecem com os valores que estavam. Como você sabe? Eu sei pois após o construtor do Y ser executado, a próxima ação executada é o @PreUpdate do objeto X e nesse momento eu mando exibir o estado do objeto Y e ele está, como eu disse, com os atributos preenchidos pelo usuário ok e os atributos preenchidos pela aplicação através do @PrePersist todos NULL! Após o método @PreUpdate ser finalizado, o LOG gerado pelo provedor de persistência finaliza a gravação, ou seja, executa de fato os DMLs na seguinte sequência:
UPDATE X …
INSERT INTO Y …
E nesse caso meus atributos de Y populados pela aplicação estão todos NULL também no banco de dados (é claro!).
Alguma alma caridosa poderia me dar alguma luz? Estou até pagando por uma solução :shock:
grato.
Danilo G. Magrini