简体   繁体   English

为什么 JpaRepository 不更新我的实体?

[英]Why doesn't JpaRepository update my entity?

I have such Jpa repository:我有这样的 Jpa 存储库:

public interface BalanceRepository extends JpaRepository<Balance, Long> {

}

As far as I know (and this answer it confirms) entity manager insert new record (when entity is new) and update entity record when is not new.据我所知(并且这个答案证实了)实体管理器插入新记录(当实体是新的)并在不是新的时更新实体记录。

My entity class hierarchy:我的实体类层次结构:

@Entity
@Table(name = "balances")
public class Balance extends BaseEntity {
// omitted 
}

and BaseEntity和基础BaseEntity

    @MappedSuperclass
    @EntityListeners(AuditingEntityListener.class)
    @JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
    public abstract class BaseEntity {

        private static Logger LOGGER = LogManager.getLogger(BaseEntity.class);

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id", updatable = false, nullable = false)
        @JsonProperty("id")
        private Long id;

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
               this.id = id;
            }

    public boolean isNew() {
            return id == null;
        }

 }

When I save new Balance entity, new record is inserted but not update is done, why?当我保存新的Balance实体时,插入了新记录但没有完成更新,为什么?

Balance bal = new Balance();
        bal.setFinalBalance(BigDecimal.TEN);
        bal.setUser(user);
        bal.setRecordDate(date);
        bal.setMinusBalance(BigDecimal.TEN);
        bal.setPlusBalance(BigDecimal.TEN);
        bal.setTotalBalance(BigDecimal.TEN);

        // entity is inserted
        balanceRepository.save(bal);

        // no update...
        bal.setFinalBalance(bal.getFinalBalance().add(BigDecimal.TEN));
        balanceRepository.save(bal);

Update 1 - When I findOne(Long id) updated record, value seems to be updated, but value in database is not changed.更新 1 - 当我findOne(Long id)更新记录时,值似乎已更新,但数据库中的值未更改。

Try setting "bal = balanceRepository.save(bal);"尝试设置“bal = balanceRepository.save(bal);” ... this will return the saved object and will include the generated id ... when you run the next save, it will know that it is an existing object and will then do an update instead of a save. ...这将返回保存的对象并包含生成的 id ...当您运行下一次保存时,它将知道它是一个现有对象,然后将执行更新而不是保存。

If that doesn't work, create a newBalance object, set it on the first save and use it for the second save and setFinalBalance call.如果这不起作用,请创建一个 newBalance 对象,在第一次保存时设置它并将其用于第二次保存和 setFinalBalance 调用。

Try to rewrite your code such way:尝试以这种方式重写您的代码:

@Service
public class BalanceService {
  // ...
  @Transactional
  public void save(Balance balance){
     balanceRepository.save(balance);  
  }

  public void check(){
     Balance bal = new Balance();
    bal.setFinalBalance(BigDecimal.TEN);
    bal.setUser(user);
    bal.setRecordDate(date);
    bal.setMinusBalance(BigDecimal.TEN);
    bal.setPlusBalance(BigDecimal.TEN);
    bal.setTotalBalance(BigDecimal.TEN);
    // entity is inserted
    save(bal);

    bal.setFinalBalance(bal.getFinalBalance().add(BigDecimal.TEN));
    save(bal);

  }

}

And tell me does it help or not.并告诉我它是否有帮助。

Hei

This part looks weird to me:这部分对我来说看起来很奇怪:

public boolean isNew() {
    return id == null;
}

Because this function is covered by the Persistable interface and is the default implementation.因为这个函数被Persistable接口覆盖,并且是默认实现。 Read here: https://docs.spring.io/spring-data/jpa/docs/1.4.1.RELEASE/reference/html/jpa.repositories.html#jpa.entity-persistence.saving-entites在这里阅读: https : //docs.spring.io/spring-data/jpa/docs/1.4.1.RELEASE/reference/html/jpa.repositories.html#jpa.entity-persistence.saving-entites

You can override this function by implementing the Persistable interface in your Entity .您可以通过在Entity实现Persistable接口来覆盖此功能。 I needed to do this because I used an not gerenerated table id as PK.我需要这样做,因为我使用了一个未生成的表 ID 作为 PK。

Do you try to save the data during a @DataJpaTest ?您是否尝试在@DataJpaTest期间保存数据? Because this can lead to open transactions and will not save to the database.因为这会导致打开事务并且不会保存到数据库中。

Is the return value from balanceRepository.save(bal);balanceRepository.save(bal);的返回值balanceRepository.save(bal); the same as bal ?bal吗? If not you can trie to add the @Version annotation.如果没有,您可以尝试添加@Version注释。 I read that this sometimes might help.我读到这有时可能会有所帮助。 You can also trie to implement the Persistable interface and add the @Version annotation and use it like this:您还可以尝试实现Persistable接口并添加@Version注释并像这样使用它:

@Version
private Long version;

@Override
public Long getId() {
    return id;
}

@Override
public boolean isNew() {
    return version == null;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM