2011-06-01 14 views
5

usando Hibernate, me gustaría actualizar un dato en la base de datos sobre la base de condiciones, pero me dio el siguiente error: "nodo para atravesar no puede ser nulo"valor de actualización con join

Aquí está la descripción de mi base de datos:

Account: id, email, password 
Member : id, account, team 
Team: id, current (and a reference to member => members) 

Aquí es mi JPA:

UPDATE Team t SET t.current = :current LEFT JOIN t.members m WHERE t.current = :current_true AND m.account = :account 

¿Qué estoy haciendo mal? Si muevo el LEFT JOIN para antes del SET:

UPDATE Team t LEFT JOIN t.members m SET t.current = :current WHERE t.current = :current_true AND m.account = :account 

llegué: "esperando SET, encontré IZQUIERDA"

Si quito la unión:

UPDATE Team t SET t.current = :current WHERE t.current = :current_true AND t.members.account = :account 

llegué: " Intento ilegal de eliminación de la colección ".

¿Cuál es la forma correcta de actualizar los valores?

Gracias por su ayuda!

Respuesta

7

La especificación JPA 2.0 en el capítulo 4 contiene detalles de todas las funciones compatibles en JPQL. Esta es la definición de la declaración de "actualización":

La sintaxis de estas operaciones es la siguiente:

update_statement ::= update_clause [where_clause] 
update_clause ::= UPDATE entity_name [[AS] identification_variable] 
        SET update_item {, update_item}* 
    update_item ::= [identification_variable.]{state_field | single_valued_object_field} = 
        new_value 
new_value ::= 
    scalar_expression | 
    simple_entity_expression | 
    NULL 

Como se puede ver, soporte para múltiples entidades no se indica aquí. Supongo que tendrá que encontrar una forma diferente de hacerlo, tal vez crear un método que seleccione primero las entidades que desea actualizar y luego iterar sobre los resultados configurando los valores. O podría usar una actualización SQL nativa.

+1

Una actualización SQL nativo se prefirió entonces, es tonto para repetir n entrada en su base de datos para hacer la actualización cuando se puede hacerlo con una consulta! (y es extraño JPA no lo incluye ?!) –

+0

@ cx42net Aun así, no veo la necesidad de la unión en su consulta. ¿Por qué no puedes escribir la consulta sobre la entidad del Equipo sin usar el campo de miembros? Después de todo, estás utilizando una combinación izquierda, por lo que el resultado sería el mismo, ¿no es así? –

+0

El miembro se une al equipo y a la cuenta, y debo filtrar la actualización en función de las cuentas, así que supongo que debo unirme a un miembro. –

11

Usar una subconsulta:

(no probado)

UPDATE Team t SET t.current = :current 
WHERE t.id in (select t1.id from Team t1 LEFT JOIN t1.members m WHERE t1.current = :current_true AND m.account = :account) 
+0

Esto se traducirá en una subselección en sql bastante bien, y funcionará siempre que la clave no sea una clave compuesta. – KarlP

+0

Muchas gracias por su publicación. ¡Solucionó mi problema! – curious1

+0

¡Sí! esto funcionó. ¡Maldita sea! Estaba preocupado por un segundo. También esto funciona si hay una clave incrustada compuesta – mike