2013-10-02 25 views
6

Tôi có một thực thể có tính chất DateTime vẫn kiên trì với chế độ ngủ đôngLàm thế nào để chuyển đổi Joda DateTime trong JPA truy vấn nguồn gốc

@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime") 
@Column(name = "EFF_DT") 
protected DateTime effDt; 

này tất cả hoạt động tốt và tốt cho thường xuyên mùa xuân-data-JPA tạo ra các truy vấn.

Tôi cố gắng để thêm một truy vấn gốc tùy chỉnh

@Query(value = "SELECT COUNT(*) FROM wsa_circuit_state_history ch WHERE ch.eff_dt between ?1 and ?2", nativeQuery = true) 
    Integer countEffDateBetween(DateTime start, DateTime end); 

Các lỗi tôi nhận được khi cố gắng gọi đây là

java.sql.SQLException: ORA-00932: inconsistent datatypes: expected DATE got BINARY 

Đây là lỗi tương tự tôi sử dụng để nhận được với mùa xuân thường xuyên công cụ tìm dữ liệu trước khi thêm ánh xạ loại tùy chỉnh vào thực thể của tôi

@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime") 

Làm cách nào tôi có thể tạo ra mùa xuân -data-jpa/hibernate sử dụng ánh xạ kiểu tùy chỉnh cho các tham số cho các truy vấn gốc?

+0

Bạn đã tìm thấy một câu trả lời cho điều này? –

+0

@ WojciechGórski Không, tôi không tìm thấy bản sửa lỗi. Cuối cùng tôi quản lý để viết lại truy vấn trong JPA, và do đó, chú thích hibernate @Type được khởi tạo để xử lý chuyển đổi kiểu '@Query (" select count (ch.circuitId) từ nz.co.vodafone.wcim. model.CircuitStateLog ch nơi ch.effDt giữa? 1 và? 2 và ch.state =? 3 ")' –

Trả lời

0

Chỉ cần thiết lập tài sản của bạn để java.util.Date như thế này

Sau đó chuyển đổi trong getter của bạn/setter

public DateTime getEffDt() { 
    return null == effDt ? null : new DateTime(effDt); 
} 

public void setEffDt(final DateTime effDt) { 
    this.effDt = null == effDt ? null : effDt.toDate(); 
} 

Quê quán:

@Query(value = "SELECT COUNT(*) FROM wsa_circuit_state_history ch WHERE ch.eff_dt between ?1 and ?2", nativeQuery = true) 
Integer countEffDateBetween(Date start, Date end); 
+0

Đó là một cách giải quyết thú vị để tránh sử dụng DateTime, nhưng trong trường hợp của chúng ta, chúng ta muốn giữ trường là DateTime. –

+0

Tại sao bạn không thể thay đổi 'countEffDateBetween (bắt đầu ngày giờ, kết thúc ngày giờ),' thành 'countEffDateBetween (Ngày bắt đầu, Ngày kết thúc);'? Điều đó sẽ cho phép bạn giữ các thuộc tính của bạn như là DateTime. –

+1

Chúng tôi đang sử dụng DateTime, không phải java.util.Date. Chắc chắn nếu chúng ta ngừng sử dụng DateTime và Date được sử dụng, chúng ta sẽ không gặp vấn đề này. Tuy nhiên, chúng tôi muốn sử dụng API DateTime cao cấp hơn rất nhiều. Câu hỏi của tôi là 'làm thế nào tôi có thể làm cho các truy vấn gốc làm việc với DateTime', không sử dụng DateTime không phải là một giải pháp cho câu hỏi này. –

0

Trong một tình huống tương tự Tôi đã sử dụng để viết một CompositeUserType tùy chỉnh lưu trữ Joda DateTime trong hai trường, một dateti lĩnh vực của tôi và một lĩnh vực múi giờ.

Khi thực thể được lưu, nó lưu trữ giá trị thời gian trong UTC và múi giờ làm giá trị ban đầu, khi truy xuất nó đảo ngược (tức là nó đã chuyển đổi thời gian được lưu trữ trên cơ sở dữ liệu trở lại múi giờ ban đầu).

Như bạn đã xác định ở trên, mặc dù truy vấn như "ngày giờ GIỮA? 1 VÀ? 2" có ý nghĩa trực quan, tất nhiên nó không có ý nghĩa về loại hỗn hợp khi bạn cần ghi nhớ múi giờ. Đây là lý do tôi lưu trữ tất cả các giá trị trong UTC vì vậy tôi luôn có thể so sánh hai giá trị ngày/giờ trên cơ sở dữ liệu.

Thật không may, điều này có nghĩa là tất cả thông số truy vấn ngày/giờ tôi đã chuyển phải được chuyển thành UTC.

0

Chính xác tôi cũng có cùng yêu cầu. Và tôi đã giải quyết bằng cách đăng ký loại tùy chỉnh cho cấu hình ngủ đông.

Đối với truy vấn gốc, TypeDefs không đủ để ngủ đông để tìm loại người dùng. Cần loại Trình phân giải để tìm loại của nó.

@Query(value = "SELECT COUNT(*) FROM wsa_circuit_state_history ch WHERE ch.eff_dt between ?1 and ?2", nativeQuery = true) 
    Integer countEffDateBetween(DateTime start, DateTime end); 

Trong trường hợp này, hibernate cố đoán loại (org.joda.time.DateTime) từ trình phân giải loại.

Type type = session.getFactory().getTypeResolver().heuristicType(typename); 

Vì không có giải quyết cho DateTime.Then nó là nhận được loại mặc định (loại serializable) .Và giá trị DateTime được đúc để loại của nó, đó là tuần tự và sự bền bỉ trong DB, nơi nó được thất bại do đến giá trị nhị phân lớn.

Để giải quyết điều này, bạn cần phải đăng ký DateTime loại để Hibernate Configuration như

configuration.registerTypeOverride(new org.jadira.usertype.dateandtime.joda.PersistentDateTime(), new String[]{"org.joda.time.DateTime"}); 
Các vấn đề liên quan