Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data JPA inserting instead of Update

Hi I am new to Spring Data JPA and I am wondering even though I pass the Id to the entity, the Spring data jpa is inserting instead of merge. I thought when I implement the Persistable interface and implement the two methods:

public Long getId();
public Boolean isNew();

It will automatically merge instead of persist.

I have an entity class called User like:

@Entity
@Table(name = "T_USER")
public class User implements Serializable, Persistable<Long> {

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name = "USER_ID")
   private Long id;

   @Column(name = "CREATION_TIME", nullable = false)
   private Date creationTime;

   @Column(name = "FIRST_NAME", nullable = false)
   private String firstName;

   @Column(name = "LAST_NAME", nullable = false)
   private String lastName;

   @Column(name = "MODIFICATION_TIME", nullable = false)
   private Date modificationTime;

And have another class

@Entity
@Table(name = "T_USER_ROLE")
public class UserRole implements Serializable, Persistable<Long> {

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private Long roleId;

   @Column(name = "ROLE_NAME")
   private String userRole;
}

I have a custom repository called UserRepostory extending JpaReopistory. I am hitting the save for merge and persist as I see the implementation demonstrate that Spring Data Jpa uses above two methods to either update or insert.

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

I have been trying to figure out but didn't get any clue. Maybe you guys can help.

like image 279
Rana_S Avatar asked Dec 28 '14 04:12

Rana_S


People also ask

What is the difference between CrudRepository and JpaRepository?

Their main functions are: CrudRepository mainly provides CRUD functions. PagingAndSortingRepository provides methods to do pagination and sorting records. JpaRepository provides some JPA-related methods such as flushing the persistence context and deleting records in a batch.

How do you update data on a CrudRepository?

CrudRepository save() to Update an Instance We can use the same save() method to update an existing entry in our database. Suppose we saved a MerchandiseEntity instance with a specific title: MerchandiseEntity pants = new MerchandiseEntity( "Pair of Pants", 34.99); pants = repo. save(pants);

What is saveAndFlush in JPA?

The saveAndFlush() method flushes the data immediately during the execution. This method belongs to the JpaRepository interface of Spring Data JPA. you can use it as follows. userRepository.


2 Answers

I ran into this issue, tried to implement Persistable to no avail, and then looked into the Spring Data JPA source. I don't necessarily see this in your example code, but I have a @Version field in my entity. If there is a @Version field Spring Data will test that value to determine if the entity is new or not. If the @Version field is not a primitive and is null then the entity is considered new.

This threw me for a long time in my tests because I was not setting the version field in my representation but only on the persisted entity. I also don't see this documented in the otherwise helpful Spring Data docs (which is another issue...).

Hope that helps someone!

like image 181
John Shields Avatar answered Oct 12 '22 00:10

John Shields


By default Spring Data JPA inspects the identifier property of the given entity. If the identifier property is null, then the entity will be assumed as new, otherwise as not new. It's Id-Property inspection Reference

If you are using Spring JPA with EntityManager calling .merge() will update your entity and .persist() will insert.

@PersistenceContext
private EntityManager em;

@Override
@Transactional
public User save(User user) {

    if (user.getId() == null) {
        em.persist(user);
        return user;
    } else {
        return em.merge(user);
    }
}

There is no need to implement the Persistable interface.

like image 3
njjnex Avatar answered Oct 12 '22 00:10

njjnex