Not-null属性引用瞬态值 - 必须在当前操作之前保存瞬态实例

时间:2016-01-27 15:24:50

标签: spring hibernate model-view-controller

这是日志异常:

Structure

方案如下:我有两个实体bean Prestito和PrestitoLibro,一个ServicePrestito和一个带控制器的会话bean ShoppingCard:

GRAVE: Servlet.service() for servlet [dispatcher] in context with path [/Libreria] threw exception [Request processing failed; nested exception is org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : com.angelo.springmvc.model.PrestitoLibro.prestito -> com.angelo.springmvc.model.Prestito] with root cause
org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : com.angelo.springmvc.model.PrestitoLibro.prestito -> com.angelo.springmvc.model.Prestito
    at org.hibernate.action.internal.UnresolvedEntityInsertActions.checkNoUnresolvedActionsAfterOperation(UnresolvedEntityInsertActions.java:137)
    at org.hibernate.engine.spi.ActionQueue.checkNoUnresolvedActionsAfterOperation(ActionQueue.java:318)
    at org.hibernate.internal.SessionImpl.checkNoUnresolvedActionsAfterOperation(SessionImpl.java:658)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:813)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:784)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:789)
    at com.angelo.springmvc.dao.AbstractDao.persist(AbstractDao.java:34)
    at com.angelo.springmvc.dao.PrestitoLibroDaoImpl.savePrestitoLibro(PrestitoLibroDaoImpl.java:27)
    at com.angelo.springmvc.service.PrestitoServiceImpl.salvaPrestito(PrestitoServiceImpl.java:85)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy45.salvaPrestito(Unknown Source)
    at com.angelo.springmvc.controller.ShoppingCartController.ordinaShoppingCart(ShoppingCartController.java:62)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

当我在此处致电@Entity @Table(name="PRESTITO") @XmlRootElement public class Prestito { private Integer id; private Cliente cliente; private Date dataprestito; private Set<PrestitoLibro> prestitolibros = new HashSet<PrestitoLibro>(0); public Prestito() { } public Prestito(Cliente cliente, Date dataprestito) { this.cliente = cliente; this.dataprestito = dataprestito; } public Prestito(Cliente cliente, Date dataprestito, Set<PrestitoLibro> prestitolibros) { this.cliente = cliente; this.dataprestito = dataprestito; this.prestitolibros = prestitolibros; } @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "id", unique = true, nullable = false) public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "id_cliente", nullable = false) public Cliente getCliente() { return this.cliente; } public void setCliente(Cliente cliente) { this.cliente = cliente; } @Temporal(TemporalType.DATE) @Column(name = "dataprestito", nullable = false, length = 10) public Date getDataprestito() { return this.dataprestito; } public void setDataprestito(Date dataprestito) { this.dataprestito = dataprestito; } @OneToMany(fetch = FetchType.LAZY, mappedBy = "prestito") public Set<PrestitoLibro> getPrestitolibros() { return this.prestitolibros; } public void setPrestitolibros(Set<PrestitoLibro> prestitolibros) { this.prestitolibros = prestitolibros; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Prestito other = (Prestito) obj; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; return true; } @Override public String toString() { return "Prestito [id=" + id + ", cliente=" + cliente + ", dataprestito=" + dataprestito + ", prestitolibros=" + prestitolibros + "]"; } } @Entity @Table(name="PRESTITOLIBRO") @XmlRootElement public class PrestitoLibro { private Integer id; private Libro libro; private Prestito prestito; private Integer qta; private Double subtotal; public PrestitoLibro() { } public PrestitoLibro(Libro libro, Prestito prestito) { this.libro = libro; this.prestito = prestito; } public PrestitoLibro(Libro libro, Prestito prestito, Integer qta, Double subtotal) { this.libro = libro; this.prestito = prestito; this.qta = qta; this.subtotal = subtotal; } @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "id", unique = true, nullable = false) public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } @ManyToOne(fetch = FetchType.LAZY)//, cascade=CascadeType.ALL @JoinColumn(name = "id_libro", nullable = false) public Libro getLibro() { return this.libro; } public void setLibro(Libro libro) { this.libro = libro; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "id_prestito", nullable = false) public Prestito getPrestito() { return this.prestito; } public void setPrestito(Prestito prestito) { this.prestito = prestito; } @Column(name = "qta") public Integer getQta() { return this.qta; } public void setQta(Integer qta) { this.qta = qta; } @Column(name = "subtotal", precision = 22, scale = 0) public Double getSubtotal() { return this.subtotal; } public void setSubtotal(Double subtotal) { this.subtotal = subtotal; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; PrestitoLibro other = (PrestitoLibro) obj; if (id != other.id) return false; return true; } @Override public String toString() { return "PrestitoLibro [id=" + id + ", libro=" + libro + ", prestito=" + prestito + ", qta=" + qta + ", subtotal=" + subtotal + "]"; } } @Component @Scope(value=WebApplicationContext.SCOPE_SESSION, proxyMode=ScopedProxyMode.TARGET_CLASS) public class ShoppingCart { private Map<Libro, Integer> contents = new HashMap<>(); public Map<Libro, Integer> getContents() { return contents; } public void setContents(Map<Libro, Integer> contents) { this.contents = contents; } public void addLibro(Libro libro, int count){ if(contents.containsKey(libro)){ contents.put(libro, contents.get(libro)+count); }else{ contents.put(libro,count); } } public void removeLibro(Libro libro){ contents.remove(libro); } public void clearCart(){ contents.clear(); } @Override public String toString() { return "ShoppingCart [contents=" + contents + "]"; } public double getTotalCost(){ double totalcost = 0; int i = 0; for(Libro libro: contents.keySet()){ i = contents.get(libro); totalcost += i * libro.getPrezzo(); } return totalcost; } } 时会出现问题:

salvaprestito()

这是购物车控制器:

@Service("prestitoService")
@Transactional
public class PrestitoServiceImpl implements PrestitoService {

@Autowired
private PrestitoDao dao;

@Autowired
private PrestitoLibroDao daoprestitolibro;


public Prestito findById(int id) {
    return dao.findById(id);
}

public void savePrestito(Prestito prestito) {
    dao.savePrestito(prestito);
}

public void updatePrestito(Prestito prestito) {
    Prestito entity = dao.findById(prestito.getId());
    if(entity!=null){
        entity.setCliente(prestito.getCliente());
        entity.setDataprestito(prestito.getDataprestito());
        entity.setPrestitolibros(prestito.getPrestitolibros());
    }
}

public void deletePrestitoBySss(String sss) {
    dao.deletePrestitoBySss(sss);
}

public List<Prestito> findAllPrestiti() {
    return dao.findAllPrestiti();
}

public Prestito findPrestitoBySss(String sss) {
    return dao.findPrestitoBySss(sss);
}

public boolean isPrestitoSssUnique(Integer id, String sss) {
    Prestito prestito = findPrestitoBySss(sss);
    return ( prestito == null || ((id != null) && (prestito.getId() == id)));
}


public void salvaPrestito(Map<Libro, Integer> shoppingcartContents, Cliente cliente){

    Prestito prestito = new Prestito();
    prestito = dao.findById(prestito.getId());
    prestito.setCliente(cliente);
    dao.savePrestito(prestito);
    for(Entry<Libro, Integer> entry: shoppingcartContents.entrySet()){

        PrestitoLibro prestLibro = new PrestitoLibro(entry.getKey(),prestito);

        prestLibro.setQta(entry.getValue());
        prestLibro.setPrestito(prestito);               prestLibro.setSubtotal(entry.getKey().getPrezzo()*entry.getValue());
        daoprestitolibro.savePrestitoLibro(prestLibro);
        prestito.getPrestitolibros().add(prestLibro);
    }   
}

这些是Daos:

@Controller
public class ShoppingCartController {

private static final Logger logger =       LoggerFactory.getLogger(ShoppingCartController.class);

@Autowired
private LibroService libroservice;

@Autowired
private PrestitoService prestitoservice;

@Autowired
private ShoppingCart shoppingcart;

@RequestMapping(value = { "/shoppingcart/add/{libroId}" }, method = RequestMethod.GET)
public String addtoShoppingCart(@PathVariable("libroId") int libroId, @RequestHeader("referer") String rForm) {

    Libro libro = (Libro) libroservice.findById(libroId);
    shoppingcart.addLibro(libro, 1);
    logger.debug("Aggiunto Libro a carrello" + libro);
    return "redirect:" + rForm;

}

@RequestMapping(value = { "/shoppingcart" }, method = RequestMethod.GET)
public String viewShoppingCart(Model model) {
    model.addAttribute("shoppingcart", shoppingcart);
    return "shoppingcart";
}

@RequestMapping(value = { "/shoppingcart/order" }, method = RequestMethod.POST)
public String ordinaShoppingCart(HttpSession session) {
    if(shoppingcart.getContents().isEmpty()){
        return "redirect:/shoppingcart";
    }else{
        Cliente cliente = (Cliente) session.getAttribute("cliente");
            prestitoservice.salvaPrestito(shoppingcart.getContents(), cliente);
            return "redirect:/shoppingcart";    
    }
}

1 个答案:

答案 0 :(得分:0)

Hibernate只需要id中的Prestito来通过外键将其与PrestitoLibro相关联。我想,您id这里没有prestito

prestLibro.setPrestito(prestito);               
daoprestitolibro.savePrestitoLibro(prestLibro);

尝试输出prestito.getId(),然后再将其设置为prestLibro

如果你真的没有id,原因可能就是这一代策略

@GeneratedValue(strategy = IDENTITY)

@Transactional中您没有PrestitoServiceImpl的交易,因此dao.savePrestito(prestito)根本不会保存prestito。可以在你的问题中添加你的spring xml配置来帮助你。

你在方法中做了一些不必要的东西,所以它应该是

public void salvaPrestito(Map<Libro, Integer> shoppingcartContents, Cliente cliente){

    Prestito prestito = new Prestito();
    prestito.setCliente(cliente);
    dao.savePrestito(prestito);
    for(Entry<Libro, Integer> entry: shoppingcartContents.entrySet()){

        PrestitoLibro prestLibro = new PrestitoLibro(entry.getKey(), prestito);

        prestLibro.setQta(entry.getValue());
        prestLibro.setSubtotal(entry.getKey().getPrezzo() * entry.getValue());
        daoprestitolibro.savePrestitoLibro(prestLibro);
    }   
}

您不需要prestLibro.setPrestito(prestito)prestito.getPrestitolibros().add(prestLibro)