一对多关系:无法将值保存到多个副实体中

时间:2014-09-23 01:48:32

标签: java-ee jpa ejb

客户实体

            @Entity

            @NamedQuery(name = "findAllCustomer", query = "SELECT i FROM Customer i")

            public class Customer implements Serializable {

                private static final long serialVersionUID = 1L;
                @Id
                private int id;
                private String firstName;
                private String lastName;
                private String address;
                @OneToMany(cascade=ALL, mappedBy="customer")
                private Collection<Rent> rent;

                public Customer(){

                }

                public Customer(int id,String firstName, String lastName, String address){
                    this.id = id;
                    this.firstName = firstName;
                    this.lastName = lastName;
                    this.address = address;
                }

                public int getId() {
                    return id;
                }

                public void setId(int id) {
                    this.id = id;
                }

                public String getFirstName(){
                    return firstName;
                }
                public void setFirstName(String firstName){
                    this.firstName = firstName;
                }
                public String getLastName(){
                    return lastName;
                }
                public void setLastName(String lastName){
                    this.lastName = lastName;
                }
                public String getAddress(){
                    return address;
                }
                public void setAddress(String address){
                    this.address = address;
                }


                public Collection<Rent> getRent() {
                    return rent;
                }

                public void setRent(Collection<Rent> rent) {
                    this.rent = rent;
                }

                 public void addRent(Rent rent) {
                    this.getRent().add(rent);
                }

            }

       *

租金实体

            @Entity

            @NamedQuery(name = "findAllRent", query = "SELECT i FROM Rent i")

            public class Rent implements Serializable {

                private static final long serialVersionUID = 1L;
                @Id
                @GeneratedValue(strategy = GenerationType.AUTO)
                private Long id;
                private String item;
                private int days;
                private int rDate;
                @JoinColumn(name="VENDORID")
                @ManyToOne
                private Customer customer;

                public Rent(){

                }
                public Rent(String item, int days, int rDate){
                    this.item = item;
                    this.days = days;
                    this.rDate= rDate;
                }

                public Long getId() {
                    return id;
                }

                public void setId(Long id) {
                    this.id = id;
                }
                public String getItem() {
                    return item;
                }

                public void setItem(String item) {
                    this.item = item;
                }
                public int getDays() {
                    return days;
                }

                public void setDays(int days ) {
                    this.days = days;
                }
                public int getRDate() {
                    return rDate;
                }

                public void setRDate(int rDate ) {
                    this.rDate = rDate;
                }

                public Customer getCustomer() {
                    return customer;
                }

                public void setCustomer(Customer customer) {
                    this.customer = customer;
                }

            }

EJB

            public void createRent (int currentCustomer,String item, int days, int rDate ){

                        Customer customer = em.find(Customer.class, currentCustomer);
                        Rent rent = new Rent(item, days, rDate);        
                        customer.addRent(rent);
                        rent.setCustomer(customer);
                        em.merge(customer);

                }

控制器

            //currentCustomer has the id of the  customer for whom the rent is being created//

             public int getCurrentCustomer() {

                    return currentCustomer;

                }

                public void setCurrentCustomer(int currentCustomer) {

                    this.currentCustomer = currentCustomer;

                }

            public String doCreateRent() {

                   System.out.println(""+currentCustomer);

                    try {            

                        customerEJB.createRent(this.currentCustomer, this.item, this.days, this.rDate);  

                    } catch (Exception e) {

                        System.out.printf( "Problem adding line items to order ID {0}");
                    }
                    return "listRent.xhtml";
                }

listCustomer.xhtml;列出客户,当点击id时,它会转到newRent.xhtml

<h:head>
    <title>List all the customer</title>
</h:head>
<h:body>
    <h1>List all the customer</h1>
    <hr/>

    <h:dataTable value="#{customerController.customerList}" var="it" border="1">

        <h:column>
            <f:facet name="header">
                <h:outputText value="Id"/>
            </f:facet>

我认为这是我搞乱应用程序的地方

            <h:form>
                <h:commandLink id="customer_Id_link" action="newRent.xhtml">
                    <h:outputText value="#{it.id}"/>
                    <f:setPropertyActionListener target="#{customerController.currentCustomer}" value="#{it.id}" />
                </h:commandLink>
            </h:form>            
        </h:column>

        <h:column>
            <f:facet name="header">
                <h:outputText value="FirstName"/>
            </f:facet>
            <h:outputText value="#{it.firstName}"/>
        </h:column>

        <h:column>
            <f:facet name="header">
                <h:outputText value="LastName"/>
            </f:facet>
            <h:outputText value="#{it.lastName}"/>
        </h:column>

        <h:column>
            <f:facet name="header">
                <h:outputText value="Address"/>
            </f:facet>
            <h:outputText value="#{it.address}"/>
        </h:column>    

    </h:dataTable>
    <h:form>


        <h:link outcome="index.xhtml" value="mainpage"/>
    </h:form>
    <hr/>
    <i>APress - Beginning Java EE 6</i>
</h:body>
</html>

newRent.xhtml

    <h:head>
        <title>Creates a new rent</title>
    </h:head>
    <h:body>
        <h1>Create a new rent</h1>
        <hr/>
        <h:form>
            <table border="0">

                <tr>
                    <td>
                        <h:outputLabel value="Item : "/>
                    </td>
                    <td>
                        <h:inputText value="#{customerController.item}"/>
                    </td>
                </tr>

                <tr>
                    <td>
                        <h:outputLabel value="days : "/>
                    </td>
                    <td>
                        <h:inputText value="#{customerController.days}"/>
                    </td>
                </tr>

                <tr>
                    <td>
                        <h:outputLabel value="Date : "/>
                    </td>
                    <td>
                        <h:inputText value="#{customerController.RDate}"/>
                    </td>
                </tr>

            </table>

            <h:commandButton value="Create a rent" action="#{customerController.doCreateRent()}"/>

        </h:form>
        <hr/>
        <i>APress - Beginning Java EE 6</i>

    </h:body>
    </html>

输出

    INFO: currentcustomer0
    WARNING: EJB5184:A system exception occurred during an invocation on EJB CustomerEJB, method: public void shoeb.CustomerEJB.createRent(int,java.lang.String,int,int)
    WARNING: javax.ejb.EJBException
        at com.sun.ejb.containers.BaseContainer.processSystemException(BaseContainer.java:5215)
        at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5113)
        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:89)
        at com.sun.proxy.$Proxy185.createRent(Unknown Source)
        at shoeb.__EJB31_Generated__CustomerEJB__Intf____Bean__.createRent(Unknown Source)
        at shoeb.CustomerController.doCreateRent(CustomerController.java:57)
        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 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 com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
        at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
        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.processApplication(UIViewRoot.java:1259)
        at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
        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:1550)
        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:860)
        at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
        at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
        at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
        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:744)
    Caused by: java.lang.NullPointerException
        at shoeb.CustomerEJB.createRent(CustomerEJB.java:45)
        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.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1052)
        at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1124)
        at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5388)
        at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:619)
        at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
        at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:571)
        at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:162)
        at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:144)
        at sun.reflect.GeneratedMethodAccessor78.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:861)
        at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:800)
        at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:370)
        at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5360)
        at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5348)
        at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:214)
        ... 47 more

    INFO: Problem adding line items to order ID {0}

1 个答案:

答案 0 :(得分:0)

试试这个:

public void createRent (int currentCustomer,String item, int days, int rDate ){

    try{

        Customer customer = em.find(Customer.class, currentCustomer);
        Rent rent = new Rent(item, days, rDate);
        customer.addRent(rent);
        rent.setCustomer(customer);
        em.merge(customer);

    } catch (Exception e) {
        throw new EJBException(e.getMessage());
    } 
}

由于关系是双向的,因此您需要为彼此指定实体。 这是:

If the OneToMany uses a foreign key in the target object's table JPA 
requires that the relationship be bi-directional 
(inverse ManyToOne relationship must be defined in the target object), 
and the source object must use the mappedBy attribute to define the mapping

和链接: http://en.wikibooks.org/wiki/Java_Persistence/OneToMany