2016-04-11 14 views
0

現在、Spring(Boot)と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 ...] 
} 

私はH2を使用して、アプリケーションの起動

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

上のデータを挿入するためにCRUDRepository

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

を使用しています:私は、次の2つのエンティティを持っていますコンソール、私はテーブルが生成され空です。しかし、orderRepository.save(order)を呼び出すと、DataIntegrityViolationExceptionが発生します。テーブルが空である

  1. 同じキーを持つ2つのエンティティをマージする必要があります保存私はIDと
  2. としてUUIDを使用しています
  3. 、:として

    これは私には非常に奇妙なようです。

完全なスタックトレース:http://pastebin.com/gYk2ZvP4

答えて

0

flushまたはcommitが発行されるまで、ちょうどsave変更を使用すると、データベースには適用されませんしながら、saveAndFlush変更は、即座にDBにフラッシュされると、代わりにorderRepository.save(order);orderRepository.saveAndFlush(order);を使用してみてください。

+0

これはCRUDRepositoryなので、flush()メソッドやsaveAndFlush()メソッドはありません。私はそれをJPARepositoryに変更しようとしましたが、上記の方法を使用しましたが、Exceptionは同じままです。 –

+0

@ 3vIL_VIrUsあなたは正しいデータベースをチェックしていますか? –

+0

私はそれがアプリケーションに利用できる唯一のものであり、テーブルが生成されるので、正しいものと仮定します。 –

関連する問題