当我尝试持久化父实体时,它仍然存在,但是当我尝试子实体时,它会返回错误。
这是父实体
@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 Bean(它工作正常)
@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);
}
}
这是Child 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: bean.Parent@13d247e.
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
答案 0 :(得分:1)
异常消息说明了一切:
During synchronization a new object was found through a relationship that was not marked cascade PERSIST: bean.Parent@13d247e
你想要坚持一个孩子。孩子的父母是新的父母。父不是持久的。因此,你试图坚持一个没有持久性的父母的孩子。它无法运作。
您想要的是为现有父级保存新子级,然后您必须将此现有父级附加到子级:
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);