The save method using spring-data-jpa in springboot cannot update normally.

  java, question

Make update the simplest way

public Merchant modifyOne(Merchant merchant) {

The passed-in method parameter merchant has already set id and some attributes, and other attributes have not been set (i.e null)

The log in the console shows select before update

Hibernate: select merchant0_.ID as ID1_2_0_,   ......
 Hibernate: update MERCHANT set ADDRESS=?  ,  ......

However, the actual update operation did not merge the select result with the parameter merchant passed in the method, promptingADDRESS can not be null

In fact, I have tried to addDynamicUpdateSuch as, but no effect

 public class Merchant implements Serializable {
 @GeneratedValue(strategy = GenerationType.AUTO)
 private Long id;
 @Column(nullable = false, length = 200)
 private String address;

Does it have to be done manually before the update calls savefindOneOnce, do you manually merge the query results and parameters?
Solving. . .

After a long time of investigation, it is true that@ so afraid of troubleThis is what I said.
As for why@DynamicUpdateThe ineffectiveness is still unclear. . .
The solutions that can be found at present are their own.JpaRepository
Here we give our own implementation for reference (Springboot 1.5.6 test passed)

Define one’s ownExtJpaRepositoryInterface

 public interface ExtJpaRepository<T, ID extends Serializable> extends JpaRepository<T,ID> {
 * insert or dynamic update entity (will findOne first)
 * @param id entity id
 * @param entity entity
 * @return entity
 T dynamicSave(ID id, T entity);

InterfaceExtJpaRepositoryThe implementation of (includinggetNullPropNamesFor custom methods)

public class SimpleExtJpaRepository<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements ExtJpaRepository<T, ID> {
 private final EntityManager em;
 public SimpleExtJpaRepository(JpaEntityInformation<T, ?  > entityInformation, EntityManager em) {
 super(entityInformation, em);
 this.em = em;
 public SimpleExtJpaRepository(Class<T> domainClass, EntityManager em) {
 super(domainClass, em);
 this.em = em;
 public T dynamicSave(ID id, T entity) {
 T managedEntity = this.findOne(id);
 T mergedEntity;
 if (managedEntity == null) {
 mergedEntity = entity;
 } else {
 BeanUtils.copyProperties(entity, managedEntity, BeanUtil.getNullPropNames(entity));
 mergedEntity = managedEntity;
 return mergedEntity;

Realize one’s ownExtJpaRepositoryFactoryBeanTo replace the originalJpaRepositoryFactoryBean

public class ExtJpaRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable> extends JpaRepositoryFactoryBean<R, T, I> {
 public ExtJpaRepositoryFactoryBean(Class<?  extends R> repositoryInterface) {
 protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) {
 return new ExtJpaRepositoryFactory(em);

ExtJpaRepositoryFactoryBeanUsed inExtJpaRepositoryFactory

public class ExtJpaRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {
    private final EntityManager em;

    public ExtJpaRepositoryFactory(EntityManager em) {
        this.em = em;

    protected <T, ID extends Serializable> SimpleExtJpaRepository<?, ?> getTargetRepository(RepositoryInformation information, EntityManager entityManager) {
        JpaEntityInformation<?, Serializable> entityInformation = getEntityInformation(information.getDomainType());
        return getTargetRepositoryViaReflection(information, entityInformation, entityManager);

    protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
        if (isQueryDslExecutor(metadata.getRepositoryInterface())) {
            return QueryDslJpaRepository.class;
        } else {
            return SimpleExtJpaRepository.class;

    private boolean isQueryDslExecutor(Class<?> repositoryInterface) {
        return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface);

Finally, the entranceApplicationSpecifies to use a custom FactoryBean in

 @EnableJpaRepositories(repositoryFactoryBeanClass = ExtJpaRepositoryFactoryBean.class)
 public class StartApplication {
 public static void main(String[] args) {, args);