簡體   English   中英

Spring:分離的實體傳遞給持久化

[英]Spring: detached entity passed to persist

我學習Spring的時間很短,我是一個學生,我有依賴注入的問題。 在這個項目中,我在方法 acquista.Why 中有這個錯誤代碼? Acquista 英文翻譯成“buy”。如果我的 Carrello(購物車)由多個 Articolo(Article) 組成,在 ArticoliOrdine(ArticlesOrder) 中我只有第一個。為什么?我該如何解決?

錯誤代碼:

 Grave: Servlet.service() for servlet [applicationContext] in context with path  [/SpringStore] threw exception [Request processing failed; nested exception is  javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: bean.Ordine] with root cause
org.hibernate.PersistentObjectException: detached entity passed to persist: bean.Ordine
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:811)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:289)
at com.sun.proxy.$Proxy37.persist(Unknown Source)
at daoJPA.CarrelloDAOImpl.acquista(CarrelloDAOImpl.java:130)     

CarrelloDAOImpl.java

@Transactional
 public class CarrelloDAOImpl implements CarrelloDAO {

@PersistenceContext
private EntityManager em;

@Autowired
Carrello carrello;

@Autowired
private ArticoliOrdine articoliOrdine;

@Autowired
private Ordine ordine;


public void acquista(Cliente c){

    ordine.setIdCliente(c);
    ordine.setData(new Date(System.currentTimeMillis()));
    ordine.setStato("In lavorazione");
    em.persist(ordine);

    Set<String> lista_articoli=carrello.getMappa_Articoli().keySet();
    synchronized(lista_articoli){
        Iterator<String> it=lista_articoli.iterator();
        while(it.hasNext()){
            String codice=it.next();
            System.out.println("codice: "+codice);
            Query q=em.createQuery("SELECT a FROM Articolo a WHERE a.codice =:codice");
            q.setParameter("codice", codice);
            Articolo a =(Articolo)q.getSingleResult();
            ArticoliOrdinePK pk=articoliOrdine.getArticoliordinePK();
            pk.setIdArticolo(a.getId());
            pk.setIdOrdine(ordine.getId());
            articoliOrdine.setArticolo(a);
            articoliOrdine.setQuantita(carrello.getMappa_Articoli().get(codice));
            em.persist(articoliOrdine);

            //aggiorno la quantita' dell'articolo
            Articolo articolo_update=em.find(Articolo.class,a.getId());
            articolo_update.setQuantita(articolo_update.getQuantita()- articoliOrdine.getQuantita());
        }//while        
    }//syncronized
}//acquista

}//CarrelloDAOImpl

順序.java

@Table(name="ordine")
@Entity
public class Ordine implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private Integer id;

@Temporal(TemporalType.TIMESTAMP)
@Column(name="data")
private Date data;

@Column(name="stato")
private String stato;

@ManyToOne(optional=false)
@JoinColumn(name="idCliente",referencedColumnName="id")
private Cliente idCliente;

@OneToMany(mappedBy="ordine",cascade=CascadeType.ALL,fetch=FetchType.LAZY)
Collection<ArticoliOrdine> articoliordineCollection;

public Ordine() {
}

public Ordine(Integer id) {
    this.id = id;
}

public Ordine(Integer id, Date data, String stato) {
    this.id = id;
    this.data = data;
    this.stato = stato;
}

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}


public Date getData() {
    return data;
}

public void setData(Date data) {
    this.data = data;
}

public String getStato() {
    return stato;
}

public void setStato(String stato) {
    this.stato = stato;
}


public Cliente getIdCliente() {
    return idCliente;
}

public void setIdCliente(Cliente idCliente) {
    this.idCliente = idCliente;
}

public Collection<ArticoliOrdine> getArticoliordineCollection() {
    return articoliordineCollection;
}

public void setArticoliordineCollection(
        Collection<ArticoliOrdine> articoliordineCollection) {
    this.articoliordineCollection = articoliordineCollection;
}

@Override
public boolean equals(Object o){
    if(! (o instanceof Ordine) )
        return false;
    Ordine ordine=(Ordine)o;
    return ordine.id==this.id;
}//equals

public String toString(){
    return id+" cliente:"+idCliente.getId();
}//toString



}//Ordine

卡雷洛控制器.java

@Controller
public class CarrelloController {

@Autowired
CarrelloDAO carrelloDAO;

@Autowired
Carrello carrello;

...

@RequestMapping(value="/acquista",method=RequestMethod.POST)
public String acquista(HttpServletRequest request,ModelMap model){
    HttpSession session=request.getSession();
    Cliente cliente=(Cliente)session.getAttribute("cliente");
    carrelloDAO.acquista(cliente);
    carrello.svuotaCarrello();
    model.addAttribute("num_articoli",carrello.contaArticoliCarrello());
    model.addAttribute("totale_carrello",carrello.getTotale());
    return "redirect:/";
}//checkOut

}//卡雷羅控制器

應用上下文.xml

<bean  class="daoJPA.ClienteDAOImpl" id="clienteDAO"/>

<bean  class="daoJPA.ArticoloDAOImpl" id="articoloDAO"/>

<bean class="bean.Carrello" id="carrello" scope="session">
    <aop:scoped-proxy/>
</bean>

<bean class="daoJPA.CarrelloDAOImpl" id="carrelloDAO"/>

<bean class="bean.ArticoliOrdine" id="articoliOrdine" scope="prototype">
    <property name="articoliordinePK">
        <bean class="bean.ArticoliOrdinePK" id="articoliOrdinePK" scope="prototype"/>
    </property>
</bean>

<bean class="bean.Ordine" id="ordine" scope="prototype"/>

你沒有以正確的方式解決這個問題。 您的實體不應被視為 Spring Beans

@Autowired
private ArticoliOrdine articoliOrdine;

...

em.persist(articoliOrdine);

對於長時間的對話,您應該使用:

  • 擴展持久化上下文
  • 保存在 Http Session 中的分離對象

不應該將分離的實體傳遞給持久化。 你應該合並它們。

Persist 僅用於將實體狀態從 TRANSIENT 移動到 PERSISTED 對於 DETACHED -> PERSISTED 轉換,您應該始終使用EntityManager#merge()或 Hibernate 特定的saveOrUpdate

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM