简体   繁体   English

Spring:分离的实体传递给持久化

[英]Spring: detached entity passed to persist

It is a short time that I'm studying Spring,I'm a student I have problems with dependency injection.我学习Spring的时间很短,我是一个学生,我有依赖注入的问题。 In this project I have this error code in the method acquista.Why?在这个项目中,我在方法 acquista.Why 中有这个错误代码? Acquista in english is translated in "buy".If my Carrello (cart) is composed by more than one Articolo(Article) , in ArticoliOrdine(ArticlesOrder) I have only the first of them.Why?How can I solve it? Acquista 英文翻译成“buy”。如果我的 Carrello(购物车)由多个 Articolo(Article) 组成,在 ArticoliOrdine(ArticlesOrder) 中我只有第一个。为什么?我该如何解决?

Error code:错误代码:

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

Ordine.java顺序.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

CarrelloController.java卡雷洛控制器.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

}//CarrelloController }//卡雷罗控制器

ApplicationContext.xml应用上下文.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"/>

You are not approaching this the right way.你没有以正确的方式解决这个问题。 Your entities shouldn't be treated as Spring Beans . 您的实体不应被视为 Spring Beans

@Autowired
private ArticoliOrdine articoliOrdine;

...

em.persist(articoliOrdine);

For long conversations you should either use:对于长时间的对话,您应该使用:

  • Extended persistence context扩展持久化上下文
  • detached objects saved in your Http Session保存在 Http Session 中的分离对象

And detached entities shouldn't be passed to persist.不应该将分离的实体传递给持久化。 You should merge them instead.你应该合并它们。

Persist is only meant for moving an entity state from TRANSIENT to PERSISTED . Persist 仅用于将实体状态从 TRANSIENT 移动到 PERSISTED For DETACHED -> PERSISTED transitions you should always use EntityManager#merge() or Hibernate specific saveOrUpdate .对于 DETACHED -> PERSISTED 转换,您应该始终使用EntityManager#merge()或 Hibernate 特定的saveOrUpdate

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM