我正在尝试使用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;
答案 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(..)
不是分离的,而是新的。