TopLink 实体管理器无法正确保存对象



非常感谢任何帮助(至少在如何追踪问题根本原因方面),因为我已经为此斗争了好几天,甚至没有找到解决方法。

问题本身:我有几个实体,它们都很好用-persist()、find()等。除了一个方法,我创建了两个不同的实体(Order和Items,一个订单可以有很多Items)。调用em.persist(..)后,订单被保存,我看到它的id是由DB生成的,项目被保存到DB中(我直接在DB中通过SELECT看到它),但它显示id=0。无论我做什么,它总是0(例如,当我打开订单时,我仍然看到它的ID=0),直到我重新启动服务器,然后它显示项目的正确ID。方法代码(在日志记录后,我添加了我得到的实际值):

public void createOrderFromItems(ArrayList<TehnomirItemDTO> items, User user) {
    Order ord = new Order();
    User managers = getUserByEmail(Constants.ALL_MANAGERS_GROUP);
    ord.setAssignedTo(managers);
    Date date = new Date();
    ord.setCreatedOn(date);
    User customer = user;
    ord.setCustomer(customer);
    BigDecimal custBalance = new BigDecimal(0);
    ArrayList<Balance> balances = getBalanceForUser(customer);
    for (Balance b:balances) {
        custBalance.add(b.getAmount());
    }
    logger.debug("before1. order: "+ord.getOrderId()); //here I get 0
    em.persist(ord);
    logger.debug("before2. order: "+ord.getOrderId()); //still 0
    State new_state = getStateByName(SharedConstants.STATE_NEW);
    logger.debug("before3. order: "+ord.getOrderId()); //here I get actual ID, generated by DB, e.g. 189
    State overpriced = getStateByName(SharedConstants.STATE_LIMIT_EXCEEDED);
    ArrayList<Item> itemList = new ArrayList<Item>();
    for (TehnomirItemDTO tid:items) {
        Item item = new Item(tid);
        item.setOrder(ord);
        logger.debug("order inside2:"+ord.getOrderId()); //again, actual ID
        item.setPriceInt(tid.getPrice_int());
        custBalance = custBalance.subtract(item.getPriceInt());
        if (custBalance.floatValue()>0) {
            item.setStateBean(new_state);
        } else item.setStateBean(overpriced);       
        logger.debug("item before:"+item.getItemId()); //here I get 0
        em.persist(item);
        item = em.merge(item);
        em.setFlushMode(FlushModeType.COMMIT);//added just in case it would work but it didn't
        em.flush();//same as previous line
        Item tst = getItemByID(1);
        logger.debug("item after:"+item.getItemId()+"  ord:"+ord.getOrderId()); //again, orderID is correct, itemID is 0
        itemList.add(item);
    }
    ord.setItems(itemList);
    State new_state2 = getStateByName(SharedConstants.STATE_NEW);
    logger.debug(ord.getItems().get(0).getItemId()+" order: "+ord.getOrderId());//again, orderID is correct, itemID is 0
}

订单类别:

@Entity
@Table(name="orders")
public class Order implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY/*,     generator="ORDERS_ORDERID_GENERATOR"*/)
    @Column(name="ORDER_ID")
    private int orderId;
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name="CREATED_ON")
    private Date createdOn;
    //bi-directional many-to-one association to Item
    @OneToMany(mappedBy="order")
    private List<Item> items;

    //uni-directional many-to-one association to User
    @ManyToOne
    @JoinColumn(name="ASSIGNED_TO")
    private User assignedTo;
    //uni-directional many-to-one association to User
    @ManyToOne
    @JoinColumn(name="CUSTOMER")
    private User customer;
    public Order() {
    }
    public int getOrderId() {
        return this.orderId;
    }
}

项类(删除getter和setter以使其更可读):@实体@表(name="items")公共类Item实现Serializable{private static最终长serialVersionUID=1L;

    @Id
    @Column(name="ITEM_ID")
    private int itemId;
    private String code;
    private BigDecimal weight;
    public BigDecimal getWeight() {
        return weight;
    }
    public void setWeight(BigDecimal weight) {
        this.weight = weight;
    }
    private String comments;//any additional info user'd like to add
    private String description;
    @Column(name="EXT_ID")
    private int extId;
    private String manufacturer;
    @Column(name="PRICE_EXT")
    private BigDecimal priceExt;
    @Column(name="PRICE_INT")
    private BigDecimal priceInt;
    private String region;
    private String term;
    //bi-directional many-to-one association to Order
    @ManyToOne(cascade=CascadeType.PERSIST)
    @JoinColumn(name="ORDER_ID")
    private Order order;
    //bi-directional many-to-one association to State
    @ManyToOne
    @JoinColumn(name="STATE")
    private State state;
}

我对缓存有一些想法,所以我在persistence.xml行中添加了

property name="toplink.cache.type.default" value="NONE"
property name="toplink.cache.type.Order" value="NONE"

但这对也没有帮助

尝试将int更改为Integer

private Integer orderId;

以及getter和setter。

您提到Item由数据库分配了一个ID值,但错过了订单上的@GeneratedValue(策略=GenerationType.IDENTITY)注释。这就是告诉JPA,数据库控制该值,否则它希望应用程序设置该值,使其保持默认的0。

调用em.persist(obj)后,调用em.flush();。它应该起作用。

最好保存一个私有方法像

private void save(object obj)
{
    em.persist(obj);
    em.flush();
}

相关内容

  • 没有找到相关文章

最新更新