How to use em.merge () to insert or update for jpa objects if the primary key is generated by the database?

I have a JPA object like this:

@Entity
@Table(name = "category")
public class Category implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private Integer id;

    @Basic(optional = false)
    @Column(name = "name")
    private String name;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "category")
    private Collection<ItemCategory> itemCategoryCollection;

    //...
}

Use Mysql as a Base Database. "name" is a unique key. Use Hibernate as a JPA Provider.

The problem with using the merge method is that since pk is generated by db, so if the record already exists (the name already exists), Hibernate will try to insert it into db, and I will get a unique key constraint exception exception and without updating. Does anyone have a good practice to handle this? Thank!

PS: my workaround is as follows:

public void save(Category entity) {

    Category existingEntity = this.find(entity.getName());
    if (existingEntity == null) {
       em.persist(entity);
       //code to commit ...
    } else {
        entity.setId(existingEntity.getId());
        em.merge(entity);
        //code to commit ...
    }
}

public Category find(String categoryName) {
    try {
        return (Category) getEm().createNamedQuery("Category.findByName").
                setParameter("name", categoryName).getSingleResult();
    } catch (NoResultException e) {
        return null;

    }
}
+5
source share
2

em.merge() jpa, ?

, IMO . , "upsert" - , PK, JPA (merge ).

, AFAIK 2.

INSERT, - , ( ).

SELECT, SELECT ( , ). , 100% , ( categoryName , ). , .

: , 3- , MySQL, . 12.2.5.3, INSERT... ON DUPLICATE KEY UPDATE . JPA.

+9

, , . .

, , , @Version , ( db) .

, . , , - , . :

CREATE TABLE example
(
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  version INT,   -- <== It really is that simple!
  value VARCHAR(255)
);

Java @Version :

@Entity
public class Example {
    @Id 
    @GeneratedValue
    private Integer id;

    @Version  // <-- that the trick!
    private Integer version;

    @Column(length=255)
    private String value;
}

@Version JPA , , :

UPDATE example 
SET value = 'Hello, World!' 
WHERE id = 23
AND version = 2  -- <-- if version has changed, update won't happen

(JPA , )

, ​​ ( ) ( ).

, , , getter version, . isPersistent, , , :

@Entity
public class Example {
    // ...
    /** Indicates whether this entity is present in the database. */
    public boolean isPersistent() {
        return version != null;
    }
}

, insertOrUpdate:

public insertOrUpdate(Example example) {
    if (example.isPersistent()) {
        // record is already present in the db
        // update it here
    }
    else {
        // record is not present in the db
        // insert it here
    }
}
+1

All Articles