2011-11-14 30 views
5

Chỉnh sửa: SOLVED Phải. Tôi tìm thấy thứ khiến tôi bối rối. Tôi sử dụng pgadmin để tạo bảng và các nội dung cơ sở dữ liệu khác, được kiểm tra ngay bây giờ: nếu ít nhất một chữ cái trong tên (tên bảng, tên cột, tên pk, v.v.) nằm trong chữ hoa, thì pgadmin sử dụng nó trong quá trình tạo SQL kịch bản như vậy, sử dụng dấu ngoặc kép, vì vậy PostgreSQL diễn giải tên như được viết. Nếu chạy tập lệnh sau:JPA với Hibernate 3.6.8.Final, PostgresSQL 9.1, SQLGrammarException - vấn đề cấu hình? Câu lệnh SQL Weird

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

nó tạo mọi thứ trong trường hợp thấp hơn và phiên bản Sample.java gốc hoạt động tốt.


Có gì sai ở đây? Vấn đề này có cụ thể đối với PostgreSQL 9.1 hoặc PostgreSQL nói chung hay thiếu một số cấu hình ngủ đông không?

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

Ngoại lệ:

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

Rõ ràng, câu lệnh SQL này trên:

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

không được thực hiện thành công từ PostgreSQL bản thân (từ pgAdmin) .

Nhưng, nếu tôi thay đổi Sample.java tới:

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

đó là lạ, nó hoạt động.

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

Có phải hibernate.dialect vô dụng ở đây hoặc không hoạt động bình thường với PostgreSQL 9.1? Ngoài ra, tôi không muốn nhập tên cột nếu chúng giống với trường, nhưng trong trường hợp trên, nó cũng có thể không?

Cảm ơn bạn.

+0

Nếu bạn xóa thuộc tính liên quan đến phương ngữ ngủ đông - nó có hoạt động không? AFAIR cấu trúc '@Entity (\" "..." \ ")' là buộc nhà cung cấp JPA sử dụng giá trị chính xác được cung cấp (tức là sử dụng trường hợp chính xác của tên bảng). Không biết tại sao trong trường hợp của bạn nó làm một số phép thuật. –

+0

Tôi đã thử mà không có phương ngữ, Sample.java ban đầu không hoạt động, công việc sửa đổi, cũng đã cố gắng sử dụng phương ngữ MySQL thay vì PostgreSQL, chỉ để mong đợi để xem cảnh báo hoặc lỗi, kết quả là như nhau, có vẻ như là a) được bỏ qua b) phương ngữ không được sử dụng trong khi xây dựng các truy vấn SQL, nhưng có lẽ chỉ dành cho hành vi của nhà cung cấp cụ thể, chẳng hạn như phân trang, chẳng hạn. – akazlou

+0

và điều gì sẽ xảy ra nếu bạn thử sử dụng các thuộc tính JPA cho kết nối JDBC (http://www.vogella.de/articles/JavaPersistenceAPI/article.html#example_persistenceunit) và loại bỏ các thuộc tính liên quan đến phương ngữ và ngủ đông? Tên bảng chính xác trong DB của bạn là gì? –

Trả lời

4

Cấu trúc @Table("\"...\"") là buộc nhà cung cấp JPA sử dụng giá trị chính xác mà bạn cung cấp (ví dụ: sử dụng trường hợp chính xác của tên bảng).

Hơn nữa, nó tương tự trong thế giới PostgreSQL.Nếu bạn gọi CREATE TABLE và chỉ định tên bảng trong dấu ngoặc kép, nó sẽ tạo bảng có tên chính xác mà bạn chỉ định (không chỉ trường hợp mà còn là ngữ nghĩa - theo cách này bạn có thể tạo bảng có tên TABLE):

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

sẽ cho kết quả trong bảng TeSt8.

CREATE TABLE TeSt2 (id int PRIMARY KEY NOT NULL) 

sẽ dẫn đến bảng test2.

Do đó, để truy vấn bảng "TeSt", bạn cần phải thực thi SELECT * FROM "TeSt" (khôngSELECT * FROM TeSt).

Vì vậy, nếu bạn tạo một bảng với CREATE TABLE "SAMPLE" bạn cần phải chỉ định @Table(name="\"SAMPLE\"") để làm cho nó hoạt động.

+0

Đã thêm giải thích cho tiêu đề của câu hỏi của tôi. Cảm ơn bạn. – akazlou

Các vấn đề liên quan