如何解决javax.persistence.EntityExistsException:具有相同标识符值的另一个对象已与会话

时间:2015-12-18 13:28:06

标签: java hibernate jpa entitymanager

我使用迭代来保存Collection中的所有实体。然后我有这个问题。我尝试了persist()merge(),但似乎实体的ID从未改变过。 如果有人能提供帮助,我将不胜感激。

我的道歉

@Repository
public class SaleOrderDAOImpl implements SaleOrderDAO{

    @PersistenceContext
    private EntityManager em;

    @Override
    public void save(SaleOrder sale) {
        // TODO Auto-generated method stub
        if(sale.getId() == null)em.persist(sale);
        else
             em.merge(sale);
    }

    @Override
    public SaleOrder getById(Integer id) {
        // TODO Auto-generated method stub
        return em.find(SaleOrder.class,id );
    }

}

相关功能

@Override
    public Set<SaleOrder> generateOrder(Integer cus_id) {
        // TODO Auto-generated method stub
        Set<SaleOrder> orders = new HashSet<>();
        Customer consumer = (Customer) userDAO.findUserById(cus_id);
        if(consumer == null) throw new NullPointerException();
        Cart cart = consumer.getCart();
        System.out.println(cart);
        if(cart == null) return null;

        // 生成订单

        SaleOrder fake = new SaleOrder();
        fake.setProvider(new Artist());
        orders.add(fake);
        boolean flag = false;
        for(CartItem item :cart.getItems()){
            Artist seller = item.getProduct().getSeller();
            flag = false;
            while(true){
                for(SaleOrder order:orders)
                if(order.getProvider().equals(seller))order.getItems().add(item);
                else{
                    SaleOrder another = new SaleOrder();
                    another.getItems().add(item);
                    another.setProvider(seller);
                    another.setConsumer(consumer);
                    orders.add(another);
                    flag = true;
                    break;
                }
                if(flag == true) break;
            }
        }
        orders.remove(fake);
        Iterator iter = orders.iterator();
        SaleOrder order;
        while(iter.hasNext()){
            order = (SaleOrder) iter.next();
            order.calcTotal();
            soDAO.save(order); // call SaleOrderDAO, and problem occurs here.
        }

        // 清空购物车

        cart.Empty();

        return orders;
    }

我的SaleOrder课程

@Entity
@Table(name ="myorder")
@DiscriminatorValue("Sale")
public class SaleOrder extends Order {

//  private List<Feedback> feedbacks;


    @OneToMany(mappedBy="order")
    private Set<CartItem> items;

    @OneToOne(cascade = CascadeType.ALL,mappedBy="order")
    private Payment payment;


    private Double total;

    // constructor

    public SaleOrder(){
        this.setStatus("Unpaid");
    }


    // BusinessLogic

    public void calcTotal(){
        Double total = 0.0;
        for(CartItem item:items){
            total+= item.getProduct().getPrice()*item.getQuantity();
        }
        this.total=total;
    }

    public void changeStatus(){
        if(payment.isPaid())this.setStatus("Paid");
    }

    @Override 
    public void specify(){
        super.specify();
        total += this.getShipment().getPrice();
        this.payment = new Payment(total);
    }

我的Order.class

@Entity
@Table(name = "myorder")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Order{


    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @ManyToOne( fetch = FetchType.LAZY)
    @MapsId
    @JoinColumn(name = "consumer_id")
    private Customer consumer; // 下订单的人

    @ManyToOne(fetch = FetchType.LAZY)
    @MapsId
    @JoinColumn(name = "provider_id")
    private Artist provider; // 即卖家

    private String status;

    @OneToOne(targetEntity = Address.class,fetch = FetchType.EAGER)
    private Address addr;

    @Column(columnDefinition = "timestamp on update current_timestamp")
    private Timestamp orderDate;

    @OneToOne(cascade = CascadeType.ALL,targetEntity = Shipment.class,fetch = FetchType.EAGER)
    private Shipment shipment;

    // Business Logic

    /**
     * 生成最终订单
     */
    public void specify(){};

    /**
     * 更改订单支付状态
     */
    public void changeStatus(){};


    // getters and setters

提前感谢。

2 个答案:

答案 0 :(得分:0)

虽然我没有SaleOrder课程,但我想有两件事:

1)id类型为String并初始化为&#34;&#34;。在这种情况下,请确保将其初始化为null

2)id类型是int或primary类型。在这种情况下,我建议将其更改为类似Integer的Object类型,然后将其初始化为null。

答案 1 :(得分:0)

您可以尝试在@Transactional方法上添加注释save()