2013-08-22 1 views
0

Действительно оцените любую помощь (по крайней мере, как проследить основную причину проблемы), потому что я боролся с этим несколько дней и не нашел даже обходного пути.TopLink EntityManager не сохраняет объект должным образом

Проблема сама: у меня есть несколько сущностей, все они работают хорошо - persist(), find() и т. Д., За исключением одного метода, когда я создаю два разных объекта (порядок и элементы, один заказ может иметь много элементов) , После вызова em.persist (..) порядок сохраняется, и я вижу его идентификатор, сгенерированный БД, элемент сохраняется в БД (я вижу его через SELECT непосредственно в БД), но он показывает ID = 0. И что бы я ни делал, всегда 0 (например, когда я открываю порядок, я все еще вижу его ID = 0), пока я не перезапущу сервер, - тогда он показывает правильный идентификатор элемента. код метода (после регистрации я добавил фактические значения я): класс

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

} 

класс Item (удаленные методы получения и установки, чтобы сделать его более удобным для чтения): @Entity @Table (name = "items") public class Item реализует Serializable { закрытый статический окончательный длинный 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" 

но это не помогло

ответ

0

Попробуйте изменить int к Integer

private Integer orderId; 

и геттеры и сеттеры.

+0

Спасибо, но это не помогает. Во всяком случае, Order (и другие объекты) имеет int как id, и он работает. К настоящему моменту я добавил метод, который находит максимальный идентификатор из элементов и задает увеличенное значение как ItemID до его сохранения, он работает, но он настолько уродлив, что мои глаза истекают кровью, когда я вижу это :) – user2676881

0

Вы упомянули аннотацию @GeneratedValue (strategy = GenerationType.IDENTITY), которую вы указали при заказе. Это то, что говорит JPA, db управляет значением, в противном случае он ожидает, что приложение установит его, сохраняя его по умолчанию 0.

0

после вызова em.persist (obj), вызов em.flush() ;. Он должен работать.

лучше иметь частный метод сохранения как

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