2016-04-11 3 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 ...] 
} 

Я использую 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 консоли, я вижу, что таблицы генерируются и пустые. Тем не менее, я получаю DataIntegrityViolationException при вызове orderRepository.save (order).

Это кажется мне очень странным, как:

  1. столы пустуют,
  2. Я использую UUID, как идентификаторы и
  3. сохранить должны объединить два объекта с тем же ключом.

Полный StackTrace: http://pastebin.com/gYk2ZvP4

ответ

0

Попробуйте использовать orderRepository.saveAndFlush(order); вместо orderRepository.save(order); с saveAndFlush изменения будут сброшены в БД немедленно, в то время как, используя только save изменения не будут применяться к базе данных до flush или commit выпускаются ,

+0

Поскольку это CRUDRepository, он не имеет методов flush() или saveAndFlush(). Я попытался изменить его на JPARepository и использовать указанные методы, но Exception остается прежним. –

+0

@ 3vIL_VIrUs Вы уверены, что проверяете правильную базу данных? –

+0

Я предполагаю, что он правильный, так как его единственный доступный для приложения и таблицы генерируются –

Смежные вопросы