我在项目中使用Eclipselink作为JPA实现。
我正在尝试使用此处所述的复合持久性单元http://wiki.eclipse.org/EclipseLink/Examples/JPA/Composite。
我创建了两个实体ToDo和Diary,它们单独运行,具有自己的持久性单元,并且仍然使用复合持久性单元。
然后我在日记实体中添加了一个新字段,应用程序开始显示问题。所以我想我会放弃这张桌子,以便JPA自动添加新字段。
但是,当我删除创建的数据库表并尝试再次运行该示例时,它将不会按原样重新创建表。
这是我的复合持久性单元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="compositePU">
<provider>
org.eclipse.persistence.jpa.PersistenceProvider
</provider>
<jar-file>todo.jar</jar-file>
<jar-file>diary.jar</jar-file>
<properties>
<property name="eclipselink.ddl-generation" value="create-or-extend-tables" />
<property name="eclipselink.composite-unit" value="true" />
<property name="javax.persistence.schema-generation.database.action"
value="create" />
</properties>
</persistence-unit>
</persistence>
我在Apache Tomcat 7上使用它并使用Eclipselink 2.5。
这是我现在得到的错误:
HTTP Status 500 - Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.DatabaseException
--------------------------------------------------------------------------------
type Exception report
message Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.DatabaseException
description The server encountered an internal error that prevented it from fulfilling this request.
exception
javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'testdb.todo' doesn't exist
Error Code: 1146
Call: INSERT INTO TODO (DESCRIPTION, NAME) VALUES (?, ?)
bind => [2 parameters bound]
Query: InsertObjectQuery(todo.ToDo@3ba3441d)
org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:157)
com.lladmotors.test.AddToDo.doPost(AddToDo.java:64)
com.lladmotors.test.AddToDo.doGet(AddToDo.java:41)
javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'testdb.todo' doesn't exist
Error Code: 1146
Call: INSERT INTO TODO (DESCRIPTION, NAME) VALUES (?, ?)
bind => [2 parameters bound]
Query: InsertObjectQuery(todo.ToDo@3ba3441d)
org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:331)
org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:900)
org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:962)
org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:631)
org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1991)
org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:298)
org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:377)
org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:165)
org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:180)
org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:489)
org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:80)
org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:90)
org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:301)
org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:798)
org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1793)
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1775)
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1726)
org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:226)
org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:125)
org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:4196)
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1441)
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531)
org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:277)
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169)
org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132)
com.lladmotors.test.AddToDo.doPost(AddToDo.java:64)
com.lladmotors.test.AddToDo.doGet(AddToDo.java:41)
javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'testdb.todo' doesn't exist
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
java.lang.reflect.Constructor.newInstance(Unknown Source)
com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
com.mysql.jdbc.Util.getInstance(Util.java:384)
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1052)
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4232)
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4164)
com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2615)
com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2776)
com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2838)
com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2082)
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2334)
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2262)
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2246)
org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:890)
org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:962)
org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:631)
org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1991)
org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:298)
org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:377)
org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:165)
org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:180)
org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:489)
org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:80)
org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:90)
org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:301)
org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:58)
org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:798)
org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1793)
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1775)
org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1726)
org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:226)
org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:125)
org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:4196)
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1441)
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531)
org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:277)
org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169)
org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132)
com.lladmotors.test.AddToDo.doPost(AddToDo.java:64)
com.lladmotors.test.AddToDo.doGet(AddToDo.java:41)
javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.72 logs.
--------------------------------------------------------------------------------
Apache Tomcat/7.0.72
这是我用来添加记录的代码
package com.lladmotors.test;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import todo.ToDo;
import com.lladmotors.diary.Diary;
public class AddToDo extends HttpServlet {
private static final long serialVersionUID = 1L;
public AddToDo() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// Call the doPost method
doPost(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// create a new To Do
//EntityManagerFactory factory = Persistence
// .createEntityManagerFactory("todo");
//EntityManager em = factory.createEntityManager();
EntityManagerFactory factory = Persistence
.createEntityManagerFactory("compositePU");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
ToDo toDo = new ToDo();
toDo.setName(request.getParameter("name")+"via Servlet");
toDo.setDescription(request.getParameter("description") + "via Servlet");
em.persist(toDo);
em.getTransaction().commit();
// display a list of To Do.
Query q = em.createQuery("select t from ToDo t");
@SuppressWarnings("unchecked")
List<ToDo> todoList = (List<ToDo>) q.getResultList();
for (ToDo todo : todoList) {
response.getWriter().println(
todo.getId() + todo.getName() + todo.getDescription() + "<br>");
}
//em.close();
// create a new To Do
//EntityManagerFactory factory2 = Persistence
// .createEntityManagerFactory("diary");
//EntityManager em2 = factory2.createEntityManager();
em.getTransaction().begin();
Diary diary = new Diary();
diary.setName(request.getParameter("name"));
diary.setDetails(request.getParameter("description"));
diary.setTodo(toDo);
Date date = new Date();
diary.setDate(date);
em.persist(diary);
em.getTransaction().commit();
// display a list of To Do.
Query q2 = em.createQuery("select d from Diary d");
@SuppressWarnings("unchecked")
List<Diary> diaryList = (List<Diary>) q2.getResultList();
for (Diary entry : diaryList) {
response.getWriter().println(
entry.getId() + entry.getName() + entry.getDetails()
+ entry.getDate() + entry.getTodo().getDescription()
+"<br>");
}
em.close();
}
}
答案 0 :(得分:2)
我添加了以下persistence.xml文件属性,现在运行良好。如果要通过复合持久性单元对数据库进行更改,我认为您还必须在复合单元的persistence.xml中包含数据库访问详细信息。
我认为复合单元persistence.xml使用包含的JPA项目中persistence.xml文件中的数据在内存中创建一个persistence.xml(就像maven一样,带有'POM)
<?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="compositePU">
<jar-file>todo.jar</jar-file>
<jar-file>diary.jar</jar-file>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/testdb" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="root" />
<property name="eclipselink.logging.level" value="ALL" />
<property name="eclipselink.logging.level.jpa" value="ALL" />
<property name="eclipselink.logging.level.ddl" value="ALL" />
<property name="eclipselink.logging.level.connection" value="ALL" />
<property name="eclipselink.logging.level.sql" value="ALL" />
<property name="eclipselink.logging.level.transaction"
value="ALL" />
<property name="eclipselink.logging.level.sequencing" value="ALL" />
<property name="eclipselink.logging.level.server" value="ALL" />
<property name="eclipselink.logging.level.query" value="ALL" />
<property name="eclipselink.logging.level.properties" value="ALL" />
<property name="eclipselink.ddl-generation" value="create-or-extend-tables" />
<property name="eclipselink.ddl-generation.output-mode"
value="database" />
<property name="javax.persistence.schema-generation.database.action"
value="create" />
</properties>
</persistence-unit>
</persistence>
答案 1 :(得分:1)
您正在混合DDL生成的EclipseLink特定配置和JPA 2.1配置。
使用eclipselink.ddl-generation
进行配置。 documentation个州,您只能在create-or-extend-tables
时使用eclipselink.ddl-generation.output-mode = database
。第一个例子中缺少这个。
specification概括了模式生成。使用javax.persistence.schema-generation.database.action
。有效值为none, create, drop-and-create, drop
。但是,EclipseLink对此属性接受create-or-extend-tables
但不接受none
。
仅使用EclipseLink或JPA 2.1配置属性。