【问题标题】:JpaRepository not updating entityJpaRepository 不更新实体
【发布时间】:2019-11-15 11:33:11
【问题描述】:

据我所知,JpaRepository save() 方法应该更新我在数据库中的实体。

我在 MySQL 中有一个名为 REF_PERIOD 的表,它只有两列:code_id,即 INT 和主键,以及 code_name,即 VARCHAR。

这是我的实体:

@Data
@Entity
@Table(name = "REF_PERIOD")
public class PayRefPeriod {

    @Id
    @Column(name = "code_id")
    private int codeId;

    @Column(name = "code_name", length = 254, nullable = false)
    private String codeName;
}

我的仓库:

@Repository
public interface PayRefPeriodRepository extends JpaRepository<PayRefPeriod, Integer> {

}

和控制器:

@Slf4j
@RestController
@RequestMapping("/api")
public class PayRefPeriodController {

    @Autowired
    private PayRefPeriodRepository payRefPeriodRepository;

    // Get all pay reference periods
    @GetMapping("/payrefperiods")
    public List<PayRefPeriod> getAllPayRefPeriod() {
        return payRefPeriodRepository.findAll();
    }

    // Create a new pay reference period
    @PostMapping("/payrefperiods")
    public PayRefPeriod createPayRefPeriod(@Valid @RequestBody PayRefPeriod payRefPeriod) {
        return payRefPeriodRepository.save(payRefPeriod);
    }

    // Get a single pay reference period
    @GetMapping("/payrefperiods/{id}")
    public PayRefPeriod PayRefPeriod(@PathVariable(value = "id") int payRefPeriodId) {
        return payRefPeriodRepository.findById(payRefPeriodId)
                .orElseThrow(() -> new ResourceNotFoundException("PayRefPeriod", "id", payRefPeriodId));
    }

    // Update a pay reference period
    @PutMapping("/payrefperiods/{id}")
    public PayRefPeriod updatePayRefPeriod(@PathVariable(value = "id") int payRefPeriodId,
                                      @Valid @RequestBody PayRefPeriod payRefPeriodDetails) {

        PayRefPeriod payRefPeriod = payRefPeriodRepository.findById(payRefPeriodId)
                .orElseThrow(() -> new ResourceNotFoundException("PayRefPeriod", "id", payRefPeriodId));

        payRefPeriod.setCodeName(payRefPeriodDetails.getCodeName());

        log.debug(payRefPeriod.toString());

        return payRefPeriodRepository.save(payRefPeriod);
    }

    // Delete a pay reference period
    @DeleteMapping("/payrefperiods/{id}")
    public ResponseEntity<?> deletePayRefPeriod(@PathVariable(value = "id") int payRefPeriodId) {
        PayRefPeriod payRefPeriod = payRefPeriodRepository.findById(payRefPeriodId)
                .orElseThrow(() -> new ResourceNotFoundException("PayRefPeriod", "id", payRefPeriodId));

        payRefPeriodRepository.delete(payRefPeriod);

        return ResponseEntity.ok().build();
    }
}

我希望 updatePayRefPeriod 方法更新我的实体(在 MySQL 数据库中的 Id 为 0),但它会引发异常:java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '0' for key 'PRIMARY'。

我做错了什么?

【问题讨论】:

  • 似乎你的 Id 不工作,已经有一个 id 为 0 的元素。当你保存一个没有任何 id 的实体时,你需要一个序列来增加你的 id。您使用的是哪个数据库?
  • 请检查您在数据库和调试器中的ID
  • 不要使用 save() 方法,而应该使用 update() 方法
  • 你不应该需要那个 @Repository 注释。我不知道这是否会导致您的问题。
  • @arnonuem 是的,已经有一个 id 为 0 的元素。但是我修改了“codeName”值,实体发生了变化,所以保存方法应该更新记录...数据库是 MySQL

标签: java mysql spring spring-boot jpa


【解决方案1】:

尝试将 sequenceGenerator 和 GeneratedValue 添加到您的 id 列。

@Data
@Entity
@Table(name = "REF_PERIOD")
public class PayRefPeriod {

@SequenceGenerator(name = "generator", sequenceName = "REF_PERIOD_ID_SEQ")
@GeneratedValue(strategy = GenerationType.AUTO, generator = "generator")
@Id
@Column(name = "code_id")
private int codeId;

@Column(name = "code_name", length = 254, nullable = false)
private String codeName;

}

【讨论】:

  • 我不想为我的 id 列添加自动生成的值。我只想修改现有记录的“codeName”值。
【解决方案2】:

我想这可能是一个mysql驱动程序特定的限制,当我们将它用于标识符时,对于java原始类型int。我建议您将codeId 的类型更改为它的盒装对象类型Integer

@Id
@Column(name = "code_id")
private Integer codeId;

因此底层的hibernate在生成相应的更新查询时可以理解null标识符与非空但0值标识符之间的区别。

【讨论】:

    猜你喜欢
    • 2017-09-11
    • 2017-06-28
    • 1970-01-01
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多