2013-08-22 2 views
0

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

Répondre

0

Essayez de changer int à Integer

private Integer orderId; 

et accesseurs ainsi.

+0

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

0

Vous mentionnez l'article est attribué une valeur d'identité par la base de données, mais il a manqué l'annotation @GeneratedValue (stratégie = GenerationType.IDENTITY) que vous avez sur commande. C'est ce qui indique à JPA que la base de données contrôle la valeur, sinon elle attend que l'application la définisse, en la gardant par défaut 0.

0

après avoir appelé em.persist (obj), appelez em.flush(); Ça devrait marcher.

mieux d'avoir une méthode privée sauvegarde comme

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