Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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
Java JPA关系的显式删除_Java_Jpa_Eclipselink_Ejb 3.1 - Fatal编程技术网

Java JPA关系的显式删除

Java JPA关系的显式删除,java,jpa,eclipselink,ejb-3.1,Java,Jpa,Eclipselink,Ejb 3.1,我对JPA中的关系管理有点困惑。 基本上,我有两个具有一对多关系的实体 配置可以有一个或多个与之关联的电子邮件列表 @Entity public class Config { @OneToMany(mappedBy="owner",cascade=CascadeType.ALL, fetch=FetchType.EAGER) private List<Email> emailReceivers; } @Entity public class Email { @

我对JPA中的关系管理有点困惑。 基本上,我有两个具有一对多关系的实体

配置可以有一个或多个与之关联的电子邮件列表

@Entity
public class Config {
    @OneToMany(mappedBy="owner",cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    private List<Email> emailReceivers;
}
@Entity
public class Email {
    @ManyToOne
    private Config owner;
}
@实体
公共类配置{
@OneToMany(mappedBy=“owner”,cascade=CascadeType.ALL,fetch=FetchType.EAGER)
私人名单收件人;
}
@实体
公共类电子邮件{
@许多酮
私有配置所有者;
}
在EJB中以及更新/合并操作期间,我将编辑与配置关联的电子邮件列表, 我认为我不需要显式调用我的电子邮件实体上的删除操作,我只需要通过删除配置电子邮件列表中的电子邮件来管理关系

@Stateless
public class ConfigFacadeImpl implements ConfigFacade{
    @EJB
    private ConfigDao configDao;
    @EJB
    private EmailDao emailDao;

    @Override
    public void update(Config Config, List<Email> emailsForDelete) {
        if(emailsForDelete!=null && emailsForDelete.size() > 0){
            for(Email emailTemp: emailsForDelete){
                Email email = emailDao.find(emailTemp.getId());
                emailDao.delete(email);  // Do I need to explicitly call the remove??
                config.getEmailReceivers().remove(email);
            }
        }
        configDao.update(config);
    }
}
@无状态
公共类ConfigFacadeImpl实现ConfigFacade{
@EJB
私有ConfigDao ConfigDao;
@EJB
私有EmailDao EmailDao;
@凌驾
公共无效更新(配置,列表emailsForDelete){
if(emailsForDelete!=null&&emailsForDelete.size()>0){
对于(电子邮件emailTemp:emailsForDelete){
Email-Email=emailDao.find(emailTemp.getId());
emailDao.delete(email);//我需要显式调用remove吗??
config.getEmailReceivers().remove(电子邮件);
}
}
configDao.update(config);
}
}
如果我不执行删除操作,只将其从列表中删除,它将不会删除我的表行

UI和数据库现在不同步,因为UI不会显示我已删除的电子邮件,但当您检查数据库时,行仍然存在

需要吗?我以为JPA会帮我处理这个问题,如果我把它从我的实体中移除的话

更新

在进行任何更改之前,我已经调整了代码以首先从数据库中获取实体,但它仍然没有删除我的子电子邮件实体。我想知道这是否是一个apache derby问题。(这是正确的方法,因为我正在将实体从JSF托管bean传递到EJB中,所以我需要首先从DB获得同步。)

@覆盖
公共无效更新(配置,列表emailsForDelete){
Config configTemp=configDao.find(Config.getId());
if(emailsForDelete!=null&&emailsForDelete.size()>0){
对于(电子邮件emailTemp:emailsForDelete){
configTemp.getEmailReceivers().remove(emailTemp);
}
}
configDao.update(config);
}

因为您已经定义了cascade type=
cascade type.ALL
,JPA应该负责删除<代码>显式删除语句是非必需的

不需要这两种陈述:

     Email email = emailDao.find(emailTemp.getId());
     emailDao.delete(email);  // Do I need to explicitly call the remove??
相反,您可能只想在
config.getEmailReceivers()
中找到匹配的
EmailReceivers
,然后删除匹配的
EmailReceivers
。无需从数据库加载
电子邮件
实体


编辑:要删除孤立对象,您可能需要包括
CascadeType。删除\u orphan
CascadeType属性以及
CascadeType。所有

这与中的问题相同


基本上,JPA只能级联到集合中的实体上。因此,对从集合中删除的子对象所做的更改永远不会放入上下文中,因此无法推送到数据库中。在本例中,oneToMany由manytones back指针控制,因此即使集合更改也不会显示,除非子集合也被合并。一旦从树中删除了一个子项,就需要对其进行单独管理和合并,以获取对其所做的更改。

对于JPA 2.0,您可以在父实体中使用选项OrphanRemoving=true

例如:

@Entity
public class Parent {
    ...

    @OneToMany(mappedBy="parentId",cascade=CascadeType.ALL, orphanRemoval=true)
    private List<Child> childList;
    ...

}
@实体
公共类父类{
...
@OneToMany(mappedBy=“parentId”,cascade=CascadeType.ALL,orphan=true)
私人名单儿童名单;
...
}

这是什么意思?实际上,我并没有删除我所有的电子邮件接收者。。仅从我的JSF UI中删除了一些项目。。如果我注释掉emailDao.delete,它不会删除我电子邮件中的条目table@MarkEstrada否。
CascadeType.ALL
相当于cascade={PERSIST,MERGE,REMOVE,REFRESH,DETACH}。保存时,它将仅删除您从集合中删除的记录,例如,如果您将配置为5个电子邮件接收者,然后删除其中2个,然后保存配置;它只会删除2个,而不是全部5个。这也是我的理解,因为我只是在阅读和遵循在线教程。。。如果我删除了显式删除邮件列表的代码行,我只是不确定为什么我的代码仍然没有删除邮件列表。@MarkEstrada请参考我更新的答案。我只是怀疑,它真的没有从列表中删除元素,因为您删除它们的方式。您可以在删除呼叫之前和之后打印/记录
emailReceivers
大小来验证这一点。我还更新了我的更新方法。在更新过程中,我首先从数据库同步配置表,然后执行删除操作。在删除之前,我有五个…在for循环之后,它现在有三个。。。但在调用merge时,它不会删除数据库中的两行。。
@Entity
public class Parent {
    ...

    @OneToMany(mappedBy="parentId",cascade=CascadeType.ALL, orphanRemoval=true)
    private List<Child> childList;
    ...

}