Удалить строки базы данных с EJB 3.0 - PullRequest
2 голосов
/ 28 августа 2011

Я хочу удалить строку в базе данных, поэтому я создал EJB, который делает это для меня

@Stateless(name = "ejbs/AdminAcountEJB")
public class AdminAcountEJB implements IAdminAcountEJB  {

    @PersistenceContext
    private EntityManager entityManager;

    public void deleteRecord(Record record) {
                    entityManager.remove(record);
    }
}

Я не создал объект TransactionEntity, а затем использовал метод begin (), потому что, как я понял, EJB-объекты уже защищены транзакциями.

Чтобы проверить, работает ли он в пользовательском интерфейсе (страница JSF 2.0), я создал таблицу данных со столбцом со ссылкой на команду удаления и вызвал ее из бэк-бина, подключенного к EJB:

стр.

<h:dataTable value="#{managementBB.retrieveRecords()}" var="record">
                   ...
                    <h:column>
    <h:commandLink value="X" action="#{managementBB.deleteRow(record)}"/>
                    </h:column>
</h:dataTable>

фасоль

 @Named("managementBB")
@SessionScoped
public class ManagementBB implements Serializable{

    @EJB
    private IAdminAcountEJB managementEJB;

    //...

    public String deleteRow(Record record) {

        managementEJB.deleteRecord(record);
        return "manage?faces-redirect=true;";
    }

Это ошибка, которую я вижу в консоли при нажатии на ссылку для удаления строки:

ПРЕДУПРЕЖДЕНИЕ: StandardWrapperValve [Faces Servlet]: PWC1406: Servlet.service () для сервлета Faces Сервлет бросил исключение javax.faces.el.EvaluationException: javax.ejb.EJBException at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke (MethodBindingMethodExpressionAdapter.java:102) в com.sun.faces.application.ActionListenerImpl.processAction (ActionListenerImpl.java:102) на javax.faces.component.UICommand.broadcast (UICommand.java:315) на javax.faces.component.UIData.broadcast (UIData.java:912) в javax.faces.component.UIViewRoot.broadcastEvents (UIViewRoot.java:775) в javax.faces.component.UIViewRoot.processApplication (UIViewRoot.java:1267) в com.sun.faces.lifecycle.InvokeApplicationPhase.execute (InvokeApplicationPhase.java:82) в com.sun.faces.lifecycle.Phase.doPhase (Phase.java:101) в com.sun.faces.lifecycle.LifecycleImpl.execute (LifecycleImpl.java:118) в javax.faces.webapp.FacesServlet.service (FacesServlet.java:312) в org.apache.catalina.core.StandardWrapper.service (StandardWrapper.java:1523) в org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:279) в org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:188) в org.apache.catalina.core.StandardPipeline.invoke (StandardPipeline.java:641) на com.sun.enterprise.web.WebPipeline.invoke (WebPipeline.java:97) на com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke (PESessionLockingStandardPipeline.java:85) в org.apache.catalina.core.StandardHostValve.invoke (StandardHostValve.java:185) в org.apache.catalina.connector.CoyoteAdapter.doService (CoyoteAdapter.java:325) в org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:226) в com.sun.enterprise.v3.services.impl.ContainerMapper.service (ContainerMapper.java:165) в com.sun.grizzly.http.ProcessorTask.invokeAdapter (ProcessorTask.java:791) в com.sun.grizzly.http.ProcessorTask.doProcess (ProcessorTask.java:693) на com.sun.grizzly.http.ProcessorTask.process (ProcessorTask.java:954) в com.sun.grizzly.http.DefaultProtocolFilter.execute (DefaultProtocolFilter.java:170) в com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter (DefaultProtocolChain.java:135) в com.sun.grizzly.DefaultProtocolChain.execute (DefaultProtocolChain.java:102) в com.sun.grizzly.DefaultProtocolChain.execute (DefaultProtocolChain.java:88) в com.sun.grizzly.http.HttpProtocolChain.execute (HttpProtocolChain.java:76) в com.sun.grizzly.ProtocolChainContextTask.doCall (ProtocolChainContextTask.java:53) в com.sun.grizzly.SelectionKeyContextTask.call (SelectionKeyContextTask.java:57) в com.sun.grizzly.ContextTask.run (ContextTask.java:69) в com.sun.grizzly.util.AbstractThreadPool $ Worker.doWork (AbstractThreadPool.java:330) в com.sun.grizzly.util.AbstractThreadPool $ Worker.run (AbstractThreadPool.java:309) at java.lang.Thread.run (Thread.java:662) Вызывается: javax.ejb.EJBException at com.sun.ejb.containers.BaseContainer.processSystemException (BaseContainer.java:5119) в com.sun.ejb.containers.BaseContainer.completeNewTx (BaseContainer.java:5017) в com.sun.ejb.containers.BaseContainer.postInvokeTx (BaseContainer.java:4805)на com.sun.ejb.containers.BaseContainer.postInvoke (BaseContainer.java:2004) на com.sun.ejb.containers.BaseContainer.postInvoke (BaseContainer.java:1955) на com.sun.ejb.containers.EJBLocalObjectInvocin.Hand.(EJBLocalObjectInvocationHandler.java:198) в com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke (EJBLocalObjectInvocationHandlerDelegate.java:84) в $ Proxy162.dej .BendingRec.reflect.(Method.java:597) в org.jboss.weld.util.reflection.SecureReflections $ 13.work (SecureReflections.java:304) в org.jboss.weld.util.reflection.SecureReflectionAccess.run (SecureReflectionAccess.java:54)в org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation (SecureReflectionAccess.java:163) в org.jboss.weld.util.reflection.SecureReflections.invoke (SecureReflections.java:298) в org.jboss.weld.bean.proxy.ClientProxyMethodhoandHandHandHandHandler.in113) в org.jboss.weld.util.CleanableMethodHandler.invoke (CleanableMethodHandler.java:43) в backingbeans.ManagementBB _ $$ _ javassist_132.deleteRow (ManagementBB _ $$ _ javassist_132.jmphotiveNo) ()) в солнечной среде.в sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) в sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) в java.lang.hoj.jj.v.jjel.BeanELResolver.invokeMethod (BeanELResolver.java:737) в javax.el.BeanELResolver.invoke (BeanELResolver.java:467) в javax.el.CompositeELResolver.invoke (CompositeELResolver.arv..AstValue.invoke (AstValue.java:228) в com.sun.el.MethodExpressionImpl.invoke (MethodExpressionImpl.java:297) в org.jboss.weld.util.el.ForwardingMethodExpression.invoke (ForwardingMethodExpression.java:43) в org.jboss.weld.el.WeldMethodExpression.invoke (WeldMetj.sp:.faces.facelets.el.TagMethodExpression.invoke (TagMethodExpression.java:98) по адресу javax.faces.component.MethodBindingMethodExpressionAdapter.invoke (MethodBindingMethodExpressionAdapter.java:88) ... еще 33 класса, вызываемого по указанным ссылкам: исключая аргументудастся вызвать удаление: entity.Record@df8b3d, попробуйте объединить отдельное и попробуйте удалить снова.в org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.performRemove (UnitOfWorkImpl.java:3539) в org.eclipse.persistence.internal.jpa.EntityManagerImpl.remove (EntityManagerImpl.java.sconerpr..common.impl.EntityManagerWrapper..java: 39) в sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) в java.lang.reflect.Method.invoke (Method.java:597) в org.glassfish.ejb.security.appurity.appurity.J.BS.runMethod (EJBSecurityManager.java:1056) в org.glassfish.ejb.security.application.EJBSecurityManager.invoke (EJBSecurityManager.java:1128) в com.sun.ejb.containers.BaseContainer.invokeBeanMethoj.sun.ejb.EjbInvocation.invokeBeanMethod (EjbInvocation.java:615) в com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext (InterceptorManager.java:797) в com.sun.ejb.EjbInvocation.proceed (EjbInvocation.java:567) вorg.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke (SessionBeanInterceptor.java:47) at sun.reflect.GeneratedMethodAccessor87.invoke (неизвестный источник) в sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) в java.lang.reflect.Method.invoke (Method.java:597) в com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept (InterceptorManager.java:858) в com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext (InterceptorManager.java:797) в com.sun.ejb.EjbInvocation.proceed (EjbInvocation.java:567) в com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround (SystemInterceptorProxy.java:157) в com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke (SystemInterceptorProxy.java:139) at sun.reflect.GeneratedMethodAccessor86.invoke (неизвестный источник) в sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) в java.lang.reflect.Method.invoke (Method.java:597) в com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept (InterceptorManager.java:858) в com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext (InterceptorManager.java:797) в com.sun.ejb.containers.interceptors.InterceptorManager.intercept (InterceptorManager.java:367) в com.sun.ejb.containers.BaseContainer .__ перехватывают (BaseContainer.java:5264) в com.sun.ejb.containers.BaseContainer.intercept (BaseContainer.java:5252) в com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke (EJBLocalObjectInvocationHandler.java:190) ... еще 60

Как видите, я использую CDI для бобов (@Named) вместо @ManagedBeans, но я надеюсь, что это не причина. Также я хотел бы отметить, что в моей базе данных есть независимая таблица, которая вообще не связана с таблицей записей, может ли это повлиять?

1 Ответ

4 голосов
/ 28 августа 2011

Ответ можно найти в самой трассировке стека в следующих строках:

Причина: java.lang.IllegalArgumentException: Сущность должна управляться для вызова remove: entity.Record@df8b3d, попробуйте объединитьотсоедините и попробуйте удалить снова.

EntityManager.remove требует, чтобы ссылка, передаваемая в качестве аргумента, была управляемым объектом, то есть объект должен присутствовать в контексте постоянства.Если вы передаете ссылку на сущность из управляемого бина JSF или управляемого бина CDI, это все еще неуправляемый / отсоединенный объект, если вы изначально не получили ссылку на сущность из текущего контекста персистентности.

Для пониманияКроме того, вы должны знать о жизненном цикле сущности JPA.В большинстве случаев управляемый объект, извлекаемый из контекста постоянства, отсоединяется в конце транзакции (т. Е. Когда заканчивается контекст постоянства).Поэтому ваши управляемые компоненты JSF / CDI будут работать с отсоединенными объектами, а не с управляемыми объектами.Когда вы передаете отсоединенный объект от JSF обратно в EJB, вызов EntityManager.remove приведет к описанному IllegalArgumentException.

Поэтому решение состоит в том, чтобы получить ссылку на управляемый объект с помощью отсоединенного объекта,используя EntityManager.merge (который объединяет содержимое отдельного объекта с постоянным контекстом и возвращает ссылку на управляемый объект) или EntityManager.find (который возвращает управляемый объект изконтекст постоянства, если он там присутствует).Я предпочитаю использовать EntityManager.find в сценарии, где возможно изменение отсоединенной сущности - когда у отсоединенной сущности есть отношения с другими сущностями, тогда MERGE может быть каскадным, в то время как операция REMOVE может не произойти, если выне осторожны при определении того, какие операции должны каскадироваться.

...