2012-04-26 55 views
2

對於我的EclipseLink和Spring(MVC和spring-data)版本3.1.1設置的另一個問題:Spring實體bean未知。使用新的Spring 3.1 packagesToScan屬性並且沒有persistence.xml

我試圖讓JPA無需使用根據this article的persistence.xml文件。在文章中它說:

通常,JPA通過META-INF/persistence.xml文件定義了一個持久單元。從Spring 3.1開始,不再需要此XML文件 - LocalContainerEntityManagerFactoryBean 現在支持'packagesToScan'屬性,其中可以指定用於掃描 for @Entity類的包。

persistence.xml文件是要刪除的最後一塊XML - 現在,JPA可以完全沒有XML設置。

我知道如果有人使用persistence.xml文件,這裏所有的實體類都應該在這裏聲明。但是,我試圖使用packagesToScan屬性來代替。下面是完整的啓動日誌和向servlet發出一個請求後產生的錯誤,最終嘗試在數據庫中創建一個新用戶。它似乎沒有認識到User對象是一個實體。由於我對Spring沒有多少經驗,所以我想知道是否有人首先會發現我正在犯的錯誤,但除此之外,我知道調試它的最好方法。我想知道什麼實體對象已被EntityManagerFactory識別。我的備份選項是切換到使用persistence.xml(還沒有嘗試過,但實際上),但我想如果可能的話擺脫(少一個XML文件擔心)。

更新:基於Sean Patrick Floyd的回答,但我沒有解決主要問題,因此在將建議的配置更改爲entityManagerFactory後,我更新了錯誤日誌。我也做了一個替代方法,通過創建一個persistence.xml文件(舊的和更常見的方式)來實現這個功能,並在servlet中添加一小段測試代碼。功能。 所以,現在我有我的servlet這段代碼:

User user = new User(); 
user.setFirstName("John"); 
user.setLastName("Doe"); 
// user = userService.addUser(user); 

EntityManagerFactory emf = Persistence.createEntityManagerFactory("proxiPU"); 
EntityManager em = emf.createEntityManager(); 
em.getTransaction().begin(); 
em.persist(user); 
em.getTransaction().commit(); 
em.close(); 
emf.close(); 

這persistence.xml文件:

<?xml version="1.0" encoding="UTF-8" ?> 
<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_2_0.xsd" 
    version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"> 

    <persistence-unit name="proxiPU" transaction-type="RESOURCE_LOCAL"> 
     <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
     <class>com.proxi.user.User</class> 
     <exclude-unlisted-classes>false</exclude-unlisted-classes> 
     <properties> 
      <property name="eclipselink.jdbc.driver" value="org.hsqldb.jdbcDriver"/> 
      <property name="eclipselink.jdbc.url" value="jdbc:hsqldb:file:\Users\nly31175\hsqldb;shutdown=true"/> 
      <property name="eclipselink.jdbc.user" value="proxi"/> 
      <property name="eclipselink.jdbc.password" value=""/> 
      <property name="eclipselink.target-database" value="org.eclipse.persistence.platform.database.HSQLPlatform"/> 
      <property name="eclipselink.logging.level" value="FINEST"/> 
      <property name="eclipselink.orm.throw.exceptions" value="true"/> 
      <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/> 
      <property name="eclipselink.ddl-generation.output-mode" value="database"/> 
     </properties> 
    </persistence-unit> 
</persistence> 

這實際工作,所以我現在想知道它是否是用的方式有問題EntityManagerFactory被初始化或類似的東西。我已經包含了用於處理數據庫相關內容的UserService類的代碼。

這裏是啓動日誌(包括錯誤)在整個範圍內:

INFO: Reloading Context with name [/proxi] is completed 
INFO : com.proxi.controller.HomeController - Welcome home! The client locale is en_GB 
[EL Info]: 2012-04-26 15:17:35.066--ServerSession(313687096)--Thread(Thread[http-bio-8980-exec-3,5,main])--EclipseLink, version: Eclipse Persistence Services - 2.2.0.v20110202-r8913 
[EL Config]: 2012-04-26 15:17:35.079--ServerSession(313687096)--Connection(1182807222)--Thread(Thread[http-bio-8980-exec-3,5,main])--connecting(DatabaseLogin(
    platform=>HSQLPlatform 
    user name=> "" 
    connector=>JNDIConnector datasource name=>null 
)) 
INFO : hsqldb.db.HSQLDB36EB6EA7CB.ENGINE - checkpointClose start 
INFO : hsqldb.db.HSQLDB36EB6EA7CB.ENGINE - checkpointClose end 
[EL Config]: 2012-04-26 15:17:36.016--ServerSession(313687096)--Connection(1257700692)--Thread(Thread[http-bio-8980-exec-3,5,main])--Connected: jdbc:hsqldb:file:\Users\nly31175\hsqldb;shutdown=true 
    User: proxi 
    Database: HSQL Database Engine Version: 2.2.6 
    Driver: HSQL Database Engine Driver Version: 2.2.6 
INFO : hsqldb.db.HSQLDB36EB6EA7CB.ENGINE - Database closed 
[EL Config]: 2012-04-26 15:17:36.365--ServerSession(313687096)--Connection(385835848)--Thread(Thread[http-bio-8980-exec-3,5,main])--connecting(DatabaseLogin(
    platform=>HSQLPlatform 
    user name=> "" 
    connector=>JNDIConnector datasource name=>null 
)) 
INFO : hsqldb.db.HSQLDB36EB6EA7CB.ENGINE - checkpointClose start 
INFO : hsqldb.db.HSQLDB36EB6EA7CB.ENGINE - checkpointClose end 
[EL Config]: 2012-04-26 15:17:36.877--ServerSession(313687096)--Connection(603544782)--Thread(Thread[http-bio-8980-exec-3,5,main])--Connected: jdbc:hsqldb:file:\Users\nly31175\hsqldb;shutdown=true 
    User: proxi 
    Database: HSQL Database Engine Version: 2.2.6 
    Driver: HSQL Database Engine Driver Version: 2.2.6 
INFO : hsqldb.db.HSQLDB36EB6EA7CB.ENGINE - Database closed 
[EL Info]: 2012-04-26 15:17:37.328--ServerSession(313687096)--Thread(Thread[http-bio-8980-exec-3,5,main])--file:/C:/Users/nly31175/workspace/spring/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/proxi/WEB-INF/classes/_default login successful 
Apr 26, 2012 3:17:37 PM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/proxi] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: Object: [email protected] is not a known entity type.] with root cause 
java.lang.IllegalArgumentException: Object: [email protected] is not a known entity type. 
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4128) 
    at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:406) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:365) 
    at $Proxy23.persist(Unknown Source) 
    at com.proxi.user.UserService.save(UserService.java:27) 
    at com.proxi.user.UserService.addUser(UserService.java:39) 
    at com.proxi.controller.HomeController.home(HomeController.java:51) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:662) 

根-context.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:beans="http://www.springframework.org/schema/beans" 
    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.1.xsd"> 

    <!-- Root Context: defines shared resources visible to all other web components --> 
    <bean id="userService" class="com.proxi.user.UserService" > 
     <property name="entityManagerFactory" ref="entityManagerFactory" /> 
    </bean> 

    <!-- Starting with Spring 3.1, the persistence.xml XML file is no longer 
     necessary. The LocalContainerEntityManagerFactoryBean now supports a ‘packagesToScan’ 
     property where the packages to scan for @Entity classes can be specified. --> 
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <property name="jpaDialect" ref="jpaDialect" /> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="packagesToScan" value="com.proxi.user" /> 
     <property name="jpaVendorAdapter"> 
      <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"> 
       <property name="showSql" value="true" /> 
       <property name="generateDdl" value="true" /> 
       <property name="databasePlatform" value="org.eclipse.persistence.platform.database.HSQLPlatform" /> 
      </bean> 
     </property> 
     <property name="loadTimeWeaver"> 
      <bean class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver" /> 
     </property> 
    </bean> 

    <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect " /> 

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
     <property name="driverClassName" value="org.hsqldb.jdbcDriver" /> 
     <property name="url" value="jdbc:hsqldb:file:\Users\nly31175\hsqldb;shutdown=true" /> 
     <property name="username" value="proxi" /> 
     <property name="password" value="" /> 
    </bean> 

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

</beans> 

User.java類:

/** 
* 
*/ 
package com.proxi.user; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Table; 

import javax.persistence.Id; 

    /** 
    * Represents an application user. 
    */ 
    @Entity 
    @Table(name = "user") 
    public class User { 

     @Id 
     @GeneratedValue(strategy = GenerationType.IDENTITY) 
     @Column(name = "id") 
     private Long id; 

     @Column(name = "first_name") 
     private String firstName; 

     @Column(name = "last_name") 
     private String lastName; 

     // /////// GETTERS AND SETTERS /////////// 

     public String getFirstName() { 
      return firstName; 
     } 

     public void setFirstName(String firstName) { 
      this.firstName = firstName; 
     } 

     public String getLastName() { 
      return lastName; 
     } 

     public void setLastName(String lastName) { 
      this.lastName = lastName; 
     } 

     public Long getId() { 
      return id; 
     } 

     public void setId(Long id) { 
      this.id = id; 
     } 
    } 

這裏是UserService。java的

package com.proxi.user; 

import javax.persistence.EntityManager; 
import javax.persistence.EntityManagerFactory; 
import javax.persistence.PersistenceUnit; 

import org.springframework.transaction.annotation.Transactional; 

/** 
* Performs user related operations. 
* 
*/ 
public class UserService { 

    @PersistenceUnit 
    private EntityManagerFactory entityManagerFactory; 

    @Transactional 
    public User save(User user) { 
     EntityManager entityManager = entityManagerFactory.createEntityManager(); 

     if (user.getId() == null) { 
      entityManager.persist(user); 
      return user; 
     } else { 
      return entityManager.merge(user); 
     } 
    } 

    public User findUser(String userid) { 
     return null; 
    } 

    public User addUser(User user) { 
     return save(user); 
    } 

    // /////////////////////// GETTERS AND SETTERS ////////////////////// 

    public EntityManagerFactory getEntityManagerFactory() { 
     return entityManagerFactory; 
    } 

    public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) { 
     this.entityManagerFactory = entityManagerFactory; 
    } 
} 

回答

1

內部異常:java.sql.SQLSyntaxErrorException:對象名稱 已經存在:在語句[CREATE TABLE用戶(發電默認身份ID BIGINT USER(從1開始,遞增1) NOT NULL ,如first_name VARCHAR(255),姓氏VARCHAR(255),PRIMARY KEY (ID))]

這似乎是這個問題:春/的EclipseLink試圖創建一個已經存在的表。

嘗試從您的XML內容刪除此行:

<property name="generateDdl" value="true" /> 
+0

這確實消除了內部異常,但主要問題依然存在。 – chrisjleu 2012-04-26 12:48:21

1

我真的搜索在這個問題上了天,現在,我可以拿出最好的是JPA的這一侷限性小記教程標題爲:EclipseLink JPA Deployed on Tomcat 6 using Eclipse WTP。相關章節說:

由於Tomcat不是Java EE 5兼容服務器,所以對JPA有一些 限制。

  • 沒有動態編織(工具) - 實體的靜態編織通過EclipseLink仍然可用。
  • @EJB注入會話bean(包含EntityManager)可用 - 直接使用持久性工廠和管理器。
  • @PersistenceContext注入容器管理持久性單元可用 - 使用 Persistence.createEntityManagerFactory(JTA_PU_NAME)

我認爲後兩點適用於我遇到的問題。正如我所說,我可以讓它工作沒有問題與測試代碼片段,但是當我嘗試正確連接它時,我遇到了一個問題。因此,沒有任何其他答案,我認爲這是我必須解決的問題。任何進一步的見解歡迎,但我不覺得它是一個非常令人滿意的答案。

0

您的persistence.xml文件出現在項目中嗎?
如果是這種情況,從項目中完全刪除persistence.xml。這個文件與packagesToScan屬性有衝突,即使你沒有在配置中的任何地方明確提及它。我自己遇到了這個特點。

0

@chrisjleu你非常接近。我把它設置日食鏈接使用靜態織的工作:

private static final Properties jpaProperties = new Properties(); 
static { 
    jpaProperties.put("eclipselink.logging.level", "INFO"); 
    jpaProperties.put("eclipselink.weaving", "static"); 
} 

,並將其添加到LocalContainerEntityManagerFactoryBean.setJpaProperties(jpaProperties)

爲了讓靜態編織工作,我使用AspectJ。我的項目在Maven中,因此我使用以下插件:

  <plugin> 
       <groupId>org.codehaus.mojo</groupId> 
       <artifactId>aspectj-maven-plugin</artifactId> 
       <version>1.2</version> 
       <!-- NB: do not use 1.3 or 1.3.x due to MASPECTJ-90 and do not use 1.4 
        due to declare parents issue --> 
       <dependencies> 
        <!-- NB: You must use Maven 2.0.9 or above or these are ignored (see 
         MNG-2972) --> 
        <dependency> 
         <groupId>org.aspectj</groupId> 
         <artifactId>aspectjrt</artifactId> 
         <version>${version.aspectj}</version> 
        </dependency> 
        <dependency> 
         <groupId>org.aspectj</groupId> 
         <artifactId>aspectjtools</artifactId> 
         <version>${version.aspectj}</version> 
        </dependency> 
       </dependencies> 
       <executions> 
        <execution> 
         <goals> 
          <goal>compile</goal> 
          <goal>test-compile</goal> 
         </goals> 
        </execution> 
       </executions> 
       <configuration> 
        <outxml>true</outxml> 
        <aspectLibraries> 
         <aspectLibrary> 
          <groupId>org.springframework</groupId> 
          <artifactId>spring-aspects</artifactId> 
         </aspectLibrary> 
        </aspectLibraries> 
        <source>${version.java}</source> 
        <target>${version.java}</target> 
       </configuration> 
      </plugin> 
相關問題