【问题标题】:DataIntegrityViolationException: same identifier using CRUDRepositoryDataIntegrityViolationException:使用 CRUDRepository 的相同标识符
【发布时间】:2016-04-11 12:31:42
【问题描述】:

我目前正在使用 Spring (Boot) 和 JPA 开发应用程序。我有以下两个实体:

@Entity
@AccessType(AccessType.Type.PROPERTY)
@Table(name = "T_ORDER")
public class Order {
    @Id
    private String id;
    @Version
    private Integer version = 0;
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "order", cascade = CascadeType.ALL)
    private List<Item> items = new ArrayList<>();

    private String text;
    private String status;

    @Deprecated
    public Order() {}

    public static Order newOrder() {
        Order order = new Order();
        order.id = UUID.randomUUID().toString();
        return order;
    }

    [... getters and setters ...]

    [... equals and hashCode ...]
}

@Entity
@Table(name = "T_ITEM")
@IdClass(Item.ItemId.class)
public class Item {
    public static class ItemId implements Serializable {
        public String order;
        public String id;
        [... equals and hashcode ...]
    }

    @Id
    @JsonIgnore
    @ManyToOne(cascade = CascadeType.PERSIST)
    private Order order;
    @Id
    private String id;
    @Version
    private int version = 0;
    @Transient
    private Product product;
    private Integer productId;
    private BigDecimal quantity;
    private String quantityUnit;
    private BigDecimal price;

    [... getters and setters ...]
    [... equals and hashcode ...]
}

我正在使用 CRUDRepository

@Repository
public interface OrderRepository extends CrudRepository<Order, String> {
    @Transactional
    List<Order> removeByStatus(String status);
}

在应用程序启动时插入数据

@Component
public class OrderLoader implements ApplicationListener<ContextRefreshedEvent> {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    private OrderRepository orderRepository;

    @Autowired
    public void setOrderRepository(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }

    @Override
    @Transactional(readOnly = false)
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        try {
            Order order = Order.newOrder();

            for (int itemId = 1; itemId < 3; itemId++) {
                Item item = order.addItem();
                item.setProductId(1);
            }

            order.setText("this is an order");
            order.setStatus("delivered");

            orderRepository.save(order);
        } catch (Exception e) {
            logger.error("This shit...", e);
        }
    }
}

使用 H2 控制台,我可以看到正在生成的表是空的。但是,在调用 orderRepository.save(order) 时,我得到了 DataIntegrityViolationException。

这对我来说似乎很奇怪:

  1. 表格是空的,
  2. 我使用 UUID 作为 ID 和
  3. 保存应合并具有相同键的两个实体。

完整的堆栈跟踪:http://pastebin.com/gYk2ZvP4

【问题讨论】:

    标签: java spring hibernate jpa crud


    【解决方案1】:

    尝试使用orderRepository.saveAndFlush(order); 而不是orderRepository.save(order);saveAndFlush 更改将立即刷新到数据库,而仅使用save 更改将不会应用于数据库,直到发出flushcommit .

    【讨论】:

    • 因为这是一个 CRUDRepository,它没有 flush() 或 saveAndFlush() 方法。我尝试将其更改为 JPARepository 并使用上述方法,但异常保持不变。
    • @3vIL_VIrUs 你确定你检查的是正确的数据库吗?
    • 我认为它是正确的,因为它是应用程序唯一可用的,并且表格会生成
    • @3vIL_VIrUs 你能在 saveAndFlush 之前记录下你的 Order id
    • sure: 628adb3f-e357-4c25-bb09-9b6732c770c7 当然,因为这是一个 UUID,它每次都会改变。我还检查了项目 ID,它们也设置正确。
    猜你喜欢
    • 2019-05-28
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-03
    • 2020-08-22
    • 2012-08-23
    相关资源
    最近更新 更多