2009-05-20 16 views
7

Im folgenden Code habe ich Probleme mit meinem injizierten EnitityManager, der immer als null zeigt;Null-EntityManger im Frühjahr reparieren MVC-Anwendung?

public class GenericController extends AbstractController { 

    @PersistenceContext(unitName = "GenericPU") 
    private EntityManager em; 

    protected ModelAndView handleRequestInternal(
      HttpServletRequest request, 
      HttpServletResponse response) throws Exception { 
     //(em == null) is always trigged 
     if (em == null) throw new NullPointerException("em is null"); 
     Collection<Generic> Generics = em.createNamedQuery("Generic.findAll").getResultList(); 

     ModelAndView mav = new ModelAndView("Generic"); 
     mav.addObject(Generics); 
     return mav; 
    } 
} 

Hier ist die Bohne Definition, definiert in Dispatcher-servlet.xml. Annotation-basierte, definiert in der Persistenz-context.xml Datei:

<bean id="Generic" class="com.application.web.GenericController" /> 

EnitityManager sollte basierend auf tx injiziert werden.

<?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: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-2.5.xsd 
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> 

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
     <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" /> 
     <property name="url" value="removed" /> 
     <property name="username" value="removed" /> 
     <property name="password" value="removed" /> 
    </bean> 

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="persistenceUnitName" value="GenericPU" /> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="jpaDialect"> 
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" /> 
     </property> 
     <property name="jpaVendorAdapter"> 
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
       <property name="showSql" value="true" /> 
       <property name="generateDdl" value="false" /> 
       <property name="databasePlatform" value="org.hibernate.dialect.SQLServerDialect" /> 
      </bean> 
     </property> 
    </bean> 

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="entityManagerFactory"/> 
    </bean> 

    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> 

    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/> 

</beans> 

Der Persistenz-Kontext aus dem applicationContext.xml

ist
<?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:context="http://www.springframework.org/schema/context" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">  
    <import resource="classpath:META-INF/persistence-context.xml"/> 
</beans> 

die Classpath Import geladen wird, weil die ORM Entitäten als JAR-Datei in das Projekt einbezogen werden. Beachten Sie, dass der Persistenzkontext geladen wird, da Spring die Implementierung der Anwendung nicht zulässt, wenn die Konfigurationsdateien nicht analysiert werden können.

Hier ist meine persistence.xml.

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> 
    <persistence-unit name="CoolOrmJpaPU" transaction-type="RESOURCE_LOCAL"> 
    <class>com.application.orm.jpa.Generic</class> 
    <!-- bunch more classes --> 
    </persistence-unit> 
</persistence> 

Und mein web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 
    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/applicationContext.xml</param-value> 
    </context-param> 
    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 
    <servlet> 
     <servlet-name>dispatcher</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <load-on-startup>2</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>dispatcher</servlet-name> 
     <url-pattern>*.htm</url-pattern> 
    </servlet-mapping> 
    <session-config> 
     <session-timeout> 
      30 
     </session-timeout> 
    </session-config> 
    <welcome-file-list> 
     <welcome-file>redirect.jsp</welcome-file> 
    </welcome-file-list> 
</web-app> 

Kann mir hier jemand helfen?

+0

Wie verweisen Sie persistence-context.xml aus application-context.xml? Verwenden Sie den Import? – Mark

+0

Mark, ich habe das für dich hinzugefügt. Entschuldigung, ich wollte Details ausschließen, aber es gibt so viele Einstellungen, dass ich nicht alles einbeziehen wollte. –

Antwort

8

Ich hatte heute das Glück, mit einem Berater über dieses Thema sprechen zu können, er konnte mir helfen, das Ganze zu sortieren.

Also mein Problem ist, dass Spring MVC wurde zwei verschiedene Kontexte, ein Anwendungskontext, in applicationContext.xml und einem Web-Kontext definiert, in dispatcher-servlet.xml definiert.

Beans aus einem Kontext können nicht mit Beans in einem anderen Kontext kommunizieren. Wenn ich also meinen Persistenzkontext innerhalb von applicationContext.xml initiierte, konnte ich in Beans, die von dispatcher-servlet.xml, dh meinen Controllern geladen wurden, nicht darauf zugreifen.

Wenn Netbeans die Basis für meine Spring MVC automatisch generiert hat, wird diese standardmäßig eingerichtet. In einigen großen Webanwendungen wäre es sinnvoll, den Webpart der Anwendung in einem Kontext zu trennen, der sich vom Rest der Logik unterscheidet (Persistenz, Geschäftscode usw.). In meinem Fall, wo ich versuche, meinen Entity Manager direkt in meine Controller zu injizieren, hat das gegen mich geklappt.

Um das Problem zu beheben, zog ich die Linie

<import resource="classpath:META-INF/persistence-context.xml"/> 

Vom applicationContext.xml zu meinem Dispatcher-servlet.xml. Meine Controller wurden dann ordnungsgemäß mit EntityManagers aus der Annotation @PersistanceContext injiziert.

+0

Der gesamte Prozess der XML-Konfiguration für die Web-Ebene wird im Spring-Referenzhandbuch, Kapitel 13 beschrieben: http://static.springframework.org/spring/docs/2.5.x/reference/mvc.html – MetroidFan2002

+0

Äh, sorry, Nicht nur XML-Konfiguration, sondern Konfiguration allgemein - wo ist schon der Kommentar-Button ?! – MetroidFan2002

+0

Also, wie hast du es gelöst? Wie ich es verstehe - der ApplicationContext dient als "root" - oder "parent" -Kontext für den DispatcherServlet-Kontext (und alle anderen Kontexte), so dass alle im Anwendungskontext definierten Beans für ihn verfügbar sein sollten. z.B. Controller haben im Allgemeinen andere @Service- oder @ Component-Beans, die in den applicationContext definiert sind. Deine Antwort erklärt nicht wirklich, warum es nicht für dich funktioniert hat. –

0

Ich glaube, Sie brauchen eine Datei persistence.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="1.0" 
    xmlns="http://java.sun.com/xml/ns/persistence" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> 

    <persistence-unit name="GenericPU"> 
    <class>com.domain.MyClass</class> 
    </persistence-unit> 

</persistence> 

ich denke, es wird nicht funktionieren, wenn die Datei einen anderen Namen hat, schon gar nicht, da Sie nicht der EntityManager Fabrik die neuen Namen überall erzählen Sie.

+0

Ich habe eine persistence.xml, ich habe es weggelassen, weil ich nicht gedacht habe, ob das für das Problem entscheidend wäre. –

+0

Sorry, dass ich es zu der Frage hinzugefügt habe. –

0

habe ich mit einer älteren Frühjahr Version zu arbeiten, wenn Sie wie mußten setProperty(), um die Bohne setzen und den propery-Tag in der Feder-Bean-Definition festgelegt:

<bean id="Generic" class="com.application.web.GenericController" /> 
    <property name="em" ref="entityManager" /> 
</bean> 

Vielleicht sollen Sie arbeiten mit der transactionManager oder die entityManagerFactory beans ...

PD: Ich persönlich bevorzuge die alte Art, Abhängigkeiten zu injizieren.

0

Haben Sie

enthalten XML
<context:annotation-config /> 

In Ihrer Feder. Referenz here

+0

Ich habe das nicht, aber ich glaube, es wird implizit eingeschaltet, indem man tx: annotation-driven setzt. –