Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Проблема с Hibernate @ManyToMany Cascade


Автор: Lonkly 3.9.2010, 23:25
Доброго времени суток, товарищи =) Помогите разрешить проблему с Hibernate?) Или со структурой так сказать...?



Есть сущность User, у которой есть таблица, содержащая сущность User_Friends, в которой 2 ссылки на пользователя. 

Код

@ManyToMany(cascade = CascadeType.ALL, targetEntity = UserFriends.class)
    private Set<UserFriends> friends = new HashSet<UserFriends>();


Код

@Entity
@Table(name = "USER_FRIENDS")
public class UserFriends implements Serializable {

    private static final long serialVersionUID = -8267560794720819507L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "USER_FRIENDS_ID", nullable = true)
    private Long id;

    @ManyToOne()
    @JoinColumn(name = "USER_ID1", referencedColumnName = "USER_ID")
    private User user1;

    @ManyToOne()
    @JoinColumn(name = "USER_ID2", referencedColumnName = "USER_ID")
    private User user2;


Удаляю пользователя из друзей таким образом. 
Код

    @SuppressWarnings("unchecked")
    @Override
    public void removeFriend(User user, Long friendId) throws Exception {
        Long userId = user.getId();
        List<UserFriends> resultList = hibernateTemplate
                .find("from UserFriends as friends where friends.user1.id='"
                        + userId + "' or friends.user2.id='" + userId
                        + "' and friends.user2.id='" + friendId
                        + "' or friends.user1.id='" + friendId + "'");
        if (!resultList.isEmpty()) {
            hibernateTemplate.delete(resultList.get(0));

        } else
            throw new Exception();
    }


Проблема: когда удаляю пользователя, он не удаляется.  Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`socio`.`user_user_friends`, CONSTRAINT `FKBBEEACF5CB72EE3F` FOREIGN KEY (`friends_USER_FRIENDS_ID`) REFERENCES `user_friends` (`USER_FRIENDS_ID`))

А если ставлю так

Код

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "USER_ID1", referencedColumnName = "USER_ID")
    private User user1;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "USER_ID2", referencedColumnName = "USER_ID")
    private User user2;

то удаляется сразу все включая самих пользователей.


Суть вопроса: что нужно сделать, чтобы чтобы удалялась только UserFriends сущность? Или как лучше сконфигурировать друзей пользователя?

Автор: Zыыыыы 4.9.2010, 13:59
В таблице для сущности User, наверняка есть колонка типа User_Friends_id, содержащая id из таблицы User_Friends. Если это так, то стоит проверить, не стоит ли на колонке User_Friends_id ограничение not null. Если оно есть, то без удаления юзеров хибернейт не позволит удалить запись в таблице   User_Friends, т.к. это нарушит ограничение. Ну и как выход, снять это ограничение.
P.S. если со структурой таблиц ошибся, то опиши ее немного подробнее.

Автор: wedens 4.9.2010, 14:57
я бы сделал в классе пользователся список друзей со связью many-to-many

Автор: Lonkly 4.9.2010, 23:41
Цитата(wedens @  4.9.2010,  14:57 Найти цитируемый пост)
я бы сделал в классе пользователся список друзей со связью many-to-many 


О ну это очевидно, вот только потом с удалением и добавлением пользователя в друзья будет борода.



Цитата(Zыыыыы @  4.9.2010,  13:59 Найти цитируемый пост)
В таблице для сущности User, наверняка есть колонка типа User_Friends_id, содержащая id из таблицы User_Friends. Если это так, то стоит проверить, не стоит ли на колонке User_Friends_id ограничение not null. Если оно есть, то без удаления юзеров хибернейт не позволит удалить запись в таблице   User_Friends, т.к. это нарушит ограничение. Ну и как выход, снять это ограничение.


Спасибо, вот это сейчас и проверим...

Автор: Lonkly 5.9.2010, 01:36
Не выходит. Получаю вот что...


Код

Caused by: java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`socio`.`user_user_friends`, CONSTRAINT `FKBBEEACF5CB72EE3F` FOREIGN KEY (`friends_USER_FRIENDS_ID`) REFERENCES `user_friends` (`USER_FRIENDS_ID`)

Автор: wedens 5.9.2010, 08:33
у вас вобще бред полный, потому ничего и не работает, если с одной стороны ManyToMany  то и с другйо должно быть ManyToMany. сделайте просто в классе пользователся(ну он у вас итак есть) список друзей того же класса, не делая какой-то UserFriends с бредовыми полями и еще более бредовыми маппингами

Автор: Zыыыыы 5.9.2010, 12:39
Раз мой способ не помог, то возможно стоит действительно пересмотреть сруктуру классов. Если у одного юзера может быть несколько друзей, то можно сделать следующую структуру:
Таблица Users(id и поля по усмотрению), таблица Friends с полями id записи, id юзера, id юзера-друга. Уникальным будет только первое. Получится немного вырожденный вариант ManyToMany. Ну и, как написал wedens, сделать в классе User коллекцию друзей-юзеров.
Кстати важно не забыть поставить атрибут invers="true" у связи ManyToMany, так можно будет удалять друзей юзера напрямую из коллекции юзера, а потом делать его апдейт. Поле таких манипуляций таблица Users не должна измениться, а в Friends удаляться соответствующие записи.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)