2012-08-05 208 views
0

當我試圖堅持父實體,它堅持罰款,但是當我嘗試子實體,它返回一個錯誤。多對一關係不要堅持

這是父實體

@Entity(name="Parent_Detail") 
public class Parent implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Column(name = "Parent_ID", nullable = false) 
    private Integer parent_id; 

    public Integer getParent_id() { 
     return parent_id; 
    } 

    public void setParent_id(Integer parent_id) { 
     this.parent_id = parent_id; 
    } 


} 

這是子實體

@Entity 
public class Child implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Column(name = "Child_ID", nullable = false) 
    private Integer child_id; 

    @ManyToOne 
    private Parent parent; 

    public Integer getChild_id() { 
     return child_id; 
    } 

    public void setChild_id(Integer child_id) { 
     this.child_id = child_id; 
    } 

    public Parent getParent() { 
     return parent; 
    } 

    public void setParent(Parent parent) { 
     this.parent = parent; 
    } 






} 

這是孩子的會話bean

@Stateless 
@LocalBean 
public class ChildSessionBean { 
    @PersistenceContext(unitName = "WebApplication4PU") 
    private EntityManager em; 

    public void persist(Object object) { 
     em.persist(object); 
    } 





} 

這是使sesion豆對於家長(它工作正常)

@Stateless 
@LocalBean 
public class ParentSessionBean { 
    @PersistenceContext(unitName = "WebApplication4PU") 
    private EntityManager em; 

    public void persist(Object object) { 
     em.persist(object); 
    } 



} 

這是管理bean爲孩子

public class ChildManagedBean { 
    @EJB 
    private ChildSessionBean childSessionBean; 
    private Child child = new Child(); 

    public ChildManagedBean() { 
    } 

    public Child getChild() { 
     return child; 
    } 

    public void setChild(Child child) { 
     this.child = child; 
    } 
    public void save(){ 
     child.setParent(new Parent()); 
     childSessionBean.persist(child); 
    } 
} 

這是managedBean父

public class ParentManagedBean { 
    @EJB 
    private ParentSessionBean parentSessionBean; 
    private Parent parent = new Parent(); 


    public ParentManagedBean() { 
    } 

    public Parent getParent() { 
     return parent; 
    } 

    public void setParent(Parent parent) { 
     this.parent = parent; 
    } 
    public void save(){ 
     parentSessionBean.persist(parent); 
    } 
} 

這是孩子JSF頁面:我一直是簡單的沒有下拉。

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html"> 
    <h:head> 
     <title>Facelet Title</title> 
    </h:head> 
    <h:body> 
     <h:form> 
      Child ID :<h:inputText value="#{childManagedBean.child.child_id}" /><br/> 
      Parent ID :<h:inputText value="#{childManagedBean.child.parent}" /><br/> 
      <h:commandButton action="#{childManagedBean.save()}" immediate="true"/> 
     </h:form> 
    </h:body> 
</html> 

這是錯誤頁

javax.faces.el.EvaluationException: javax.ejb.EJBException: Transaction aborted 
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102) 
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) 
    at javax.faces.component.UICommand.broadcast(UICommand.java:315) 
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) 
    at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:935) 
    at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78) 
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) 
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) 
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1542) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) 
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) 
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161) 
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) 
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849) 
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746) 
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1045) 
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228) 
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) 
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) 
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) 
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) 
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) 
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) 
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71) 
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) 
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) 
    at java.lang.Thread.run(Thread.java:636) 
Caused by: javax.ejb.EJBException: Transaction aborted 
    at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5142) 
    at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4901) 
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2045) 
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994) 
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222) 
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88) 
    at $Proxy402.persist(Unknown Source) 
    at SessionBean.__EJB31_Generated__ChildSessionBean__Intf____Bean__.persist(Unknown Source) 
    at managedBean.ChildManagedBean.save(ChildManagedBean.java:33) 
    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:616) 
    at javax.el.BeanELResolver.invokeMethod(BeanELResolver.java:779) 
    at javax.el.BeanELResolver.invoke(BeanELResolver.java:528) 
    at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:257) 
    at com.sun.el.parser.AstValue.invoke(AstValue.java:248) 
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:302) 
    at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:39) 
    at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50) 
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) 
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) 
    ... 32 more 
Caused by: javax.transaction.RollbackException: Transaction marked for rollback. 
    at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:473) 
    at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.commit(JavaEETransactionManagerSimplified.java:855) 
    at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5136) 
    ... 53 more 
Caused by: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: [email protected] 
    at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.discoverUnregisteredNewObjects(RepeatableWriteUnitOfWork.java:304) 
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:702) 
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1490) 
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:3143) 
    at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:346) 
    at org.eclipse.persistence.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:157) 
    at org.eclipse.persistence.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:68) 
    at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:435) 
    ... 55 more 

回答

1

異常消息說,這一切:

During synchronization a new object was found through a relationship that was not marked cascade PERSIST: [email protected] 

你試圖堅持一個孩子。而孩子的父母是新的父母。父母不持久。所以你試圖堅持一個不持久的父母的孩子。它不能工作。

無論你想要的是保存一個新的孩子現有的父,然後你必須在這個目前家長重視孩子:

Parent existingParent = em.getReference(Parent.class, existingParentId); 
Child child = new Child(); 
child.setParent(existingParent); 
em.persist(child); 

還是要保存一個新的孩子一個新的父在一個去,你必須堅持的父母,那麼孩子:

Parent parent = new Parent(); 
Child child = new Child(); 
child.setParent(existingParent); 
em.persist(parent); 
em.persist(child); 

或者你想用一個新的父保存在一個去一個新的孩子,讓JPA自動持續家長當孩子堅持,然後你必須使堅持級聯

@ManyToOne(cascade = CascadeType.PERSIST) 
private Parent parent; 

... 

Parent parent = new Parent(); 
Child child = new Child(); 
child.setParent(existingParent); 
em.persist(child);