2015-10-07 22 views
8

Chúng tôi đang phát triển một ứng dụng được kết nối với cơ sở dữ liệu kế thừa. Điều này là rất "untyped", sử dụng chuỗi cho hầu như tất cả dữ liệu. Điều tồi tệ hơn là không đồng nhất: nó sử dụng các mẫu khác nhau cho ngày hoặc thời gian ('YYDDMM', 'HHMMSS', mili giây) và boolean ('Y'/'N', 'X'/''), cho thí dụ.JPA: Các trường hợp tham số của AttributeConverter

Chúng tôi muốn sử dụng JPA (EclipseLink) và trình chuyển đổi tùy chỉnh. Vấn đề là @Convert mong đợi một lớp thực hiện AttributeConverter, vì vậy chúng tôi phải làm các lớp mới cho mỗi mẫu. Những gì tôi muốn là một lớp BooleanConverter, có thể được khởi tạo với các giá trị 'Y'/'N' hoặc 'X'/''.

Điều này rõ ràng nằm ngoài thông số kỹ thuật JPA, nhưng có thể có thể sử dụng chú thích/cấu hình EclipseLink. Nhìn vào chú thích @Convert của nó, trình chuyển đổi có thể được chỉ định theo tên. Điều này nghe tốt với tôi nếu tôi có thể đăng ký một ynBooleanConverterxSpaceBooleanConverter:

// Unfortunately, this method does not exist :(
Session.addConverter('ynBooleanConverter', new BooleanConverter("Y", "N")); 

@Entity 
public class MyEntity { 

    @Convert("ynBooleanConverter") 
    private Boolean myBoolean; 

    ... 
} 

Có thể? Chúng ta có những lựa chọn nào khác?

+0

có phù hợp để bạn sử dụng trình chuyển đổi JPA 2.1 không? có sẵn từ eclipselink phiên bản 2.5 không? –

+0

Tôi có thể sử dụng phiên bản EclipseLink cuối cùng, nhưng tôi không thể xem cách giải quyết nó. – sinuhepop

Trả lời

1

Hãy thử @ObjectTypeConverter:

@Entity 
@ObjectTypeConverters({ 
    @ObjectTypeConverter(name = "ynBooleanConverter", objectType = Boolean.class, dataType = String.class, 
     conversionValues = { 
     @ConversionValue(objectValue = "true", dataValue = "Y"), 
     @ConversionValue(objectValue = "false", dataValue = "N") }), 
    @ObjectTypeConverter(name = "xSpaceBooleanConverter", objectType = Boolean.class, dataType = String.class, 
     conversionValues = { 
     @ConversionValue(objectValue = "true", dataValue = "X"), 
     @ConversionValue(objectValue = "false", dataValue = " ") }), 
}) 
public class MyEntity { 

    @Convert("ynBooleanConverter") 
    private boolean ynBoolean; 

    @Convert("xSpaceBooleanConverter") 
    private boolean xSpaceBoolean; 
} 
+0

Cảm ơn. Điều này chỉ hoạt động cho Booleans, nhưng không chỉ cho các ngày có định dạng khác nhau. – sinuhepop

+0

Tôi đoán bạn phải triển khai chú thích của riêng bạn để đạt được chuyển đổi đó. Tôi nghi ngờ rằng có sự hỗ trợ cho logic đó trong EclipseLink hoặc JPA. – Ish

0

Vì vậy, chuyển đổi của bạn cư xử khác nhau tùy thuộc vào một số nhà nước trong bối cảnh? Tôi nghĩ rằng tôi sẽ cố gắng để ràng buộc các thông tin ngữ cảnh để một biến threadlocal mà tôi có thể đọc lại trong việc thực hiện chuyển đổi.

Bạn có quyền truy cập vào triển khai CDI không? Sau đó, nó thậm chí còn thanh lịch hơn để chèn một số bean với thông tin ngữ cảnh của bạn vào trong quá trình thực hiện Chuyển đổi. Bạn đã đề cập rằng bạn đang thiếu một số phương thức session -Methods? Có lẽ hạt đậu tương của @SessionScope sẽ giúp bạn.

Đáng buồn là @Inject không được chỉ định trong lớp chuyển đổi. Bạn sẽ cần phải tra cứu đậu "bằng tay" như đã đề cập trong bài đăng this.

+0

Trình chuyển đổi không hoạt động tùy thuộc vào trạng thái, nhưng trường thực tế đang chuyển đổi. Tôi có một số mẫu khác nhau cho các ngày được lưu bằng chuỗi. Tôi không muốn tạo ra nhiều lớp, nhưng chỉ có một lớp. – sinuhepop

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