0

我已经搜索并阅读/研究了网络上几乎每个链接,这些链接涉及删除父实体和通过我的 OneToMany 集合进行删除级联的问题。我已经尝试了许多建议,包括删除对包含的集合的所有引用、不同的 Cascade 类型组合等。但当我尝试删除父实体时,我在持久化已删除的实体时不断遇到异常。

我有一个 Adhesive 实体类,其中包含与 AdhesiveChemicals 的 OneToMany 关系,如下所示:

@Entity
@Table(name = "Adhesive")
@NamedQueries({
public class Adhesive implements Serializable {

    private static final long serialVersionUID = 1L;
    // @Max(value=?)  @Min(value=?)//if you know range of your decimal fields consider  using these annotations to enforce field validation
    private Long adhesiveId;
    private String adhesiveName;
    private String costPerDryPound;
    private String solidPercent;
    private String totalActCost;
    private String totalDry;
    private String totalWet;
    private Boolean inactive;
    private List<AdhesiveChemicals> adhesiveChemicals;
    private List<AdhesiveComponent> adhesiveComponentsList;

    @OneToMany(cascade= {CascadeType.REMOVE, CascadeType.MERGE, CascadeType.REFRESH}, mappedBy="adhesive", targetEntity=AdhesiveChemicals.class, orphanRemoval=true)
    @LazyCollection(LazyCollectionOption.FALSE)
    public List<AdhesiveChemicals> getAdhesiveChemicalsList() {
        return adhesiveChemicals;
    }

    public void setAdhesiveChemicalsList(List<AdhesiveChemicals> adhesiveChemicals) {
        this.adhesiveChemicals = adhesiveChemicals;
    }

    @OneToMany(mappedBy="adhesive", targetEntity=AdhesiveComponent.class)
    @LazyCollection(LazyCollectionOption.FALSE)
    public List<AdhesiveComponent> getAdhesiveComponentsList() {
        return adhesiveComponentsList;
    }

    public void setAdhesiveComponentsList(List<AdhesiveComponent> adhesiveComponentsList) {
        this.adhesiveComponentsList = adhesiveComponentsList;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (adhesiveId != null ? adhesiveId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Adhesive)) {
            return false;
        }
        Adhesive other = (Adhesive) object;
        if ((this.adhesiveId == null && other.adhesiveId != null) || (this.adhesiveId != null && !this.adhesiveId.equals(other.adhesiveId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "Adhesive{" + "adhesiveId=" + adhesiveId + ", adhesiveName=" + adhesiveName +
                ", costPerDryPound=" + costPerDryPound + ", solidPercent=" + solidPercent +
                ", totalActCost=" + totalActCost + ", totalDry=" + totalDry + ", totalWet=" +
                totalWet + ", inactive=" + inactive + '}';
    }

}

粘合剂化学品类:

@Entity
public class AdhesiveChemicals implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String wetLbs;
private String dryLbs;
private String actualCost;
private Adhesive adhesive;
private Chemical chemical;

@ManyToOne(fetch= FetchType.EAGER, optional=false)
@JoinColumn(name="adhesive_id")
public Adhesive getAdhesive() {
    return adhesive;
}

public void setAdhesive(Adhesive adhesive) {
    this.adhesive = adhesive;
}

@ManyToOne(fetch = FetchType.EAGER, optional=false)
@JoinColumn(name="chemical_id")
public Chemical getChemical() {
    return chemical;
}

public void setChemical(Chemical chemical) {
    this.chemical = chemical;
}



@Override
public int hashCode() {
    int hash = 0;
    hash += (id != null ? id.hashCode() : 0);
    return hash;
}

@Override
public boolean equals(Object object) {
    // TODO: Warning - this method won't work in the case the id fields are not set
    if (!(object instanceof AdhesiveChemicals)) {
        return false;
    }
    AdhesiveChemicals other = (AdhesiveChemicals) object;
    if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
        return false;
    }
    return true;
}

@Override
public String toString() {
    return "AdhesiveChemicals{" + "wetLbs=" + wetLbs + ", dryLbs=" + dryLbs
        + ", actualCost=" + actualCost + ", adhesive=" + adhesive + ", chemical=" + chemical + '}';
}

调用删除粘合剂的代码在这里:

    // Handler for Button[fx:id="pricingAdhesiveDeleteButton"] onMouseClicked
public void doAdhesiveDelete(MouseEvent event) {
    // handle the event here
    logger.info("Entering {}.doAdhesiveDelete.", this.getClass().getName());
    if (pricingAdhesiveTable.getSelectionModel().getSelectedIndex() < 0) {
        return;
    }
    DialogFX dialog = new DialogFX(DialogFX.Type.QUESTION);
    dialog.setTitleText("Delete?");
    dialog.setMessage("  Do you really wish to delete " + tempAdhesive.getAdhesive() + "?   ");
    if (dialog.showDialog() == 1) {
        return;
    }
    tempAdhesive.getAdhesiveChemicalsList().clear();
    pricingAdhesiveTableList.remove(tempAdhesive);
//        for (AdhesiveChemicals adhesiveChemicals : acList) {
//            costingService.removeAdhesiveChemicals(adhesiveChemicals.getId());
//        }
    costingService.removeAdhesive(tempAdhesive.getId());
    init();
    pricingAdhesiveDeleteButton.setDisable(true);
}

costingService 是一个 Glassfish 服务,它实现了数据库上的所有创建/更新/删除方法。removeAdhesive 方法如下所示:

@Service
@Transactional(readOnly=false)
public class CostingServiceImpl implements CostingService {
private static final Logger logger =      LoggerFactory.getLogger(CostingServiceImpl.class.getName());
private EntityManager em;

@PersistenceContext(name="LamtecVoyagerPU")
public void setEntityManager(EntityManager entityManager) {
    this.em = entityManager;
}

    @Override
public void removeAdhesive(Long Id) {
    logger.info("Entering {}.removeAdhesive.", this.getClass().getName());
    Adhesive a = em.find(Adhesive.class, Id);
//        a.getAdhesiveChemicalsList().clear();
    em.remove(a);
}

如您所见,在这一点上,我将级联限制为一对多关系上的 REFRESH、MERGE 和 REMOVE,并且我将孤儿删除设置为 true。但是,当我尝试删除包含一些 AdhesiveChemicals 的粘合剂时,会引发以下异常。(其中有一些额外的东西与客户端和服务器之间的通信有关。)

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1440)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:69)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:33)
at javafx.event.Event.fireEvent(Event.java:171)
at javafx.scene.Scene$ClickGenerator.postProcess(Scene.java:3113)
at javafx.scene.Scene$ClickGenerator.access$8600(Scene.java:3051)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3333)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3164)
at javafx.scene.Scene$MouseHandler.access$1900(Scene.java:3119)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1559)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2261)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:228)
at com.sun.glass.ui.View.handleMouseEvent(View.java:528)
at com.sun.glass.ui.View.notifyMouse(View.java:922)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
at com.sun.glass.ui.win.WinApplication$2$1.run(WinApplication.java:67)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.reflect.InvocationTargetException
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:601)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1435)
... 31 more
Caused by: org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException: Transaction marked for rollback.
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1012)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy463.removeAdhesive(Unknown Source)
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:601)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.remoting.support.RemoteInvocationTraceInterceptor.invoke(RemoteInvocationTraceInterceptor.java:77)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy464.removeAdhesive(Unknown Source)
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:601)
at org.springframework.remoting.support.RemoteInvocation.invoke(RemoteInvocation.java:205)
at org.springframework.remoting.support.DefaultRemoteInvocationExecutor.invoke(DefaultRemoteInvocationExecutor.java:38)
at org.springframework.remoting.support.RemoteInvocationBasedExporter.invoke(RemoteInvocationBasedExporter.java:78)
at org.springframework.remoting.support.RemoteInvocationBasedExporter.invokeAndCreateResult(RemoteInvocationBasedExporter.java:114)
at org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter.handleRequest(HttpInvokerServiceExporter.java:73)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:49)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:669)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:585)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:688)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
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:722)
at org.springframework.remoting.support.RemoteInvocationUtils.fillInClientStackTraceIfPossible(RemoteInvocationUtils.java:47)
at org.springframework.remoting.support.RemoteInvocationResult.recreate(RemoteInvocationResult.java:115)
at org.springframework.remoting.support.RemoteInvocationBasedAccessor.recreateRemoteInvocationResult(RemoteInvocationBasedAccessor.java:85)
at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInterceptor.java:148)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy14.removeAdhesive(Unknown Source)
at com.lamtec.pricingclient.PricingPresenter.doAdhesiveDelete(PricingPresenter.java:982)
... 36 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.enterprise.transaction.UserTransactionImpl.commit(UserTransactionImpl.java:208)
at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1009)
... 102 more
Caused by: javax.persistence.EntityNotFoundException: deleted entity passed to persist: [com.lamtec.lamteccommon.data.costing.AdhesiveChemicals#<null>]
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1369)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1315)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1321)
at org.hibernate.ejb.AbstractEntityManagerImpl$3.mapManagedFlushFailure(AbstractEntityManagerImpl.java:1235)
at org.hibernate.transaction.synchronization.CallbackCoordinator.beforeCompletion(CallbackCoordinator.java:122)
at org.hibernate.transaction.synchronization.HibernateSynchronizationImpl.beforeCompletion(HibernateSynchronizationImpl.java:51)
at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:435)
... 105 more

填充包含 Adhesives 的列表的原始查询(默认情况下,由于急切获取,AdhesiveChemicals):

    @Override
public List<Adhesive> listAdhesives() {
    logger.info("Entering {}.listAdhesives.", this.getClass().getName());
    Query query = em.createNamedQuery("Adhesive.findAll");
    List<Adhesive> result = new ArrayList<>();
    try {
        result = query.getResultList();
    } catch (Exception ex) {
        logger.info("Not able to get Adhesive list");
        throw ex;
    }
    return result;

}

其结果被放置在定价粘合剂表列表中。当我尝试删除要删除的粘合剂时,我也将其从定价AdhesiveTableList 中删除,如上面的 doAdhesiveDelete 代码所示。

请不要担心我的感受。我已经在这个问题上打败了自己。我还有许多其他的删除工作正常,但这个继续让我感到困惑。如果您需要更多信息,请告诉我。
哦,数据库是 MS SQL Server,我使用 Hibernate 3.6 作为我的 JPA 提供程序。Glassfish 是 3.X 版。

谢谢。

4

0 回答 0