簡體   English   中英

手動刪除表后,Eclipselink無法在MySQL數據庫中創建表

[英]Eclipselink fails to create tables in MySQL database after manually dropping the tables

我在項目中使用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();
    }

}

我添加了以下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>

您正在混合DDL生成的EclipseLink特定配置和JPA 2.1配置。

EclipseLink

使用eclipselink.ddl-generation配置。 文檔指出,僅當eclipselink.ddl-generation.output-mode = database時,才能使用create-or-extend-tables 您的第一個示例中缺少此功能。

JPA 2.1

規范概括了模式生成。 使用javax.persistence.schema-generation.database.action 有效值為none, create, drop-and-create, drop 但是,EclipseLink接受create-or-extend-tables但此屬性none接受。

僅使用EclipseLink或JPA 2.1配置屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM