Reputation: 1782
I am trying to use JPA to make a simple update to my table column in MYSQL.
Here is the snippet:
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);
}
Now, fmedia is the table and I want to update an existing record of a value in fstatus
column of the table. The error I got was:
Caused by: com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Column 'FEXT' cannot be null
FEXT
is a column in the same table and it's a not nullable column but there's already a value tied to that record.The exception is thrown at the line em.merge(fmedia)
. I am confused what is the issue here.
I couldn't use save
since my JPA is the older version.
Does anyone know what am I doing wrong?
EDIT: Entity code:
@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;
Upvotes: 0
Views: 372
Reputation: 31433
Merge is used for detach entities. If you want to update an existing entity, use fetch + update.
1) fetch exiting Entity by nodeid
2) update necessary fields on that Entity (e.g. fmedia.setFstatus(2))
3) save the entity (if you're using Hibernate, the save is not necessary, Hibernate will still issue an Update statement)
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
Using entityManager:
entityManager.find(Fmedia.class, nodeId);
If you want to fetch your entity based on something else, rather than the primaryId, you will have to crate a query:
entityManager.createQuery("select m from Fmedia m where m.foname = :foname");
Upvotes: 2
Reputation: 12205
Merge does not do that you need to fetch the existing entity and update that entity instead of persisting a new one with same id, so like:
Fmedia fmedia = em.find(FMEdia.class, fileId);
fmedia.setFstatus(2);
em.persist(fmedia);
Merge is for attaching existing but detached entity to persistence context and your new FMedia(..)
is not detached but just new.
Upvotes: 1