我的EclipseLink和Spring(MVC和spring-data)版本3.1.1设置的另一个问题:
我试图让JPA在没有使用this article的persistence.xml文件的情况下工作。在文章中它说:
通常,JPA定义了一个持久性单元 META-INF / persistence.xml文件。从Spring 3.1开始,这个XML文件 不再需要 - LocalContainerEntityManagerFactoryBean 现在支持要扫描的包的'packagesToScan'属性 可以指定@Entity类。
persistence.xml文件是要删除的最后一段XML - 现在,JPA可以完全设置,没有XML。
我知道如果有人使用persistence.xml文件,那么这里的所有Entity类都应该在这里声明。但是,我正在尝试使用packagesToScan
属性。下面是完整的启动日志和向servlet发出一个请求后产生的错误,该请求最终尝试在数据库中创建新用户。它似乎没有认识到User
对象是一个实体。由于我对Spring没有什么经验,我想知道是否有人,首先可以发现我正在制造的错误,但除此之外,知道调试这个的最佳方法。我想知道EntityManagerFactory已经识别出哪些Entity对象。
我的备份选项是切换到使用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: com.proxi.user.User@5ca3ce3f is not a known entity type.] with root cause
java.lang.IllegalArgumentException: Object: com.proxi.user.User@5ca3ce3f 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)
root-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;
}
}
答案 0 :(得分:1)
内部异常:java.sql.SQLSyntaxErrorException:对象名称 已存在:USER in statement [CREATE TABLE user(id BIGINT 由默认为身份生成(从1开始,由1增加)不 NULL,first_name VARCHAR(255),last_name VARCHAR(255),PRIMARY KEY (ID))]
这似乎是问题所在:Spring / EclipseLink正在尝试创建一个已经存在的表。
尝试从xml上下文中删除此行:
<property name="generateDdl" value="true" />
答案 1 :(得分: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)
。
我认为后两点适用于我所遇到的问题。正如我所说,我可以让它工作没有测试代码片段的问题,但我尝试正确连接它的那一刻我遇到了问题。因此,没有任何其他答案,我认为这是我必须解决的问题。任何进一步的见解都欢迎,因为我觉得这不是一个非常令人满意的答案。
答案 2 :(得分:0)
项目中是否存在persistence.xml
文件?
如果是这种情况,请从项目中完全删除persistence.xml
。此文件以某种方式与packagesToScan
属性冲突,即使您未在配置中的任何位置明确提及它。我自己也遇到过这种特殊性。
答案 3 :(得分:0)
@chrisjleu你非常接近。我通过设置eclipse链接使用静态编织来实现它:
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>