Прежде всего, некоторые сведения о используемом программном обеспечении: я работаю с основными лицами 6.2.11 в Wildfly 14.0.1, наконец, с JSF 2.3.
Описание проблемы: у меня есть две сущности (User & Group), связанные с many2manyи я хочу удалить отношение на стороне, которая является , а не владельцем (сущность с mappedBy).Я не могу изменить сторону владельца, потому что это устаревший код.Я знаю, что я должен удалить отношение на обоих концах, но мой код не работает.Добавление значений в список не проблема, но удалить их невозможно.Я пробовал это несколько дней назад с Wildfly 10, и это было нормально, но не с новым.
Одна проблема состоит в том, что список основных лиц не уведомляет меня через событие ajax, когда элемент будет удален.Если бы это было так, я мог бы обработать удаление из моего списка групп и списка пользователей в группе.Поскольку у меня нет такого события, я попытался обработать это в своем сервисе, который пытается сохранить пользователя.
У меня есть две сущности:
@Entity
@Table(name = "USER")
public class User implements Serializable {
private static final long serialVersionUID = -1699265057144017750L;
@Column(name = "ID", nullable = false)
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "USER_NAME", length = 45, unique = true)
@Basic
@NotNull
private String userName;
@ManyToMany(fetch = FetchType.LAZY, targetEntity = Group.class, mappedBy = "userList")
@OrderBy("groupName")
private Set<Group> groupList;
// getter setter ...
}
@Entity
@Table(name = "GROUP")
public class User implements Serializable {
private static final long serialVersionUID = -3403518747362744630L;
@Column(name = "ID", nullable = false)
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@ManyToMany(fetch = FetchType.LAZY, targetEntity = User.class, cascade = {CascadeType.MERGE, CascadeType.PERSIST})
@JoinTable(name = "USER_GROUP",
joinColumns = {@JoinColumn(name = "GROUP_ID", referencedColumnName = "ID")},
inverseJoinColumns = {@JoinColumn(name = "USER_ID", referencedColumnName = "ID")})
@OrderBy("userName")
private Set<User> userList;
// getter setter ...
}
Я создал форму для редактирования пользователей,Эта форма имеет много входных данных, и одна из них предназначена для добавления и удаления групп у пользователя.Это просто простые символы selectCheckboxMenu.Это позволяет пользователю выбирать новые группы и удалять старые группы.Значения (я) напрямую извлекаются из объекта пользователя, а значения, которые можно выбрать, обслуживаются отдельной службой.
<p:selectCheckboxMenu id="groupList" multiple="true" filter="true" filterMatchMode="contains"
value="#{editUserBean.authUser.groupList}"
required="true" requiredMessage="At least one group is needed"
converter="cs.argos.gui.jsf.converter.groupConverter" collectionType="java.util.LinkedHashSet">
<f:selectItems value="#{groupService.groups}" var="group" itemValue="#{group}" itemLabel="#{group.authGroupName}"/>
</p:selectCheckboxMenu>
Преобразователь:
@FacesConverter(value = "groupConverter", managed = true)
public class GroupConverter implements Converter {
@Inject
GroupService groupService;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(null == value || value.isEmpty()) {
return null;
}
try {
return groupService.getGroupWithCollections(Integer.parseInt(value));
} catch (NumberFormatException e) {
throw new ConverterException(new FacesMessage("Invalid Group ID"), e);
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
Group group = (Group) value;
if (null == group) {
return "";
}
if(null != group.getId()) {
return ""+group.getId();
} else {
throw new ConverterException(new FacesMessage("Invalid Group ID"));
}
}
}
Когданажал кнопку Я звоню в следующую службу:
@Transactional(Transactional.TxType.REQUIRED)
public User persistWithDeps(User user2Save) {
User user = user = baseEm.contains(user2Save) ? user2Save : baseEm.merge(user2Save);
// Check if we have a new object (case when: baseEm.merge(user2Save))
if (user != user2Save) {
if (null != user.getGroupList()) {
// remove groups
if (!user2Save.getGroupList().containsAll(user.getGroupList())) {
// remove groups from user
Iterator<Group> iterator = user.getGroupList().iterator();
while (iterator.hasNext()) {
Group group = iterator.next();
if (!user2Save.getGroupList().contains(group)) {
group.getuser2SaveList().remove(user);
iterator.remove();
}
}
}
// Add groups to user
user.getGroupList().forEach(group -> {
if (!group.getUserList().contains(user)) {
group.getUserList().add(user);
}
});
}
}
baseEm.persist(user);
return user;
}