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

时间:2014-11-30 13:22:38

标签: java spring hibernate jpa orm

我正在学习春天,我是一名学生 我有依赖注入的问题。在这个项目中,我在方法acquista中有这个错误代码。为什么?英语中的Acquista翻译为“buy”。如果我的Carrello(购物车)由一个以上的Articolo(文章)组成,在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

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

@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

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

1 个答案:

答案 0 :(得分:1)

你做错了。 Your entities shouldn't be treated as Spring Beans

@Autowired
private ArticoliOrdine articoliOrdine;

...

em.persist(articoliOrdine);

对于long conversations,您应该使用:

  • 扩展持久化上下文
  • 保存在Http Session中的分离对象

不应传递分离的实体以保持持久性。你应该合并它们。

坚持仅适用于moving an entity state from TRANSIENT to PERSISTED。对于DETACHED - &gt; PERSISTED转换应始终使用EntityManager#merge()或Hibernate特定saveOrUpdate