无法在不抛出EntityExistException的情况下更新对象

时间:2018-04-26 20:04:52

标签: sql spring hibernate spring-boot jpa

我正在尝试执行双向一对一关系,并且在第一次保存时更新AccountExtrasModel时工作正常但在更新时我得到错误或sql语句添加插入然后删除而不是更新。

import lombok.*;
import javax.persistence.*;

@ToString
@NoArgsConstructor
@Getter
@Setter
@Entity
@Table(name = "Account")
public class AccountModel {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long Account_ID;

    @Column(nullable = false, updatable = false)
    private String name;

    @Column(nullable = false, unique = true, updatable = false)
    private String email;

    @Column(nullable = false, updatable = false)
    private String password;

    @OneToOne(mappedBy = "accountModel", cascade = CascadeType.ALL, orphanRemoval = true)
    private AccountExtrasModel accountExtras;

    public AccountModel addExtras(AccountExtrasModel accountExtrasModel) {
        accountExtrasModel.setAccountModel(this);
        this.setAccountExtras(accountExtrasModel);
        return this;
    }
}

import lombok.*;
import javax.persistence.*;

@Setter
@Getter
@NoArgsConstructor
@ToString
@Entity
@Table(name = "AccountExtras")
public class AccountExtrasModel {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long ID;

    @OneToOne(fetch = FetchType.LAZY)
    @MapsId
    private AccountModel accountModel;

    @Lob
    private String description;
    private String[] myVideos;
    private String[] likedVideos;
    private String imageReference;
}

如果我在AccountExtrasModel中将@MapsId更改为@JoinColumn,那么我会得到所需的结果,但它的作用是插入一个新行并将其链接到acccount,然后删除旧行而不是进行更新。

这是我得到的错误:

{
    "timestamp": "2018-04-26T18:19:01.657+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "A different object with the same identifier value was already associated with the session : [com.alttube.account.models.AccountExtrasModel#1]; nested exception is javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [com.alttube.account.models.AccountExtrasModel#1]",
    "path": "/update_account"
}

我该怎么做才能获得所需的结果,即只需对accountExtrasModel执行更新,直到它所属的相应帐户?

2 个答案:

答案 0 :(得分:0)

尝试使用方法 合并 ,而不是使用 save 方法,因为如果对象存在于数据库框架将更新此对象。 如果对象不存在,框架将正常插入。

问候!

答案 1 :(得分:0)

如果您通过设置AccountModel的新实例更新AccountExtrasModel实例,就像在addExtras()中一样,那么删除+插入是正常的。通过更新ID,您将以孤立记录结束。

AccountExtrasModel实例上设置新值时,请检查accountExtras是否已初始化。如果没有,请执行addExtras()内容。如果是,不要替换它,只需更改它,因此hibernate将在extras表上生成更新(但保持记录ID不变)。