JPA合并无法更新表中的值

时间:2019-02-15 08:25:09

标签: java jpa

我正在尝试使用JPA对MYSQL中的表列进行简单的更新。

以下是代码段:

public Node get_folder(long fileID) {
    try {
        List resList = nodeFacade.list_parent(fileID, LinkType.FILE);
        List resList1 = nodeFacade.list_parent(fileID, LinkType.VER_LINKS);
        if (resList == null) {
            throw new Exception("failed to get folder of a file." + 
                nodeFacade.getMsg());
        }
        if (resList.size() > 1) {
            throw new Exception("one file cannot be attached to more than one folder(s).");
        }

        //fixed bugs: modified here to display different version
        if(resList1.size()==1){
            Fmedia fmedia = em.find(fileID,Fmedia.class);
            fmedia.setFstatus(2);
            em.merge(fmedia);
            return (Node) resList1.get(0);
        }

现在,fmedia是表,我想更新表fstatus列中值的现有记录。我得到的错误是:

  

由以下原因引起:com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException:列“ FEXT”不能为空

FEXT是同一表中的一列,它不是不可为空的列,但已经有与该记录相关的值。在行em.merge(fmedia)处引发了异常。我很困惑这里是什么问题。

由于我的JPA是较旧的版本,因此我无法使用save

有人知道我在做什么错吗?

编辑:实体代码:

@Entity
@Table(name = "fmedia")
public class Fmedia implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "NODEID")
    private Long nodeid;
    @Basic(optional = false)
    @Column(name = "FONAME")
    private String foname;
    @Basic(optional = false)
    @Column(name = "FGNAME")
    private String fgname;
    @Basic(optional = false)
    @Column(name = "FEXT")
    private String fext;
    @Basic(optional = false)
    @Column(name = "FFULPATH")
    private String ffulpath;
    @Column(name = "FTYPE")
    private int ftype;
    @Basic(optional = false)
    @Column(name = "FSIZE")
    private long fsize;
    @Column(name = "FREMARK")
    private String fremark;
    @Column(name = "FSTATUS")
    private int fstatus;
    @Column(name = "FDESC")
    private String fdesc;
    @Column(name = "MODIFYDATE")
    @Temporal(TemporalType.DATE)
    private Date ModifyDate;
    @Size(max = 3000)
    @Column(name = "FNTFREMARK")
    private String fntfremark;
    @Transient
    private Fverinfo fver;

2 个答案:

答案 0 :(得分:2)

合并用于分离实体。 如果要更新现有实体,请使用提取+更新

1)通过nodeid获取退出实体

2)更新该实体上的必要字段(例如fmedia.setFstatus(2))

3)保存实体(如果您使用的是Hibernate,则不必保存,Hibernate仍会发出Update语句)

Fmedia fmedia = repository.findOne(nodeid); //manged entity-update
fmedia.setFstatus(2); // hibernate will issue an update, cause the entity is managed
repository.save(fmedia) //redundant save anti-pattern, don't call save

使用entityManager:

entityManager.find(Fmedia.class, nodeId);

如果您想基于其他东西而不是primaryId来获取您的实体,则必须创建一个查询:

entityManager.createQuery("select m from Fmedia m where m.foname = :foname");

答案 1 :(得分:1)

合并不执行,您不需要获取现有实体并更新该实体,而不是持久保存具有相同ID的新实体,例如:

Fmedia fmedia = em.find(FMEdia.class, fileId);
fmedia.setFstatus(2);
em.persist(fmedia);

合并用于将现有但分离的实体附加到持久性上下文,并且您的new FMedia(..)不是分离的,而是新的。