2016-07-23 30 views
0

Ich habe eine j2ee App ausgeführt, aber ich entschied mich, die Code-Organisation zu einem Paket nach Feature-Stil statt der Paket für Layer-Stil, den ich jetzt bin, die wichtigsten Gründe für diese Änderung sind zu ändern Code-Navigation und modulatity, ich habe dieses Schema:Glassfish Eclipse Link JPA Paket nach Funktion

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

Ich möchte es bewegen:

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

Wenn ich laufen Tests auf dem neuen Schema alles funktioniert gut, aber wenn ein Versuch, die Kundendienst über das customerHandler ich diese Fehlermeldung erhalten, zu verwenden:

Ich habe versucht, meine Klassen in das neue Paket einzeln zu gruppieren, um zu sehen, welches das Problem ist, und es ist der KundeServiceImpl.java, wenn ich diese Klasse außerhalb der com.app.cu verschiebe Stomer-Paket Meine App funktioniert gut, die Datei applicationContext.xml ist so konfiguriert, dass sie das com.app.customer-Paket scannt, das customerDaoImpl und customerServiceImpl haben @Transactional-Annotationen, ich habe gelesen, dass entweder der Dao oder der Service transaktional sein sollte, aber nicht beides Ich habe versucht, diese Anmerkung aus jeder Klasse zu entfernen, aber ich bekomme immer noch den gleichen Fehler.

Dies ist der vollständige Stack-Trace:

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) 

Was mache ich falsch? ist es möglich, eine App mit dem Paket nach Feature-Stil mit Eclipselink JPA zu bauen?

Übrigens kann ich Kundendaten aus der Datenbank abrufen.

EDIT:

Dies ist die applicationContext.xml Datei mit der ursprünglichen Verpackung Stil:

<?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> 

Für die neue Verpackung Stil i dies geändert:

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

Um dies:

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

Dann bekomme ich die oben genannten Fehler, aber wenn ich bewegen die customerServiceImpl.class außerhalb des Pakets com.app.customer an ihren ursprünglichen Standort: com.app.service und die applicationContext.xml ändern:

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

Meine App funktioniert.

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

Ich denke nicht, dass JPA interessiert, welche Art von Verpackung Sie verwenden. Die entsprechende Konfiguration wird jedoch nicht gebucht. Es ist also schwer zu sagen, was schief läuft. – ujulu

+0

Ich habe gerade die Datei "applicationContext.xml" hinzugefügt. Können Sie sich das bitte ansehen und mir sagen, ob etwas falsch ist? – Remigio

+0

Wie ist Ihre 'persistence.xml' konfiguriert? – ujulu

Antwort

0

Es stellt sich heraus, dass, wenn die Controller-Service und DAO-Klassen im selben Paket sind alle Methodenaufruf vom Controller-Objekt zum Serviceobjekt gemacht von Spring als selbst betrachtet -invocation-Aufruf, deshalb wurde den Methoden "Persistent", "Merge" und "Remove" kein Transaktionsverhalten hinzugefügt. Außerdem wird erläutert, warum die App beim Verschieben der ServiceImpl- oder DaoImpl-Klasse in ein anderes Paket funktioniert, weil so ein Methodenaufruf betrachtet wird ein externer Anruf und wird vom Proxy abgefangen.

Das Problem wurde gelöst, indem der Transaktionsmodus in AOP geändert wurde. Dieser link war hilfreich beim Konfigurieren des neuen Transaktionsmodus.