使用 JPA 会产生 SQL 语法错误

问题描述

我正在编写一个访问数据库 (MariaDB) 的简单 Java 程序。

运行时,我总是遇到一个错误,说Table ...不存在。 之所以如此,是因为当 JPA 调用 CREATE TABLE 语句时,它使用 NUMBER(n) 作为我类中声明为 int 的字段的类型。这会导致语法错误并且不会创建表。因此,在尝试将新用户插入数据库时​​会发生错误。用 NUMBERINT 替换 DECIMAL 工作正常。

我认为 MariaDB 驱动程序会处理它。

错误

Exception in thread "AWT-EventQueue-0" jakarta.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 3.0.0.v202012081010): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.sqlSyntaxErrorException: (conn=68) Table 'dbtest.user' doesn't exist
Error Code: 1146
Call: INSERT INTO User (ID,eMail,username,password) VALUES (?,?,?)

完整的堆栈跟踪:

Exception in thread "AWT-EventQueue-0" jakarta.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 3.0.0.v202012081010): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.sqlSyntaxErrorException: (conn=68) Table 'dbtest.user' doesn't exist
Error Code: 1146
Call: INSERT INTO User (ID,?)
    bind => [4 parameters bound]
Query: InsertObjectQuery(db.models.User@1b9b0b25)
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:163)
    at db.Connector.registerUser(Connector.java:15)
    at UI.Register_User$1.actionPerformed(Register_User.java:40)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setpressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6614)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
    at java.desktop/java.awt.Component.processEvent(Component.java:6379)
    at java.desktop/java.awt.Container.processEvent(Container.java:2263)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4990)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4822)
    at java.desktop/java.awt.Lightweightdispatcher.retargetMouseEvent(Container.java:4919)
    at java.desktop/java.awt.Lightweightdispatcher.processMouseEvent(Container.java:4548)
    at java.desktop/java.awt.Lightweightdispatcher.dispatchEvent(Container.java:4489)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2769)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4822)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
    at java.desktop/java.awt.EventdispatchThread.pumpOneEventForFilters(EventdispatchThread.java:203)
    at java.desktop/java.awt.EventdispatchThread.pumpEventsForFilter(EventdispatchThread.java:124)
    at java.desktop/java.awt.EventdispatchThread.pumpEventsForHierarchy(EventdispatchThread.java:113)
    at java.desktop/java.awt.EventdispatchThread.pumpEvents(EventdispatchThread.java:109)
    at java.desktop/java.awt.EventdispatchThread.pumpEvents(EventdispatchThread.java:101)
    at java.desktop/java.awt.EventdispatchThread.run(EventdispatchThread.java:90)
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 3.0.0.v202012081010): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.sqlSyntaxErrorException: (conn=68) Table 'dbtest.user' doesn't exist
Error Code: 1146
Call: INSERT INTO User (ID,?)
    bind => [4 parameters bound]
Query: InsertObjectQuery(db.models.User@1b9b0b25)
    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:334)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:908)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:970)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:640)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:567)
    at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2045)
    at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:312)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:282)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:268)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.insertObject(DatasourceCallQueryMechanism.java:421)
    at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:175)
    at org.eclipse.persistence.internal.queries.StatementQueryMechanism.insertObject(StatementQueryMechanism.java:191)
    at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:507)
    at org.eclipse.persistence.queries.InsertObjectQuery.executeCommit(InsertObjectQuery.java:83)
    at org.eclipse.persistence.queries.InsertObjectQuery.executeCommitWithChangeSet(InsertObjectQuery.java:94)
    at org.eclipse.persistence.internal.queries.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:319)
    at org.eclipse.persistence.queries.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:61)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:912)
    at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:811)
    at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:112)
    at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:89)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2984)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1844)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1826)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1776)
    at org.eclipse.persistence.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:248)
    at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:147)
    at org.eclipse.persistence.internal.sessions.AbstractSession.writeallObjectsWithChangeSet(AbstractSession.java:4329)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1496)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1586)
    at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:288)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1223)
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:138)
    ... 37 more
Caused by: java.sql.sqlSyntaxErrorException: (conn=68) Table 'dbtest.user' doesn't exist
    at org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.createException(ExceptionFactory.java:62)
    at org.mariadb.jdbc.internal.util.exceptions.ExceptionFactory.create(ExceptionFactory.java:153)
    at org.mariadb.jdbc.MariaDbStatement.executeExceptionEpilogue(MariaDbStatement.java:274)
    at org.mariadb.jdbc.ClientSidePreparedStatement.executeInternal(ClientSidePreparedStatement.java:229)
    at org.mariadb.jdbc.ClientSidePreparedStatement.execute(ClientSidePreparedStatement.java:149)
    at org.mariadb.jdbc.ClientSidePreparedStatement.executeUpdate(ClientSidePreparedStatement.java:181)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:898)
    ... 68 more
Caused by: org.mariadb.jdbc.internal.util.exceptions.MariaDbsqlException: Table 'dbtest.user' doesn't exist
    at org.mariadb.jdbc.internal.util.exceptions.MariaDbsqlException.of(MariaDbsqlException.java:34)
    at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.exceptionWithQuery(AbstractQueryProtocol.java:194)
    at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.exceptionWithQuery(AbstractQueryProtocol.java:177)
    at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.executeQuery(AbstractQueryProtocol.java:321)
    at org.mariadb.jdbc.ClientSidePreparedStatement.executeInternal(ClientSidePreparedStatement.java:220)
    ... 71 more
Caused by: java.sql.sqlException: Table 'dbtest.user' doesn't exist
    at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.readErrorPacket(AbstractQueryProtocol.java:1683)
    at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.readPacket(AbstractQueryProtocol.java:1545)
    at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.getResult(AbstractQueryProtocol.java:1508)
    at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.executeQuery(AbstractQueryProtocol.java:318)
    ... 72 more

创建语句:

Call: CREATE TABLE User (ID NUMBER(10) NOT NULL,eMail VARCHAR NOT NULL UNIQUE,username VARCHAR(60) NOT NULL UNIQUE,password NUMBER(10) NOT NULL,PRIMARY KEY (ID))
Query: DataModifyQuery(sql="CREATE TABLE User (ID NUMBER(10) NOT NULL,PRIMARY KEY (ID))")

用户类:

package db.models;

import jakarta.persistence.*;

@Entity
@Table(name = "User")
public class User {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(nullable = false,unique = true,length = 60,name = "username")
    private String name;

    @Column(nullable = false,name = "password")
    private int pass;

    @Column(nullable = false,name = "eMail")
    private String email;

    public User() {

    }

    public User(String name,int pass,String email) {
        this.name = name;
        this.pass = pass;
        this.email = email;
    }
}

导致错误函数

    public boolean registerUser(User u) {
        if(em.contains(u))
            return false;
        em.getTransaction().begin();
        em.persist(u);
        em.getTransaction().commit();
        em.close();
        return true;
    }

回答马克的评论,这是我的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="mariadb-localhost">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>db.models.User</class>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="jakarta.persistence.jdbc.driver" value="org.mariadb.jdbc.Driver"/>
            <property name="jakarta.persistence.jdbc.url" value="jdbc:mariadb://localhost:3306/dbtest"/>
            <property name="jakarta.persistence.jdbc.user" value="root"/>
            <property name="jakarta.persistence.jdbc.password" value="password"/>
            <property name="jakarta.persistence.schema-generation.database.action" value="drop-and-create"/>
            <property name="eclipselink.logging.level.sql" value="FINE"/>
            <property name="eclipselink.ddl-generation" value="create-tables"/>
            <!-- or just value="create-tables" -->
        </properties>
    </persistence-unit>

</persistence>

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...