2011-02-02 29 views
16

Tôi có một bảng trong Oracle nơi cột SC_CUR_CODE là CHAR (3)Hibernate bản địa truy vấn - char (3) cột

Khi tôi làm:

Query q2 = em.createNativeQuery("select sc_cur_code, sc_amount from sector_costs"); 

    q2.setMaxResults(10); 

    List<Object[]> rs2 = q2.getResultList(); 

    for (Object[] o : rs2) { 
     System.out.println(">>> cur=" + o[0]); 
    } 

tôi thấy cur=Ecur=U thay vì cur=EURcur=USD

o[0] là một java.lang.Character

Làm thế nào tôi có thể nhận được đầy đủ các valu e EURUSD?

Trả lời

34

Dường như giá trị đọc Hibernate của loại CHAR(n)Character. Cố gắng bỏ nó vào VARCHAR(n):

Query q2 = em.createNativeQuery(
    "select cast(sc_cur_code as VARCHAR2(3)), sc_amount from sector_costs"); 

Khi sử dụng Hibernate qua giao diện Session, bạn explcitly có thể thiết lập một loại kết quả với addScalar() thay (còn truy cập qua unwrap() trong JPA 2.0):

Query q2 = em.createNativeQuery(
    "select sc_cur_code, sc_amount from sector_costs"); 
q2.unwrap(SQLQuery.class).addScalar("sc_cur_code", StringType.INSTANCE); 

Có có rất nhiều vấn đề chưa được giải quyết liên quan đến vấn đề này trong Hibernate JIRA, bắt đầu từ HHH-2220.

Dưới đây là một lời giải thích bởi Max Rydahl Andersen từ bình luận HHH-2220 của:

Hiện nay Hibernate hỗ trợ một loại "automagic" ánh xạ từ kiểu SQL để Hibernate loại/Java - bởi vì trong nhiều sự mơ hồ trong việc làm lập bản đồ như vậy đôi khi sẽ không khớp với những gì bạn thực sự muốn. Đó là lý do tại sao chúng tôi luôn khuyên bạn nên sử dụng addScalar OR rõ ràng nếu bạn không muốn rằng tất cả các mã của bạn sử dụng subclassing của phương ngữ để ra lệnh của nhiều ánh xạ có thể bạn muốn.

Vấn đề với CHAR là vấn đề nhất, nhưng không dễ sửa - chúng ta cần registerType (loại, từ, đến, typename) để ánh xạ một dãy thay vì độ dài cụ thể ... nhưng thậm chí sau đó bạn có thể bump vào bản đồ ambiguities (Ví dụ đôi khi bạn muốn một mảng khác lần chuỗi vv) Do đó sử dụng .addScalar được khuyến khích cho bất kỳ truy vấn sql bản địa - tùy thuộc vào tự động phát hiện sẽ luôn luôn được nguy hiểm và chỉ nên được sử dụng đến mức tối thiểu.

Nếu bạn có truy vấn gốc được mô tả trong tệp cấu hình ánh xạ Hibernate, thì bạn cần xác định <return-scalar ...> cho mỗi giá trị được trả lại. Lưu ý: Bạn phải liệt kê tất cả các giá trị trả về, như khi bạn xác định kiểu trả về một cách rõ ràng, tự động phát hiện bị tắt và chỉ các cột được khai báo được trả về.

<sql-query name="myQuery"> 
    <query-param name="days" type="int" /> 
    <return-scalar column="count" type="int" /> 
    <return-scalar column="section_name" type="string" /> 
    <![CDATA[select count(id) as count, section_name from document where days <= :days]]> 
</sql-query> 
+0

Vâng, đúng vậy. Tìm thấy vấn đề theo jira cho tính năng này. http://opensource.atlassian.com/projects/hibernate/browse/HHH-2304 – Guus

+0

giải thích tuyệt vời !!! – lwpro2

+1

tôi có một cột là char (10). và tôi nhận được lỗi khi tôi thử cast (..as VARCHAR). nó hoạt động tốt khi tôi sử dụng cast (.... như CHAR) – kommradHomer

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