@NamedQuery 将表/列名称更改为大写导致异常

Posted

技术标签:

【中文标题】@NamedQuery 将表/列名称更改为大写导致异常【英文标题】:@NamedQuery changes table/column name to upper case causing exepction 【发布时间】:2016-04-06 01:05:51 【问题描述】:

我在 mysql 中有一个名为 Course 的表,我的 Course.java 类中有以下内容

package pckt.book.ch7.jpa;

import java.io.Serializable;
import javax.persistence.*;


/**
 * The persistent class for the Course database table.
 * 
 */
@Entity
@NamedQuery(name="Course.findAll", query="SELECT c FROM Course c")
public class Course implements Serializable 
    private static final long serialVersionUID = 1L;

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

    private int credits;

    private String name;

    @Column(name="Teacher_id")
    private int teacher_id;

    public Course() 
    

    public int getId() 
        return this.id;
    

    public void setId(int id) 
        this.id = id;
    

    public int getCredits() 
        return this.credits;
    

    public void setCredits(int credits) 
        this.credits = credits;
    

    public String getName() 
        return this.name;
    

    public void setName(String name) 
        this.name = name;
    

    public int getTeacher_id() 
        return this.teacher_id;
    

    public void setTeacher_id(int teacher_id) 
        this.teacher_id = teacher_id;
    


我正在另一个类中运行如下查询

@PersistenceContext
EntityManager entityManager;

public List<Course> getCourseEntities()
    //Use named query created in Course entitiy
    //using @NamedQuery annotation
    TypedQuery<Course> courseQuery = entityManager.createNamedQuery("Course.findAll",Course.class);
    return courseQuery.getResultList();

我收到以下错误:

javax.persistence.PersistenceException: Exception [EclipseLink-4002]     (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd):     org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table   'course_management.COURSE' doesn't exist
Error Code: 1146
Call: SELECT ID, CREDITS, NAME, Teacher_id FROM COURSE
Query: ReadAllQuery(name="Course.findAll" referenceClass=Course sql="SELECT ID, CREDITS, NAME, Teacher_id FROM COURSE")

通过阅读错误,听起来问题是@NamedQuery 生成的查询是大写的,因此找不到 COURSE 表。

在 my.cnf 我有 lower_case_table_names=2 但不确定这是否会有所作为。

我的persistance.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="CourseManagementEJB">
        <jta-data-source>jdbc/CourseManagement</jta-data-source>
        <class>pckt.book.ch7.jpa.Course</class>
    </persistence-unit>
</persistence>

jdbc/CourseManagement 是 GlassFish 中的 JNDI 资源,它指向 course_management 数据库的连接池,其中 Course 是一个表。我知道我可以成功连接到数据库,因为我可以 ping 通它。

问题:

    是否期望将查询转换为大写? 如何解决此问题?

我确实对此进行了一些研究,但找不到适合我的情况的任何内容。一些解决方案建议更改表名(我不能这样做)或更改 DAO 类名,这也不是我的情况。

【问题讨论】:

你能发布你的课程课程和persistence.xml吗? @Abdelhak 我已将它们添加到问题中。 取决于您的 JPA 提供程序如何允许您选择大写、小写或区分大小写的表名。也许它有一个持久性属性来做到这一点。 MySQL 允许区分大小写,但如果敏感,则必须在表名周围加上引号 lower_case_table_names 如果设置为 0,则按指定存储表名,并且比较区分大小写。如果设置为 1,则表名以小写形式存储在磁盘上,并且比较不区分大小写。如果设置为 2,则表名按给定方式存储,但以小写形式进行比较。此选项也适用于数据库名称和表别名 @NarendraJaggi 也许你应该指定什么是“lower_case_table_names”而不是仅仅假设他知道你的意思......一些 MySQL 连接属性?一些 EclipseLink 持久性属性? 【参考方案1】:

@Table 注释中使用反引号使 JPA 使用区分大小写的名称:

@Entity
@Table(name="`Course`")
@NamedQuery(name="Course.findAll", query="SELECT c FROM Course c")
public class Course implements Serializable  ...

显然,您必须使用数据库中使用的真实姓名。例如。如果名称全部小写,请使用:

@Table(name="`course`")

【讨论】:

“Course”不是表名,是实体名。 “Course”既是表名也是实体名。 @NeilStockton:我知道这不可能那么容易。嗯。我永远不会习惯写 JPQL... 原来就是这样。【参考方案2】:

阅读您的例外情况:

 Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table   'course_management.COURSE' doesn't exist

检查您的 persistence.xml 文件,即您用于存储数据库的名称。

确保您不要手动创建表

【讨论】:

我已将此添加到问题中。 您能否指出任何说明这一点的文档?所以你是说我不能使用已经存在的数据库?那将是一个巨大而荒谬的限制。 他的意思是,您的表元数据与您创建的表不一致。最简单的方法是让 JPA 实现创建 DDL,然后应用它,或者更新 JPA 注释以解决问题 对不起,我不明白,这个元数据在哪里,为什么会不一致?我无法更改表名或创建新表,因此我需要它以某种方式与现有表一起使用。 请尝试使用 Mysql dbms 查询您的表,并在您的异常中查询:SELECT ID, CREDITS, NAME, Teacher_id FROM COURSE,看看它是否有效

以上是关于@NamedQuery 将表/列名称更改为大写导致异常的主要内容,如果未能解决你的问题,请参考以下文章

将 Hive 外部表列名称更改为大写并添加新列

将 Amazon RDS 表名重命名为大写字母会引发错误

如何将数据表的标题名称/列名称更改为 dataGridView

Oracle SQL 在包含数据时将列类型从数字更改为 varchar2

top命令排序快捷键

如何将表列从十进制更改为 varchar [重复]