2010-08-10 12 views
5

que tienen un validador personalizado como -Validación personalizada de Grails - Consulta dentro de la verificación de validación - ¿Qué ocurre durante la actualización?

validator: { userEmail, userAccount -> 

    if (userAccount.authenticationChannel == "ABC") { 
     boolean valid = true; 
     UserAccount.withNewSession { 
     if (UserAccount.findByEmail(userEmail)){ 
     valid = false; 
     } 
     else if (UserAccount.findByName(userEmail)) { 
     valid = false; 
     } 

...

Así que, básicamente, necesito algo de validación basada en una cierta condición y en mi validación que necesito para ejecutar una consulta.

Pero, ahora si lo hago -

def admin = new UserAccount(firstname:'Admin',email:'[email protected]') 


admin.save(flush:true) 


admin.addToAuthorities("ADMIN").save(flush:true) 

Se produce un error.

Grails está ejecutando la validación, incluso en la actualización y dado que la validación del correo electrónico existe, falla. ¿Cómo es esto diferente si lo hago

email {unique:true}

Es Griales diciendo que no puedo escribir un validador personalizado que comprueba singularidad.

+0

como Olexandr declaró a continuación, un stacktrace sería muy útil. "falla" no es realmente claro. – Molske

+0

> No funciona. Si proporciona cualquier excepción o falla stacktrace, sería mucho más fácil ayudarle. – Oleksandr

Respuesta

0

Una alternativa podría ser hacer las comprobaciones en el método guardar.

def save = { 
    .. 
    if (some_checks_succeed(userEmail, userAccount)) { 
    admin.save(flush: true) 
    } 
    .. 
} 

def some_checks_succeed = { String userEmail, String userAccount -> 
    boolean valid = true; 
    if (userAccount.authenticationChannel == "ABC") { 
    UserAccount.withNewSession { 
    if (UserAccount.findByEmail(userEmail)) { 
    valid = false; 
    } else if (UserAccount.findByName(userEmail)) { 
    valid = false; 
    } 

    .. 
    } 

    return valid 
} 

Algunas modificaciones pueden ser necesarias, pero el código anterior le da un ejemplo

0

Gracias. Podría hacer que esto funcione. La llamada a admin.save() valida en insert y update. Manejé ambos casos (insertar y actualizar) y pude hacer que esto funcionara.

Gracias

6

No estoy seguro si esto es su problema o no, pero cuando traté de crear una validación como esto (es decir. Uno que lo haga consultas en la base de datos), que obtendría un StackOverflowError. La razón es que, cuando ejecuta una consulta (como findByEmail), Hibernate intentará vaciar la sesión, lo que hará que valide todos los objetos transitorios, lo que a su vez llama a su validador personalizado nuevamente, lo que da como resultado una recursión infinita.

El truco para evitar esto es establecer el modo de descarga de la sesión en "manual" durante un breve tiempo mientras se ejecutan las consultas. Esto evita que Hibernate intente eliminar la sesión antes de ejecutar las consultas. El efecto secundario es que su consulta no devolverá las entidades que creó en la sesión actual, pero que aún no se han conservado (descartado) de nuevo en la base de datos.

UserAccount.withNewSession { session -> 
    session.flushMode = FlushMode.MANUAL 
    try { 
     if (UserAccount.findByEmail(userEmail)){ 
      valid = false; 
     } 
     else if (UserAccount.findByName(userEmail)) { 
      valid = false; 
     } 
    } 
    finally { 
     session.setFlushMode(FlushMode.AUTO); 
    } 
} 

Consulte UniqueConstraint para ver un ejemplo de cómo se hace esto.

+0

Hola, ¿podría proporcionar un enlace actualizado a su ejemplo de UniqueConstraint? Ese es dar un 404 por desgracia. –

+0

Actualizado. Ya no se pudo encontrar el archivo original en github. – GreenGiant

+0

Tuvo el mismo problema que RockyJ. Deberían mencionar esto en la documentación del validador. – Zan

Cuestiones relacionadas