无法使用remove()方法在JPA中删除子级 [英] Can't remove child in JPA using remove() method

查看:35
本文介绍了无法使用remove()方法在JPA中删除子级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经做了大量研究,由于某种原因我什至没有得到僵尸"实例(例如会话中已存在但不再存在于db中的情况),这对我来说是行不通的-我希望我有这种情况),因为 remove()不会传播到数据库中.子记录继续存在于我的数据库中.

I've done considerable research it doesn't work for me for some reason I don't even get into the situation where I get "zombie" instances(like existing in session but not in db anymore - I wish I had this situation) since remove() is not propagated into database. The child record continues to exist inside my db.

考虑两个表: User Token(FK_User_Id),它们分别是一对多关系.

Consider two tables: User and Token(FK_User_Id) , relationship one-to-many respectively

内部DAO最终代码无效:

public void deleteToken(Token t) {

    Token b = em.merge(t);

    em.remove(b); // does nothing

    em.flush();
}

内部控制器:

    Object obj;
    Token token;

    obj = tokenService.getByString(urlToken); // query returning detached object
    User user;

    if (obj != null) {

        token = (Token) obj; // Detached, query is "fetch" overriding lazy init, so token contains its user parent

        user = token.getUser(); // simply get the user to which this token belongs

        if ((token.getExpiryDate().compareTo(new GregorianCalendar()
                .getTime())) == 1) {

            userService.activateUser(user); // user gets merged inside and its relevant property is changed and propagated to db successfully

            tokenService.deleteToken(token); // this line calls DAO method described in snippet above - it fails to delete the token, but no error or exception - record simply stays in database

        model.addAttribute("activationSuccess", "true");


        }...

用户实体:

public class User {

    public static final String FIND_USER_BY_TOKEN = "findUserByToken";
    public static final String FIND_USER_BY_USERNAME = "findUserByUsername";
    public static final String FIND_USER_BY_EMAIL = "findUserByEmail";

    @Id
    @GeneratedValue
    private Long id;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval=true)
    private List<Token> tokens = new ArrayList(); ...

令牌实体:

@Entity
@Table(name = "token")
@NamedQueries({
    @NamedQuery(name=Token.FIND_TOKEN_BY_STRING, query="Select t From Token T where t.tokenString=:string")
})
public class Token {

    public static final String FIND_TOKEN_BY_STRING = "findTokenById";
    @Id
    @GeneratedValue
    Long id;

    @ManyToOne(optional=true)
    private User user; ...

现在,如果我打电话给类似的人

Now if I call something like:

    User c = b.getUser();
            em.remove(c);

在DAO片段中,它同时删除了令牌和用户,这不是我想要的.只有令牌必须删除.

Inside DAO snippet, it deletes both token and user which is not what I want. Only token must be deleted.

基本上,我想做的是按字符串属性检索Token,并与拥有此令牌的用户父级一起检索它.然后,我从令牌中检索该用户并更改该用户的某些属性(更改传播到db).到目前为止一切成功.然后,我想删除令牌作为最终操作,但以某种方式不会删除用户.

Basically what I am trying to do is to retrieve Token by string property and along with it the user parent which owns this token. Then I retrieve this user from token and change some property for the user(changes propagated into db). All successful so far. Then I want to delete the token as a final operation but in a way that user will not be deleted.

我已经第五个小时了,请帮忙...我设法将令牌(传播到db)的setId设置为null,但这仅使我明白了令牌不再拥有所有者,但仍保留在数据库中的情况.为了删除它,我尝试将DAO中的Token与null合并,这使我异常.然后,我尝试将User(从此令牌中检索到)中的Tokens列表值设置为null,并且也通过我设置了异常.

I am on my fifth hour on this please help... I managed to setId to null for the token(propagated into db), but it only gets me the point where token no longer has owner but still persists in database. To delete it I tried to merge the Token inside DAO with null which threw me exception. Then I tried to set Tokens list value to null inside User(which was retrieved from this token) and it also through me exception.

我应该如何删除与父级一起检索但仍保留在db中的子令牌实体?

How I am supposed to delete child token entity which I retrieved with its parent but keep parent present in db?

SQL Hibernate日志显示没有删除查询...通过了remove方法之后.

SQL Hibernate log shows no delete query...after passing remove method.

谢谢

推荐答案

如果您没有从用户的令牌列表中取消引用令牌,则级联持久性(您已级联所有包含持久性的设置)将导致令牌在以下位置恢复一点.您必须清除所有对该子项的引用,尤其是当您要删除实体时,标记为层叠的引用将保留.像这样:

If you do not dereference the token from User's list of tokens, cascade persist (you have cascade all set which includes persist) will cause the token to be resurrected at some point. You must clear all references to the child, especially ones marked cascade persist when you want to remove entities. Something like:

if ((token.getExpiryDate().compareTo(new GregorianCalendar()
                .getTime())) == 1) {
    user.getTokens().remove(token);
    userService.activateUser(user); 
    //tokenService.deleteToken(token); //no longer needed due to orphanremoval being true
    model.addAttribute("activationSuccess", "true");
    ...

这篇关于无法使用remove()方法在JPA中删除子级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆