Really appreciate ANY help (at least ways how to trace root cause of the problem) because I've been fighting with this for several days and didn't find even workaround.
The problem itself: I have a few entities, all of them work good - persist(), find() etc. except one method where I create two different entities (Order and Items, one order can have many Items). After calling em.persist(..) order is saved and I see its id generated by DB, item is saved to DB (I see it through SELECT directly in DB) but it shows ID=0. And whatever I do it always 0 (e.g. when I open the order I still see its ID=0) until I restart server - then it shows correct ID of item. Code of the method (after logging I added actual values I get):
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
}
Order class:
@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 class (removed getters and setters to make it more readable): @Entity @Table(name="items") public class Item implements Serializable { private static final long 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;
}
I had some thoughts about caching so I added to my persistence.xml lines
property name="toplink.cache.type.default" value="NONE"
property name="toplink.cache.type.Order" value="NONE"
but it didn't help either
Try to change
int
toInteger
and getters and setters as well.