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

时间:2017-02-10 13:22:04

标签: java spring-data-jpa

我有这样的Jpa存储库:

public interface BalanceRepository extends JpaRepository<Balance, Long> {

}

据我所知(并且answer它确认)实体管理器插入新记录(当实体是新的时)并且当不是新的时更新实体记录。

我的实体类层次结构:

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

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;
        }

 }

当我保存新的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);

更新1 - 当我findOne(Long id)更新记录时,似乎更新了值,但数据库中的值未更改。

3 个答案:

答案 0 :(得分:0)

尝试设置&#34; bal = balanceRepository.save(bal);&#34; ...这将返回保存的对象,并将包含生成的id ...当您运行下一次保存时,它将知道它是一个现有对象,然后将进行更新而不是保存。

如果这不起作用,请创建一个newBalance对象,在第一次保存时设置它,并将其用于第二次save和setFinalBalance调用。

答案 1 :(得分:0)

尝试以这样的方式重写代码:

@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);

  }

}

告诉我它是否有帮助。

答案 2 :(得分:0)

这部分对我来说很奇怪:

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

因为Persistable接口涵盖了此功能,所以它是默认实现。请在此处阅读:https://docs.spring.io/spring-data/jpa/docs/1.4.1.RELEASE/reference/html/jpa.repositories.html#jpa.entity-persistence.saving-entites

您可以通过在Persistable中实施Entity界面来覆盖此功能。我需要这样做,因为我使用了一个没有特色的表ID作为PK。

您是否尝试在@DataJpaTest期间保存数据?因为这会导致打开事务并且不会保存到数据库中。

balanceRepository.save(bal);的返回值是否与bal相同?如果没有,您可以尝试添加@Version注释。我读到这有时可能会有所帮助。 您还可以尝试实现Persistable接口并添加@Version注释并像这样使用它:

@Version
private Long version;

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

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