1

I have a spring repository for the class Business:

public interface BusinessRepository extends JpaRepository<Business, String> {

That include a simple method to update just one field (updateDatetime):

@Modifying
@Query("update Business business set business.updateDatetime = :updateDatetime where business.businessKey = :businessKey")
int setUpdateDatetimeForBusiness(@Param("updateDatetime") String updateDatetime, @Param("businessKey") String businessKey);

The problem is when I call this method:

businessRepository.setUpdateDatetimeForBusiness(business.getUpdateDatetime(), business.getBusinessKey());

The logs shows the following:

Hibernate: update business set name=?, timezone=?, updatedatetime=? where business_id=?
Hibernate: update business set updatedatetime=? where business_id=?

The method is calling a full update for the entity, then calling my update. What should I change to call just the second update?

Mariano L
  • 1,809
  • 4
  • 29
  • 51
  • Could you post the code that calls the method? – crizzis Apr 27 '18 at 08:33
  • 1
    Updates made to a persistent entity within a transaction will be automatically flushed when the transaction ends. So I would guess that you have loaded and modified (set the updateDateTime) a persistent entity within a transaction. When your transactional method returns the entity manager flushes the changes. – Alan Hay Apr 27 '18 at 13:58

1 Answers1

-1
@Query(value="update something", nativeQuery=true)

nativeQuery=true try to add this


update

Sorry for didn't read the question carefully.

As the inflammation you provided, I can't find the problem out. But I do have suggestions for you.

The entity managed by EntityManager can automatically persist into database, and you log Hibernate: update business set name=?, timezone=?, updatedatetime=? where business_id=? seems like it updated all the fields? If so, the update much more likely called by EntityManager.

And you can change the flushMode to COMMIT to see if this make changes. (just for testing if the problem is caused by EntityManager's automatically update)
eg: spring.jpa.properties.org.hibernate.flushMode=COMMIT in spring boot.


My test code:

service:

import cn.eeemt.dao.TagRepository;
import cn.eeemt.entity.Tag;
import cn.eeemt.service.TagService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Optional;

@Service
public class TagServiceImpl implements TagService {

    @Resource
    private TagRepository tagRepository;

    @Override
    public void update(String newDescription) {
        Tag tag = step1(newDescription);
        step2(tag.getDescription(), tag.getId());
    }

    @Transactional
    public Tag step1(String newDescription) {
        Optional<Tag> byId = tagRepository.findById(1);
        Tag tag = byId.orElseThrow(RuntimeException::new);
        System.out.println(tag);
        tag.setDescription(newDescription);
        // tagRepository.save(byId.get());  // I did not update it!!!
        return tag;
    }

    private void step2(String description, Integer id) {
        tagRepository.updateSome(description, id);
    }
}  

repository:

import cn.eeemt.entity.Tag;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

public interface TagRepository extends JpaRepository<Tag, Integer> {

    @Modifying
    @Transactional
    @Query("update Tag tag set tag.description = :description where tag.id = :id")
    void updateSome(@Param("description") String description, @Param("id") int id);
}

when spring.jpa.properties.org.hibernate.flushMode=ALWAYS

log looks like:

Tag{id=1, name='ffadsfasd', description='dasfadsg', articles=[]}
Hibernate: update tag set description=?, name=? where id=?
Hibernate: update tag set description=? where id=?

when spring.jpa.properties.org.hibernate.flushMode=COMMIT

log looks like:

Tag{id=1, name='ffadsfasd', description='dasfadsgaaer', articles=[]}
Hibernate: update tag set description=? where id=?


If the problem it what I said above, it's not good idea to change flushMode unless it's suitable for you situation. You'd better to refactor you code for better design.


information may help you:

mt eee
  • 80
  • 10