Daredevil
Daredevil

Reputation: 1782

JPA merge unable to update values in table

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

Answers (2)

hovanessyan
hovanessyan

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

pirho
pirho

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

Related Questions