En mi aplicación que tienen estos tipos mapeados-Hibernate (caso general):¿Por qué Hibernate intenta eliminar cuando intento actualizar/insertar?
class RoleRule {
private Role role;
private PermissionAwareEntity entity; // hibernate-mapped entity for which permission is granted
private PermissionType permissionType; // enum
@ManyToOne
@JoinColumn(name = "ROLE_ID")
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
class Role {
private Set<RoleRule> rules = new HashSet<RoleRule>(0);
@OneToMany(cascade=CascadeType.ALL)
@JoinColumn(name="ROLE_ID")
public Set<RoleRule> getRules() {
return rules;
}
public void setRules(Set<RoleRule> rules) {
this.rules = rules;
}
}
todas las clases han equals() & hashCode()
anulaciones.
Mi aplicación permite ajustar los roles (solo con los administradores de sistemas, no se preocupe), y entre otros campos, permite la creación de nuevas reglas de roles. Cuando se crea una nueva regla, intento crear un nuevo objeto RoleRule
e insertarlo en el campo del rol rules
. Llamo al session.update(role)
para aplicar los cambios a la base de datos.
Ahora viene la parte fea ... Hibernate decide hacer lo siguiente al cierre de la transacción y rubor:
- insertar la nueva regla en la base de datos. Excelente.
- Actualice los otros campos de función (no colecciones). Hasta aquí todo bien.
- Actualice las reglas existentes, incluso si nada ha cambiado en ellas. Puedo vivir con esto.
- Actualice las reglas existentes nuevamente. Aquí está una pasta a partir del registro, incluyendo el comentario automático:
/* delete one-to-many row Role.rules */ update ROLE_RULE set ROLE_ID=null where ROLE_ID=? and ROLE_RULE_ID=?
Por supuesto, todos los campos son no-nula, y esta operación fracasa espectacularmente.
¿Alguien puede tratar de explicar por qué Hibernate haría esto? Y, lo que es más importante, ¿cómo puedo evitar esto?
EDITAR: Estaba tan seguro de que era algo que ver con la asignación, y luego mi jefe, en un capricho, elimina el equals()
y hashCode()
en ambas clases, ellos reconstruido usando Eclipse, y misteriosamente esto solucionó el problema .
Todavía tengo mucha curiosidad sobre mi pregunta. ¿Alguien puede sugerir por qué Hibernate haría esto?
¿Qué driver y dialecto estás usando? –
la aplicación se ejecuta en Oracle 10g, pero eso no debería importar. – Yuval
Lo más importante es que falta la implementación de los métodos 'equals' y' hashCode' en tu publicación. Construir sus métodos 'equals' y' hashCode' basados en valores de identidad de la base de datos ** generados por hibernación o su base de datos ** es una mala idea, haciendo que dependan de cualquier campo que pueda actualizarse después de que el tiempo de construcción sea aún peor. –