2011-01-02 7 views
5

Estoy utilizando la implementación de JPA2 e Hibernate.Eliminación de la tabla con la anotación @OneToOne

Tengo mapeo simple como esto:

@Entity 
class Topic { 

    @Id 
    @GeneratedValue(strategy = IDENTITY) 

    int id; 

    @OneToOne(cascade = ALL) 
    @JoinColumn(name = "id_poll") 
    private Poll poll; 

} 

@Entity 
class Poll { 
    @Id 
    @GeneratedValue(strategy = IDENTITY) 
    int id; 
} 

Ahora, cuando se borra un objeto de la encuesta que está también en tema me da un error.

java.sql.SQLException: Integridad restricción de tabla FKCC42D924982D3F4B violación: [? Eliminar en encuestas donde id =] Temas en la declaración

entiendo que es porque no puedo borrar el registro Poll si tiene referencias en otra tabla. ¿Como puedó resolver esté problema? ¿Debo configurar manualmente poll = null en una tabla de temas o hay una mejor solución?

Respuesta

5

Se espera que esto:

Un problema común con las relaciones bidireccionales es la aplicación actualizaciones de un lado de la relación, pero la otra parte no recibe actualizan, y se convierte en fuera de sincronía. En JPA, como en Java en general es la responsabilidad de la aplicación, o el modelo de objetos para mantener relaciones .

Fuente: Object corruption, one side of the relationship is not updated after updating the other side

El lugar correcto para manejar esto es, en una devolución de llamada @PreRemove:

@Entity 
class Poll { 

    ... 

    @PreRemove 
    private void preRemove() { 
     Poll poll = topic.getPoll(); 
     topic.setPoll(null); 
    } 
} 

Ver también: Have JPA/Hibernate to replicate the “ON DELETE SET NULL” functionality

1

Parece que la anotación @OneToOne en JPA 2 contiene un indicador de huérfano Removimiento, puede intentar configurarlo y ver si lo elimina correctamente.

+1

No, he intentado esto y todavía doesn' t trabajo ... Todavía tengo el mismo error ... – Dawid

1

No he podido encontrar una solución hasta ahora, así que antes de eliminar un objeto Poll siempre obtengo un objeto Topic que contiene el Pool dado y lo configuro como nulo.

Topic topic = entityManager.find(Topic.class, 1); 
Poll poll = topic.getPoll(); 
topic.setPoll(null); 
entityManager.remove(poll); 

Y funciona correctamente.

0

El problema radica en el hecho de que está utilizando ID autogenerado en ambos lados. Cuando persiste la entidad padre, la entidad hijo también persiste, pero su ID dentro de la entidad padre no se actualiza con la generada desde la base de datos.

Como resultado, cuando elimina el elemento primario, no eliminará el elemento secundario, porque el elemento secundario no tiene ID.

Intente configurar manualmente el ID de la entidad secundaria y huérfano Remover funcionará. comportamiento

Cuestiones relacionadas