0

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;
pirho
  • 11,565
  • 12
  • 43
  • 70
Daredevil
  • 1,672
  • 3
  • 18
  • 47

2 Answers2

2

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");
hovanessyan
  • 30,580
  • 6
  • 55
  • 83
1

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.

pirho
  • 11,565
  • 12
  • 43
  • 70
  • But isn't persist like `insert`? It's gonna insert new records to the table? – Daredevil Feb 15 '19 at 08:48
  • @daredevil Not exactly. See [this](https://stackoverflow.com/q/4509086/6413377) for example. – pirho Feb 15 '19 at 08:53
  • I tried your way but I can't resolve the find method because my fileID is declared as `long` – Daredevil Feb 15 '19 at 08:54
  • So we use persist instead? – Daredevil Feb 15 '19 at 09:01
  • Does using fileID able to retrieve it in Fmedia class since it's NodeID in the fmedia class but i am passing fileID to it. I mean fmedia class doesn't have FileID but just nodeID but they are both the same. – Daredevil Feb 15 '19 at 09:04
  • you are passing a long/Long value of the entitys id field, the names of these fields does not matter in this case. – pirho Feb 15 '19 at 09:05
  • Well your answer does work. It does update the value to 2. However, it doesn't hide the button though – Daredevil Feb 15 '19 at 09:06