2011-11-14 5 views
5

編集解決しよう 右。私は私を混乱させるものを見つけた。 pgadminを使用してテーブルやその他のデータベースの内部構造を作成します。名前を少なくとも1文字(テーブル名、カラム名、pk名など)が大文字である場合、pgadminはSQL作成でそれを使用しますPostgreSQLは書かれたとおりに名前を解釈します。次のスクリプトを実行する場合:JPA、Hibernate 3.6.8.Final、PostgresSQL 9.1、SQLGrammarException - 設定上の問題?奇妙なSQL文

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;_ 

すべて小文字で作成され、元のSample.javaのバージョンは正常に動作します。


ここで何が間違っていますか?この問題は、PostgreSQL 9.1またはPostgreSQL全般に固有のものか、一部の休止状態の設定が欠落していますか?

の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> 

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; 
    } 
} 

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(); 
    } 
} 

例外:

... 
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 
... 

明らかに、上記のこのSQL文:

select 
    sample0_.ID as ID0_0_, 
    sample0_.TITLE as TITLE0_0_ 
from 
    SAMPLE sample0_ 
where 
    sample0_.ID=? 

が(pgAdminでから)はPostgreSQL自体から正常に実行されていません。私は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; 
    } 
} 

、それが動作します。

Hibernate: 
    select 
     sample0_."ID" as ID1_0_0_, 
     sample0_."TITLE" as TITLE2_0_0_ 
    from 
     "SAMPLE" sample0_ 
    where 
     sample0_."ID"=? 
Sample Title: Sample 

ここではhibernate.dialectは役に立たないのでしょうか、それともPostgreSQL 9.1では正しく動作しませんか? また、フィールドと同じ場合は列名を入力しませんが、大文字でも可能ですか?

ありがとうございます。

+0

休止状態の方言関連のプロパティを削除した場合、それは機能しますか? AFAIR '@Entity(\" "..." \ ")'構造体は、JPAプロバイダに指定された正確な値を使用させる(つまり、テーブル名の大文字小文字を使用する)よう強制します。なぜあなたのケースでそれはいくつかの魔法を行うか分からない。 –

+0

私はDialectを使わずに試してみました。元のSample.javaは動作しませんでした。修正された動作もPostgreSQLの代わりにMySQLの方言を使用しようとしましたが、警告やエラーを見ることを期待していました。 b)ダイアレクトはSQLクエリを構築する際には使用されませんが、おそらくページネーションなどのベンダー固有の動作に対してのみ使用されます。 – akazlou

+0

と、JDBC接続(http://www.vogella.de/articles/JavaPersistenceAPI/article.html#example_persistenceunit)にJPAプロパティを使用して、方言と休止状態に関連するプロパティを削除しようとするとどうなりますか?あなたのDBの正確なテーブル名は何ですか? –

答えて

4

@Table("\"...\"")のコンストラクタは、指定した正確な値を使用するようにJPAプロバイダを強制します(つまり、テーブル名の大文字と小文字を使用する)。

また、PostgreSQLの世界でも同様です。CREATE TABLEを呼び出して、引用符で表名を指定すると、指定した正確な名前の表が作成されます(このようにして、表という名前の表も作成できます)。

CREATE TABLE "TeSt" (id int PRIMARY KEY NOT NULL) 

は、テーブルTeSt8になります。

CREATE TABLE TeSt2 (id int PRIMARY KEY NOT NULL) 

はテーブルTEST2になります。

したがって、「テスト」の表を照会するために、あなたはSELECT * FROM "TeSt"ないSELECT * FROM TeSt)を実行する必要があります。

CREATE TABLE "SAMPLE"でテーブルを作成する場合は、テーブルを作成するには@Table(name="\"SAMPLE\"")を指定する必要があります。

+0

私の質問のヘッダに説明を追加しました。 ありがとうございます。 – akazlou