apprécier vraiment de l'aide (au moins des moyens comment tracer la cause racine du problème) parce que je me bats avec cela pendant plusieurs jours et n'a pas trouvé même solution. Le problème lui-même: J'ai quelques entités, toutes fonctionnent bien - persist(), find() etc. sauf une méthode où je crée deux entités différentes (Order et Items, une commande peut avoir plusieurs items) . Après avoir appelé em.persist (..) la commande est sauvegardée et je vois son identifiant généré par DB, l'item est sauvegardé dans DB (je le vois directement via SELECT dans DB) mais il montre ID = 0. Et tout ce que je fais toujours 0 (par exemple quand j'ouvre la commande je vois toujours son ID = 0) jusqu'à ce que je redémarre le serveur - alors il montre l'ID correct de l'article. Code de la méthode (après la coupe, j'ai ajouté des valeurs réelles que je reçois):TopLink EntityManager ne sauvegarde pas correctement l'objet
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
}
Commander Classe:
@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;
}
}
classe d'objet (retiré accesseurs pour le rendre plus lisible): @Entity @Table (name = "items") public class article implémente Serializable {private static finale longue serialVersionUID = 1 litre;
@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;
}
J'ai eu quelques réflexions sur la mise en cache alors j'ai ajouté à mes lignes persistence.xml
property name="toplink.cache.type.default" value="NONE"
property name="toplink.cache.type.Order" value="NONE"
mais il n'a pas aidé non
Merci, mais il ne vous aide pas. Quoi qu'il en soit, Order (et d'autres entités) a int comme ID et cela fonctionne. A ce jour, j'ai ajouté une méthode qui trouve l'identifiant maximum des items et la valeur incrémentée en itemID avant de persister, ça marche mais c'est tellement moche que mes yeux saignent quand je le vois :) – user2676881