Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JSF选择checkboxmenu&;Hibernate@ManyToMany删除值_Hibernate_Jsf_Primefaces_Many To Many_Jsf 2.3 - Fatal编程技术网

JSF选择checkboxmenu&;Hibernate@ManyToMany删除值

JSF选择checkboxmenu&;Hibernate@ManyToMany删除值,hibernate,jsf,primefaces,many-to-many,jsf-2.3,Hibernate,Jsf,Primefaces,Many To Many,Jsf 2.3,首先是所用软件的一些细节:我正在Wildfly 14.0.1上使用primefaces 6.2.11,最后使用JSF 2.3 问题描述:我有两个实体(用户和组)与许多人相关,我想删除一个与所有者(具有mappedBy的实体)不相关的关系。我无法更改所有者方,因为这是遗留代码。我知道我必须删除两端的关系,但我的代码不起作用。向列表中添加值没有问题,但无法删除它们。 几天前我用Wildfly 10试过这个,没问题,但新的不行 一个问题是primefaces列表没有通过ajax事件通知我何时删除某个项

首先是所用软件的一些细节:我正在Wildfly 14.0.1上使用primefaces 6.2.11,最后使用JSF 2.3

问题描述:我有两个实体(用户和组)与许多人相关,我想删除一个与所有者(具有mappedBy的实体)不相关的关系。我无法更改所有者方,因为这是遗留代码。我知道我必须删除两端的关系,但我的代码不起作用。向列表中添加值没有问题,但无法删除它们。 几天前我用Wildfly 10试过这个,没问题,但新的不行

一个问题是primefaces列表没有通过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 ...
}
当用户点击按钮时,我调用以下服务:

@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;
}
@Transactional(Transactional.TxType.REQUIRED)
公共用户persistWithDeps(用户user2Save){
User User=User=baseEm.contains(user2Save)?user2Save:baseEm.merge(user2Save);
//检查是否有一个新对象(案例:baseEm.merge(user2Save))
if(user!=user2Save){
if(null!=user.getGroupList()){
//删除组
如果(!user2Save.getGroupList().containsAll(user.getGroupList())){
//从用户中删除组
迭代器迭代器=user.getGroupList().Iterator();
while(iterator.hasNext()){
Group=iterator.next();
如果(!user2Save.getGroupList()包含(组)){
group.getuser2SaveList().remove(用户);
iterator.remove();
}
}
}
//向用户添加组
user.getGroupList().forEach(组->{
如果(!group.getUserList()包含(用户)){
group.getUserList().add(用户);
}
});
}
}
baseEm.persist(用户);
返回用户;
}

它与JPA有关。您将级联放在了错误的实体上:

@ManyToMany(fetch = FetchType.LAZY, targetEntity = Group.class, mappedBy = "userList", , cascade = {CascadeType.MERGE, CascadeType.PERSIST})
然后,您必须坚持i.s.o.合并:

baseEm.merge(user);
“持久化”只能用于创建新对象。由于要更新对象,请使用“合并”

另外,persistWithDeps方法是以一种非常奇怪的方式编写的。当Primefaces正确更新用户对象中的组列表时,这就足够了:

public User persistWithDeps(User user2Save) {
    return baseEm.merge(user2save);
}
JPA将自动生成删除或添加多对多表中的组实体所需的SQL

还要注意,添加和删除操作都是基于幕后的equals和hashcode。它们必须被正确地编程,如果没有,它可以产生什么都不发生的效果

所以,试着用我的方法代替这个方法。如果仍然不起作用,则在
return baseEm.merge(user2save)上放置一个断点并选中user.getGroupList()。它必须具有您期望的正确组数。如果是这样,合并仍然不起作用,则需要更改equals和hashcode方法。如果断点上的组数不正确,这意味着JSF链接bean(editUserBean)和对persistWithDeps的调用之间出现了问题

顺便说一句,您的SelectCheckBox菜单标签和转换器看起来正常


祝你好运

“代码不起作用”并不是自我解释。由于您没有说明它是如何工作的(日志、控制台或浏览器中的错误消息,无论如何都没有调用方法,还有许多其他可能性),我只能猜测您的代码没有编译,因为您使用
user2Save
作为变量和类型。很抱歉,我的解释不正确。代码是编译的,这是由于剥离我的stackoverflow示例而导致的类型。问题是,我不能从列表中删除任何组。Hibernate不会删除关系,因此始终需要。您是否尝试在select中添加ajax来跟踪哪些是选中的,哪些不是选中的?稍后,我可以尝试创建一个更完整的示例。是的,我添加了一些ajax,一切都很好。我将正确的列表传递给merge/persist方法,但是hibernate不执行任何delete语句,这不是jsf(2.3)或PrimeFaces问题,而是纯hibernate(甚至JPA)问题。也许创建一个简单的单元测试会更好\
baseEm.merge(user);
public User persistWithDeps(User user2Save) {
    return baseEm.merge(user2save);
}