2016-04-09 17 views
0

Sabit bir sabitler kümesine sahip bir Ink sınıfım var. Asla değişmezler ve bu sınıfı bir masa olarak saklamak istemiyorum.Hazırda bekletme: Bir tablo olmadan alanından bir sınıf yükleme

public final class Ink { 
    public static final Ink Y = new Ink(91001, 'y', 90.70, -5.23, 94.37), "Yellow"); 
    public static final Ink M = new Ink(92001, 'm', 48.19, 72.01, -1.78), "Magenta"); 
    public static final Ink C = new Ink(93001, 'c', 56.46, -41.00, -43.50), "Cyan"); 
    public static final Ink K = new Ink(94001, 'k', 18.64, 1.80, 5.21), "Black");  

    public int code; 

    public static Ink forCode(int code) { 
     //... 
    } 

    //... 
} 

Diğer sınıflar Ink ink veya Collection<Ink> inks alanlara sahip olabilir, ama her ink örneği sadece code değeri ile basit bir tamsayı sütunu ile eşleştirilmelidir. Code bir yabancı anahtar veya bir şey değil - her zaman Ink örneğini alabildiğim basit bir tam sayı değeridir.

@Entity 
public class Order { 
    //... 
    @OneToMany  
    public Set<Ink> inks; 
    //... 
} 
geri onun code ve

@Converter(autoApply = true) 
public class InkConverter implements AttributeConverter<Ink, Integer> { 

    @Overrcodee 
    public Integer convertToDatabaseColumn(Ink ink) { 
     return ink.code; 
    } 

    @Overrcodee 
    public Ink convertToEntityAttribute(Integer code) { 
     return Ink.forCode(code); 
    } 
} 

tarafından Ink sınıfını geri dönüştürücü kullanabilirsiniz

ancak soru şudur:

nasıl hala bir tablo gibi sınıf haritalama gelen Hibernate önlemek için code sütunundan yüklenmiş bir sınıf alanı var mı? Mürekkebi Java kodunuzda saklarken

+0

bir @Entity ek açıklaması yok neden bir tablo olarak harita __Ink__ Hazırda ki? Uyumlu JPA uygulaması bunu yapmaz. –

cevap

1

. Bu yüzden yük eylemini kendi kendinize uygulamalısınız. Öncelikle, Hazırda Bekletme modunu, sınıfın bir açıklama olarak @Transient ile bir tablo olarak eşlemesini önleyebilirsiniz. Sipariş yüklenen sonra Sonra yük işlemi işleyecek:

public interface Inked { 
    getCode(); 
    setInk(Ink ink); 
} 

public abstract class AbstractEntity { 

    @PostLoad 
    public void loadInk() { 
     if(this instanceof Inked){ 
      Inked inked = (Inked) this; 
      inked.setInk(Ink.forCode(getCode())); 
     } 
    } 
} 

@Entity 
public class Order extends AbstractEntity implement Inked { 
    //... 
    public Integer code; 

    @Transient 
    public Ink ink; 
    //... 

} 
+0

İyi, ama bu durumda 'loadInk() 've' code' 'Mürekkep 'alanı ile her varlığa iliştirmem gerekiyor. –

+0

Mürekkebe sahip olmak için çok fazla varlığa sahipseniz. Arayüzü kullanabiliyor musunuz? Kod güncellendi. – xierui

1

Öncelikle, Mürekkep örneklerini temsil edecek bir Enum oluşturabilirsiniz. Kod yerine kod referansı (Y, M, C, K) saklamak için sütun değiştirebilirseniz, bu en kolay çözüm olurdu. Eğer değilse, koddan Enum örneğine dönüştürmeyi önerdiğiniz bir dönüştürücü kullanabilirsiniz.

public Enum Ink { 
    Y = new Ink(91001, 'y', 90.70, -5.23, 94.37), "Yellow"); 
    M = new Ink(92001, 'm', 48.19, 72.01, -1.78), "Magenta"); 
    C = new Ink(93001, 'c', 56.46, -41.00, -43.50), "Cyan"); 
    K = new Ink(94001, 'k', 18.64, 1.80, 5.21), "Black"); 

    .....  

    private static Ink (...) { 
     ... 
    } 
} 

Y, M, C, K kaydederseniz, eşlemeler aşağıdaki gibi olacaktır. Eğer kodu kaydetmek gerekir o zaman gerekli dönüştürücüleri (http://www.nurkiewicz.com/2013/06/mapping-enums-done-right-with-convert.html) ekleyin

@Entity 
public class Order { 

    @ElementCollection 
    @CollectionTable(...) 
    @Enumerated(EnumType.STRING) 
    public Set<Ink> inks; 

    @Enumerated(EnumType.STRING) 
    private Ink ink; 
} 
İlgili konular