2016-07-23 54 views
0

我有一個j2ee應用程序正在運行,但我決定通過功能樣式將代碼組織更改爲包,而不是我現在使用的包圖層樣式,此更改的主要原因是代碼導航和modulatity,我有這樣的模式:Glassfish Eclipse Link JPA軟件包按功能

  • com.app.domain
    • customer.java
  • com.app.dao
    • customerDao.java
    • customerDaoImpl.java
  • com.app.service
    • customerService.java
    • customerServiceImpl.java
  • com.app.web
    • customerHandler.java

我想將它移動到:

  • com.app.customer
    • customer.java
    • customerDao.java
    • customerDaoImpl。 java
    • customerService.java
    • customerServiceImpl.java
    • customerHandler.java

當我運行在新模式測試一切正常,但是當嘗試通過customerHandler使用的CustomerService我得到這個錯誤:

No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call

我嘗試將我的類逐個分組到新包中,以查看其中一個是問題,它是customerServiceImpl.java,當我將此類移到com.app.cu之外stomer包我的應用程序工作正常,applicationContext.xml文件被配置爲掃描com.app.customer包,customerDaoImpl和customerServiceImpl有@Transactional註解,我讀到dao或服務應該是事務性的,但不是兩個,所以我試圖從兩個類中刪除這個註釋,但我仍然得到相同的錯誤。

這是一個完整的堆棧跟蹤:

Warning: StandardWrapperValve[dispatcher]: Servlet.service() for servlet dispatcher threw exception  
javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call 
     at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:278) 
     at com.sun.proxy.$Proxy234.merge(Unknown Source) 
     at com.app.customer.customerDaoImpl.merge(customerDaoImpl.java:49) 
     at com.app.customer.customerServiceImpl.store(customerServiceImpl.java:69) 
     at com.app.customer.customerHandler.store(customerHandler.java:39) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:498) 
     at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) 
     at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) 
     at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) 
     at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817) 
     at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731) 
     at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
     at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) 
     at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) 
     at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968) 
     at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:870) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) 
     at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 
     at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) 
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318) 
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) 
     at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) 
     at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) 
     at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) 
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) 
     at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416) 
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283) 
     at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459) 
     at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167) 
     at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206) 
     at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180) 
     at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235) 
     at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) 
     at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283) 
     at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200) 
     at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132) 
     at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111) 
     at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) 
     at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536) 
     at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) 
     at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) 
     at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) 
     at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) 
     at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591) 
     at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571) 
     at java.lang.Thread.run(Thread.java:745) 

我到底做錯了什麼?是否可以使用eclipselink JPA的功能風格構建應用程序?

順便說一句,我能夠從數據庫中檢索客戶信息。

編輯:

這是與原單包裝風格applicationContext.xml文件:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:p="http://www.springframework.org/schema/p" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context-3.2.xsd 
      http://www.springframework.org/schema/tx 
      http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"> 
    <bean id="loadTimeWeaver" class="org.springframework.instrument.classloading.glassfish.GlassFishLoadTimeWeaver" /> 
    <bean id="entityManagerFactory" p:persistenceUnitName="app_PU" 
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
    /> 
    <tx:jta-transaction-manager /> 
    <tx:annotation-driven /> 
    <context:annotation-config/> 
    <context:component-scan base-package="com.app.dao"/> 
    <context:component-scan base-package="com.app.service"/> 
</beans> 

對於新的包裝風格,我改變這樣的:

<context:component-scan base-package="com.app.dao"/> 
<context:component-scan base-package="com.app.service"/> 

要這樣:

<context:component-scan base-package="com.app.customer"/> 

然後我得到上面提到的錯誤,但如果我移動customerServiceImpl.class包com.app.customer外到其原始位置:com.app.service和改變的applicationContext.xml到:

<context:component-scan base-package="com.app.customer"/> 
<context:component-scan base-package="com.app.service"/> 

我的應用有效

的persistence.xml

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence 
       http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> 
    <persistence-unit name="app_PU" transaction-type="JTA"> 
     <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
     <jta-data-source>jdbc/appDB</jta-data-source> 
     <exclude-unlisted-classes>false</exclude-unlisted-classes> 
     <properties> 
      <property name="eclipselink.target-server" value="SunAS9"/> 
      <property name="eclipselink.logging.level" value="INFO"/> 
     </properties> 
    </persistence-unit> 
</persistence> 
+0

我不認爲JPA在意你使用的是哪種包裝。但相關配置不會發布。所以很難說出了什麼問題。 – ujulu

+0

我剛剛添加了applicationContext.xml文件,請你看看它並告訴我是否有任何錯誤? – Remigio

+0

你的'persistence.xml'如何配置? – ujulu

回答

0

事實證明,當控制器,服務和DAO類在同一包從控制器對象到服務對象所做的任何方法調用由Spring視爲自-invocation調用,這就是爲什麼沒有將事務行爲添加到持久化,合併或移除方法的原因,它還解釋了爲什麼應用程序將ServiceImpl或DaoImpl類移動到不同的包時工作,因爲任何方法調用被視爲一個外部電話將被代理攔截。

該問題已通過將事務模式更改爲AOP解決,此link對配置新的事務模式很有用。