2012-03-23 4 views
2

У меня возникла проблема при удалении записи, на которую ссылается другая таблица.JPA cascade remove

Это пример кода (простейший вариант):

@Entity 
@Table(name = "user") 
public class User 
{ 
    @Id 
    @GeneratedValue(generator="user_id_seq", strategy = GenerationType.SEQUENCE) 
    @SequenceGenerator(name="user_id_seq", sequenceName="user_id_seq") 
    @Column(name = "id", nullable = false) 
    private int id; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "user") 
    private Set<UserLog> userLogSet; 

    // Other attributes 
    // Getters/setters 
} 

@Entity 
@Table(name = "user_log") 
public class UserLog 
{ 
    @Id 
    @GeneratedValue(generator="user_log_id_seq", strategy = GenerationType.SEQUENCE) 
    @SequenceGenerator(name="user_log_id_seq", sequenceName="user_log_id_seq") 
    @Column(name = "id", nullable = false) 
    private int id; 

    @ManyToOne(cascade = CascadeType.ALL) 
    @JoinColumn(name = "user_id", nullable = false) 
    private User user; 

    // Other attributes 
    // Getters/setters 
} 

Всякий раз, когда я пытаюсь удалить запись из таблицы «пользователь», я получаю следующее сообщение об ошибке от PostGreSQL:

ERROR: update or delete on table "user" violates foreign key constraint "fk228a019fd2495d20" on table "user_log"
Detail: Key (id)=(5) is still referenced from table "user_log".

Что я делаю неправильно?

Спасибо!

Обновление: Я пробовал кодирование небольшого примера, его можно найти here. После запуска приложения с Tomcat автоматически создается схема базы данных (проверьте сведения о соединении в /src/main/webapp/WEB-INF/jdbc.properties). Когда вы посещаете http://localhost:8080, некоторые данные вставляются в базу данных. Если я попытаюсь удалить любой teacher, который указан в таблице student (с использованием phpPgAdmin), я получаю ошибку, аналогичную приведенной выше.

ответ

1

Ваше картирование кажется неправильным.

У пользователя может быть много UserLogs, я думаю.

Также @OneToMany должен быть в коллекции, например. java.util.Set. Каскад, который вы положили, находится в UserLog, который будет иметь место, если вы действуете на экземпляр UserLog, а не User.

Насколько я понимаю, картография изменений выглядит следующим образом.

@Entity 
@Table(name = "user") 
public class User 
{ 
    @Id 
    @GeneratedValue(generator="user_id_seq", strategy = GenerationType.SEQUENCE) 
    @SequenceGenerator(name="user_id_seq", sequenceName="user_id_seq") 
    @Column(name = "id", nullable = false) 
    private int id; 

    @OneToMany(cascade = CascadeType.ALL,mappedBy="user") 
    private Set<UserLog> userLogs; 

    // Other attributes 
    // Getters/setters 
} 


@Entity 
@Table(name = "user_log") 
public class UserLog 
{ 
    @Id 
    @GeneratedValue(generator="user_log_id_seq", strategy = GenerationType.SEQUENCE) 
    @SequenceGenerator(name="user_log_id_seq", sequenceName="user_log_id_seq") 
    @Column(name = "id", nullable = false) 
    private int id; 

    @ManyToOne 
    @JoinColumn(name = "user_id", nullable = false) 
    private User user; 

    // Other attributes 
    // Getters/setters 
} 

Я думаю, вы хотите удалить пользователя и все его UserLog, просто удалив пользователя и оставив UserLogs, не имеет смысла.

Надеюсь, это поможет.

Update:

Cascades as annotated in entity classes are managed by ORM, not if you externally try to delete them from external tools like phpPgAdmin.

+0

Спасибо, @ gbagga - см. мой комментарий в вопросе madth3, я просто запутался, разместив здесь пример. Теперь дело в том, что мне не нужно 'Set' в классе' User', это обязательно? В любом случае, чтобы избежать этого? – satoshi

+0

@satoshi его необязательно использовать Set, его в основном используется, чтобы дубликаты объектов не попадали в коллекцию с объектами. В случае, если вам интересно, посмотрите @ hibernate [docs] (http://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/collections.html) –

+0

Спасибо, @gbagga. К сожалению, я сталкиваюсь с той же проблемой даже с вашим решением. Должен ли JPA/Hibernate создавать индексы в PostgreSQL? Или все каскадные действия управляются ORM? Спасибо. – satoshi

0

Ваше несоответствие неверно, OneToMany должно быть в User применяется к коллекции UserLog. См. examples.

+0

К сожалению, вы правы. В коде, над которым я работаю, я использую 'ManyToOne', я просто запутался, разместив здесь пример. (отредактировал исходный вопрос) – satoshi

Смежные вопросы