2011-11-14 9 views
5

Modifica: RISOLTO Giusto. Ho trovato la cosa che mi ha confuso. Io uso pgadmin per creare tabelle e altri interni del database, controllati adesso: se almeno una lettera nel nome (nome tabella, nome colonna, nome pk, ecc.) È in maiuscolo, quindi pgadmin la usa nella creazione SQL script così com'è, usando virgolette doppie, quindi PostgreSQL interpreta il nome così come è stato scritto. Se si esegue il seguente script:JPA con Hibernate 3.6.8.Final, PostgresSQL 9.1, SQLGrammarException - problema di configurazione? Strana dichiarazione 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;_ 

crea tutto nel minuscolo e la versione originale di Sample.java funziona correttamente.


Cosa c'è di sbagliato qui? Questo problema è specifico per PostgreSQL 9.1 o PostgreSQL in generale, oppure manca qualche configurazione di sospensione?

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

Eccezione:

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

Ovviamente, questa istruzione SQL di cui sopra:

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

non viene eseguito con successo dal PostgreSQL stesso (da pgAdmin) .

Ma, se cambio Sample.java a:

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

che è strano, funziona.

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 inutile qui, o non funziona correttamente con PostgreSQL 9.1? Inoltre, mi piacerebbe non digitare i nomi delle colonne se sono uguali al campo, ma in maiuscolo è anche possibile?

Grazie.

+0

Se si rimuove la proprietà relativa al dialetto in ibernazione, funzionerà? AFAIR il costrutto '@Entity (\" "..." \ ")' costringe il provider JPA a usare il valore esatto fornito (ad esempio, usa il caso esatto del nome della tabella). Non so perché nel tuo caso fa un po 'di magia. –

+0

Ho provato senza dialetto, il sample.java originale non funziona, i lavori modificati, ho anche provato ad usare il dialetto MySQL invece di PostgreSQL, giusto per aspettarmi di vedere avvertimenti o errori, il risultato è lo stesso, sembra che a) dialetto viene ignorato b) il dialetto non viene utilizzato durante la costruzione di query SQL, ma probabilmente solo per il comportamento specifico del fornitore, ad esempio la paginazione. – akazlou

+0

e se si provasse a utilizzare le proprietà JPA per la connessione JDBC (http://www.vogella.de/articles/JavaPersistenceAPI/article.html#example_persistenceunit) e rimuovere le proprietà relative a dialect e hibernate? Qual è il nome esatto della tabella nel tuo DB? sceneggiatura –

risposta

4

Il costrutto @Table("\"...\"") consiste nel forzare il provider JPA a utilizzare il valore esatto fornito (ad esempio, utilizzare il caso esatto del nome della tabella).

Inoltre, è simile nel mondo PostgreSQL.Se invochi CREATE TABLE e specifichi il nome della tabella tra virgolette, creerai la tabella con il nome esatto specificato (non solo il caso ma anche la semantica - in questo modo puoi anche creare una tabella denominata TABLE):

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

corrisponderà alla tabella TeSt8.

CREATE TABLE TeSt2 (id int PRIMARY KEY NOT NULL) 

si tradurrà in tabella test2.

Quindi, per eseguire una query per la tabella "test" è necessario eseguire SELECT * FROM "TeSt" (non SELECT * FROM TeSt).

Quindi, se si crea una tabella con CREATE TABLE "SAMPLE" è necessario specificare @Table(name="\"SAMPLE\"") per farlo funzionare.

+0

Aggiunta spiegazione all'intestazione della mia domanda. Grazie. – akazlou

Problemi correlati