merge() e sessões
07/07/2014 15:04
0
Olá pessoal,
Estou com em uma tarefa aqui e gostaria da colaboração/avaliação de vocês:
Seguinte, tenho um serviço que gera notificações:
def generateNotification(String messagePT, String messageEN = null, String source, String sourceId, String action, ArrayList<AbstractPerson> recipients ){
Notification.withNewSession{
log.debug("gerando notificação para uma lista de destinatários: ${recipients}")
Date today = new Date()
Notification notificationPT = new Notification(message:messagePT, source:source, sourceId:sourceId, sentDate:today, action:action)
Notification notificationEN = new Notification(message:messageEN, source:source, sourceId:sourceId, sentDate:today, action:action)

/* Adiciona cada Person de recipients à Notification, de acordo com o idioma */
for(abstractPerson in recipients){
if(abstractPerson instanceof Person){
if(abstractPerson.language.name == "PORTUGUES"){
notificationPT.addToRecipients(abstractPerson)
updatePersonNotifications(abstractPerson, notificationPT)
}else if(messageEN){
notificationEN.addToRecipients(abstractPerson)
updatePersonNotifications(abstractPerson, notificationEN)
}
}else if(abstractPerson instanceof Company){
for(person in abstractPerson.person){
if(person.language.name == "PORTUGUES"){
notificationPT.addToRecipients(person)
updatePersonNotifications(person, notificationPT)
}else if(messageEN){
notificationEN.addToRecipients(person)
updatePersonNotifications(person, notificationEN)
}
}
}
}
flush:true
}
}

Para cada destinatário da notificação gerada eu atualizo sua lista de notificações não lidas:
def updatePersonNotifications(Person person, Notification notification){
Customer.withTenantId(person.tenantId) {
person = person.merge()
notification = notification.merge()
PersonNotifications personNotificationInstance = PersonNotifications.findByPerson(person)
/* Se ja temos um PersonNotifications, adicionamos a notificação a ele. Se não temos, criamos uma instância e adicionamos esta notificação */
if(personNotificationInstance){
personNotificationInstance.addToReceived(notification)
}else{
personNotificationInstance = new PersonNotifications(person:person, received:notification)
personNotificationInstance.validate()
if(personNotificationInstance.hasErrors()){
return "erro ao gerar personNotificationInstance: $personNotificationInstance.errors"
}
}
return personNotificationInstance.save(flush:true)
}

}


o código é executado sem erros, só que o comportamento esperado seria a criação de 1 notificação com X destinatários (de acordo com a lista recebida), entretanto está sendo gerada X notificações, a primeira com 1 destinatário, a segunda com 2, até a última com X destinatários (que era a única que eu gostaria que tivesse sido gerada).
Sabem me explicar por que estão sendo geradas X notificações e não apenas 1 (ja que eu dei "new" em apenas 1 Notification...)

Isso pode estar sendo gerado pelo ".merge()"? Sem ele é gerado um erro de associação entre as 2 sessões :(

obs: A classe PersonNotification é multitenant, daí a necessidade do "withTenantId" no "updatePersonNotifications()"
Tags: merge() session


0
Dyego, dá uma lida neste texto:

http://spring.io/blog/2010/07/28/gorm-gotchas-part-3/



0
Olá Henrique, obrigado pela resposta, esse material é muito bom.
Eu consegui resolver o problema removendo o return de "return personNotificationInstance.save(flush:true)" do método "updatePersonNotifications()" e adicionando um "return notification", conforme o código abaixo:
def updatePersonNotifications(Person person, Notification notification){
Customer.withTenantId(person.tenantId) {
person = person.merge()
notification = notification.merge()
PersonNotifications personNotificationInstance = PersonNotifications.findByPerson(person)
/* Se ja temos um PersonNotifications, adicionamos a notificação a ele. Se não temos, criamos uma instância e adicionamos esta notificação */
if(personNotificationInstance){
personNotificationInstance.addToReceived(notification)
}else{
personNotificationInstance = new PersonNotifications(person:person, received:notification)
personNotificationInstance.validate()
if(personNotificationInstance.hasErrors()){
return "erro ao gerar personNotificationInstance: $personNotificationInstance.errors"
}
}
personNotificationInstance.save(flush:true)
}
return notification
}


Ai no "generateNotification()" sempre que chamo o "updatePersonNotifications()" eu coloco a notificação que passo para ele como parâmetro para receber seu retorno, como abaixo:
/* Adiciona cada Person de recipients à Notification, de acordo com o idioma */	
for(abstractPerson in recipients){
if(abstractPerson instanceof Person){
if(abstractPerson.language.name == "PORTUGUES"){
notificationPT.addToRecipients(abstractPerson)
notificationPT = updatePersonNotifications(abstractPerson, notificationPT)
}else if(messageEN){
notificationEN.addToRecipients(abstractPerson)
notificationEN = updatePersonNotifications(abstractPerson, notificationEN)
}
}else if(abstractPerson instanceof Company){
for(person in abstractPerson.person){
if(person.language.name == "PORTUGUES"){
notificationPT.addToRecipients(person)
notificationPT = updatePersonNotifications(person, notificationPT)
}else if(messageEN){
notificationEN.addToRecipients(person)
notificationEN = updatePersonNotifications(person, notificationEN)
}
}
}
}

07/07/2014 18:47


0
Entretanto não consegui concluir por que não estava funcionando, por que as diversas instâncias de Notification estavam sendo geradas.
07/07/2014 18:49



Ainda não faz parte da comunidade???

Para se registrar, clique aqui.


Aprenda Groovy e Grails com a Formação itexto!

Newsletter Semana Groovy

Assinar

Envie seu link!


Livro de Grails


/dev/All

Os melhores blogs de TI (e em português) em um único lugar!

 
Creative Commons
RSS Grails Brasil é mantido por itexto Consultoria.
Em caso de problemas contacte Henrique Lobo Weissmann (Kico) por e-mail: kico@itexto.com.br
Todo o conteúdo presente neste site adota o Creative Commons como licença padrão.
Ver: 4.14.0
itexto