Транзакция прервана при попытке сохранить пользователя - PullRequest
1 голос
/ 20 января 2012

Я пытаюсь сохранить пользователя.Пользовательский объект и групповой объект имеют двунаправленное отношение «многие ко многим».Однако группы уже сохранены в базе данных (только две: администратор и пользователь).

Здесь я просто "подделал" группу, которая уже существует, потому что я думал, что это сработает.Я не могу добавить cascade = CascadeType.PERSIST для пользователя, потому что тогда он снова сохранит группу, что приведет к дублированию данных.Как бы это исправить?

Из EJB

public void persistAsUser(User user) {
    Group group = new Group(2L, "user");
    user.addGroup(group);

    userRepository.persist(user);
}

javax.ejb.EJBException: транзакция прервана

Причина: java.lang.IllegalStateException:Во время синхронизации был обнаружен новый объект через связь, которая не была помечена каскадом PERSIST:


Вот сущности:

    @Entity
    @Table(name = "app_user")
    public class User implements Serializable {

        public static final String ALL = "User.all";

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String firstName;
        private String lastName;
        private Integer age;
        private String username;
        private String email;
        private String password;

        @ManyToMany(mappedBy = "users")
        private List<Group> groups;

        ....

public void addGroup(Group group) {

    if (!getGroups().contains(group)) {
        getGroups().add(group);
    }

    if (!group.getUsers().contains(this)) {
        group.getUsers().add(this);
    }
}
}

и

@Entity
    public class Group implements Serializable {

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String groupName;

        @ManyToMany
        @JoinTable(joinColumns = {@JoinColumn(name="group_id")}, inverseJoinColumns = {@JoinColumn(name="user_id")})
        private List<User> users;

       ....

}

Ответы [ 2 ]

1 голос
/ 20 января 2012

Эта проблема обычно возникает, когда

  • у вас есть двунаправленные ассоциации, которые не заполнены с обеих сторон
  • у вас есть управляемый (User) объект, ссылающийся на неуправляемый объект (Group).

Если вы не хотите сохранять Group, просто установите для групп значение null, как указано в моем комментарии.

Однако, если вы хотите связатьПользователь в группу, один из вариантов будет

  1. load Group, в который вы хотите добавить пользователя к
  2. Добавьте User к Group иViceversa.
  3. merge Группа

Не забудьте пометить Группу -> Отношения пользователя как CascadeType.MERGE

0 голосов
/ 20 января 2012

Помещая атрибут mappedBy в класс User, вы говорите, что класс Group отвечает за сохранение ассоциации.

Поскольку отношение является двунаправленным, вы можете указать любую сторону в качестве стороны-владельца отношения.

Попробуйте переместить атрибут mappedBy в аннотацию ManyToMany класса Group, а затем сохраните пользователя таким, каким вы были.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...