2011-11-14 15 views
5

Editar: SOLUCIONADO derecho. Encontré lo que me confundió. Utilizo pgadmin para crear tablas y otras internas de la base de datos, comprobadas ahora: si al menos una letra en el nombre (nombre de la tabla, nombre de la columna, pk, etc.) está en mayúsculas, pgadmin lo usa en la creación del SQL secuencia de comandos tal como está, utilizando comillas dobles, por lo que PostgreSQL interpreta el nombre tal como fue escrito. Si se ejecuta el siguiente script:JPA con Hibernate 3.6.8.Final, PostgresSQL 9.1, SQLGrammarException - ¿problema de configuración? sentencia SQL raro

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

que crea todo en el caso más bajo, y la versión original Sample.java funciona bien.


¿Qué sucede aquí? ¿Este problema es específico de PostgreSQL 9.1 o PostgreSQL en general, o falta alguna configuración de hibernación?

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

Excepción:

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

Obviamente, esta sentencia SQL anterior:

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

no se ejecuta con éxito de la misma PostgreSQL (de pgadmin) .

Pero, si cambio a 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; 
    } 
} 

lo cual es raro, funciona.

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

Es hibernate.dialect inútil aquí, o no funciona correctamente con PostgreSQL 9.1? Además, me gustaría no escribir nombres de columnas si son los mismos que en el campo, pero en mayúsculas, ¿también es posible?

Gracias.

+0

Si elimina la propiedad relacionada con el dialecto de hibernación, ¿funcionará? AFAIR el constructo '@Entity (\" "..." \ ")' es forzar al proveedor de JPA a utilizar el valor exacto proporcionado (es decir, usar el caso exacto del nombre de la tabla). No sé por qué en tu caso hace algo de magia. –

+0

Probé sin dialecto, el Sample.java original no funciona, modifiqué trabajos, también intenté usar el dialecto MySQL en lugar de PostgreSQL, solo para esperar ver advertencias o errores, el resultado es el mismo, parece que a) el dialecto se ignora b) el dialecto no se usa al construir consultas SQL, pero probablemente solo para el comportamiento específico del proveedor, como la paginación, por ejemplo. – akazlou

+0

y ¿qué pasa si intentas usar las propiedades JPA para la conexión JDBC (http://www.vogella.de/articles/JavaPersistenceAPI/article.html#example_persistenceunit) y eliminas las propiedades relacionadas con el dialecto y la hibernación? ¿Cuál es el nombre exacto de la tabla en tu DB? guión –

Respuesta

4

El constructo @Table("\"...\"") obliga al proveedor de JPA a usar el valor exacto que usted proporciona (es decir, usa el nombre exacto de la tabla).

Además, es similar en el mundo de PostgreSQL.Si invoca CREATE TABLE y especifica el nombre de la tabla entre comillas, creará la tabla con el nombre exacto que especifique (no solo el caso sino también la semántica, de esta manera puede crear una tabla llamada TABLE):

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

dará como resultado la tabla TeSt8.

CREATE TABLE TeSt2 (id int PRIMARY KEY NOT NULL) 

se traducirá en la tabla test2 .

Por lo tanto, para consultar la tabla "prueba" que tendrá que ejecutar SELECT * FROM "TeSt" (noSELECT * FROM TeSt).

Por lo tanto, si crea una tabla con CREATE TABLE "SAMPLE", debe especificar @Table(name="\"SAMPLE\"") para que funcione.

+0

Explicación adicional al encabezado de mi pregunta. Gracias. – akazlou

Cuestiones relacionadas