2016-04-11 50 views
0

我目前正在使用Spring(引導)和JPA開發應用程序。我有以下兩個實體:DataIntegrityViolationException:使用CRUDRepository的相同標識符

@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作爲標識和
  3. 保存應合併兩個實體使用相同的密鑰。

完整的堆棧跟蹤:http://pastebin.com/gYk2ZvP4

回答

0

嘗試使用orderRepository.saveAndFlush(order);代替orderRepository.save(order);,與saveAndFlush的變化會立即刷新到數據庫,而只使用save變化不會應用到數據庫中,直到flushcommit發行。

+0

由於這是一個CRUDRepository,它沒有flush()或saveAndFlush()方法。我試圖將其更改爲JPARepository並使用上述方法,但Exception保持不變。 –

+0

@ 3vIL_VIrUs你確定你正在檢查正確的數據庫嗎? –

+0

我認爲它是正確的,因爲它是唯一可用於應用程序和表生成 –

相關問題