JPA与Hibernate 3.6.8.Final,PostgreSQL 9.1,SQLGrammarException - 配置问题?奇怪的SQL语句

aka*_*lou 5 hibernate jpa postgresql-9.1

编辑:已 解决 .我找到了困扰我的事情.我使用pgadmin创建表和其他数据库内部,立即检查:如果名称中至少有一个字母(表名,列名,pk名称等)是大写的,那么pgadmin在SQL创建脚本中使用它实际上,使用双引号,因此PostgreSQL会在编写时解释名称.如果运行以下脚本:

CREATE TABLE SAMPLE
(
  ID integer NOT NULL,
  TITLE character varying(100) NOT NULL,
  CONSTRAINT SAMPLE_ID_PK PRIMARY KEY (ID)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE SAMPLE
  OWNER TO postgres;_
Run Code Online (Sandbox Code Playgroud)

它以小写形式创建所有内容,原始的Sample.java版本工作正常.


这有什么不对?这个问题一般特定于PostgreSQL 9.1或PostgreSQL,还是缺少一些hibernate配置?

persistence.xml中:

<persistence-unit name="com.sample.persistence.jpa" transaction-type="RESOURCE_LOCAL">
    <class>com.sample.persistence.Sample</class>
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
        <property name="hibernate.connection.url" value="jdbc:postgresql:sample"/>
        <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
        <property name="hibernate.connection.username" value="postgres"/>
        <property name="hibernate.connection.password" value="postgres"/>
        <property name="hibernate.show_sql" value="true"/>
        <property name="hibernate.format_sql" value="true"/>
        <property name="hbm2ddl.auto" value="update"/>
    </properties>
</persistence-unit>
Run Code Online (Sandbox Code Playgroud)

Sample.java:

@Entity
@Table(name = "SAMPLE")
public class Sample {

    @Id
    @Column(name = "ID")
    private long id;

    @Column(name = "TITLE")
    private String title;

    public String getTitle() {
        return title;
    }
}
Run Code Online (Sandbox Code Playgroud)

PersistenceMain.java:

public class PersistenceMain {


    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("com.sample.persistence.jpa");
        EntityManager em = emf.createEntityManager();

        Sample sample = em.find(Sample.class, 1l);

        System.out.println("Sample Title: " + sample.getTitle());

        em.close();

        emf.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

例外:

...
Hibernate: 
    select
        sample0_.ID as ID0_0_,
        sample0_.TITLE as TITLE0_0_ 
    from
        SAMPLE sample0_ 
    where
        sample0_.ID=?
Exception in thread "main" javax.persistence.PersistenceException:     org.hibernate.exception.SQLGrammarException: could not load an entity:   [com.sample.persistence.Sample#1]
 ...
Caused by: org.postgresql.util.PSQLException: ERROR: relation "sample" does not exist
 ...
Run Code Online (Sandbox Code Playgroud)

显然,这个SQL语句如上:

select
    sample0_.ID as ID0_0_,
    sample0_.TITLE as TITLE0_0_ 
from
    SAMPLE sample0_ 
where
    sample0_.ID=?
Run Code Online (Sandbox Code Playgroud)

从PostgreSQL本身(来自pgadmin)未成功执行.

但是,如果我将Sample.java更改为:

@Entity
@Table(name = "\"SAMPLE\"")
public class Sample {

    @Id
    @Column(name = "\"ID\"")
    private long id;

    @Column(name = "\"TITLE\"")
    private String title;

    public String getTitle() {
        return title;
    }
}
Run Code Online (Sandbox Code Playgroud)

这很奇怪,很有效.

Hibernate: 
    select
        sample0_."ID" as ID1_0_0_,
        sample0_."TITLE" as TITLE2_0_0_ 
    from
        "SAMPLE" sample0_ 
    where
        sample0_."ID"=?
Sample Title: Sample
Run Code Online (Sandbox Code Playgroud)

hibernate.dialect在这里没用,或者它与PostgreSQL 9.1无法正常工作?此外,如果列名称与字段相同,我不想键入列名称,但在大写字母中,是否也可以?

谢谢.

Pio*_*cki 4

@Table("\"...\"")构造是强制 JPA 提供程序使用您提供的确切值(即使用表名的确切大小写)。

而且,在 PostgreSQL 世界中也是类似的。如果您CREATE TABLE在引号中调用并指定表名称,那么它将创建具有您指定的确切名称的表(不仅是大小写,而且还有语义 - 通过这种方式,您甚至可以创建一个名为 TABLE 的表):

CREATE TABLE "TeSt" ( id int PRIMARY KEY NOT NULL )
Run Code Online (Sandbox Code Playgroud)

将生成表TeSt8

CREATE TABLE TeSt2 ( id int PRIMARY KEY NOT NULL )
Run Code Online (Sandbox Code Playgroud)

将产生表test2

因此,要查询“TeSt”表,您将需要执行SELECT * FROM "TeSt"而不是 SELECT * FROM TeSt)。

因此,如果您创建一个表,则CREATE TABLE "SAMPLE"需要指定@Table(name="\"SAMPLE\"")才能使其正常工作。