mi?

2010-08-02 15 views
5

I (iyi ölçmek için) üstte Spring veri kalıcılık için Hibernate kullanarak bir uygulama vardır.mi?

@Entity 
public class B extends A { 
    public String description; 
} 

B ekledikten sonra, şimdi bir 's yüklenemedi: Ben A sınıfının bir alt sınıfı olarak adlandırılan B eklendi beri var

@Entity 
public class A { 
    @Id 
    @Column(unique = true, nullable = false, updatable = false) 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private long id; 
    public String name; 
} 

: Yakın zamana kadar, tek kalıcı A sınıfı, uygulamada yoktu .

class org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException :: Object with id: 1 was not of the specified subclass: A (Discriminator: null); nested exception is org.hibernate.WrongClassException: Object with id: 1 was not of the specified subclass: A (Discriminator: null) 

Ben B'ye aşağıdaki ek açıklama ve mülk eklendi, sorunun çözülmüş gibi görünüyor: Aşağıdaki istisna oluştu. Bu sorunu çözmek için doğru yol mu?

ID NAME 
-- ---- 
1 foo 
2 bar 

I: Aşağıdaki veritabanı gösterimi ile

:

... 
@DiscriminatorFormula("(CASE WHEN dtype IS NULL THEN 'A' ELSE dtype END)") 
public class A { 
    private String dtype = this.getClass().getSimpleName(); 
    ... 

cevap

2

(...) Yakın zamana kadar, A, uygulamada tek kalıcı sınıf vardı çünkü A'nın bir alt sınıfını denilen B (...)

ekledik

Ve SINGLE_TABLE haritalama stratejisi kullanılır böylece Inheritance ek açıklama belirtmedi. Ve Bu stratejide, bir hiyerarşideki tüm sınıflar tek bir tabloyla eşlenir. Tablo, bir “ayırt edici kolonu” olarak hizmet eden bir sütun vardır, yani, değeri bir sütun satır ile temsil edilir, örneğin ait olduğu spesifik bir alt sınıfını belirler.

tablo sonra oldu: d_type sütunun varsayılan adı olan

ID NAME DTYPE 
-- ---- ----- 
1 foo NULL 
2 bar NULL 

discriminator için kullanılacak.

B ekledikten sonra, şimdi A en yüklenemedi. Aşağıdaki istisna atıldı (...)

Aslında, mevcut değerler ayrımcı sütununda boş bir değere sahip olduğundan, sağlayıcı, hangi alt sınıfın başlatılacağını bilmemektedir.

Aşağıdaki notu ve özelliği B'ye ekledim ve sorunun çözülmüş gibi görünüyor. Bu sorunu çözmek için doğru yol mu? Bu bir yöntemdir, ancak (girişlerinizin dtype sütunundan haberdar olmaması gerekir) ve Hazırda bekletme özel durumudur. Başka bir deyişle, bir hack.

UPDATE A SET DTYPE='A' WHERE DTYPE=NULL 
:

Benim için bu çözmek için "doğru" yolu (Hibernate, varlık adına karşılık değer varsayılanlarla) 'A' seçimi için A kayıtlarını mevcut DTYPE sütunu güncelleştirmek olacaktır

Bu şekilde Hazırda Beklet, bunları düzgün şekilde yükleyebilir. Ayrıntılı yanıt için

+0

teşekkürler. Maalesef, uygulamanın tüm yüklemelerine doğrudan erişemeyeceğim, bu yüzden bu şema değişikliğinin kullanıcılara şeffaf olmasını istiyorum. DiscriminatorFormula'yı dtype alanını açıkça tanımlamaksızın eklemeyi denedim, ancak bu işe yaramadı. Yaptığım zaman bir hack gibi hissettim - bu yüzden sordum. – Armand

+1

@Alison Rica ederim. IMO'nun "ideal" çözümünü size verdim. İçeriğinize uygun değilse, kullanıcılarınıza bir geçiş komut dosyası sağlayamıyorsanız (bu "ALTER" den sonra "UPDATE" i gerçekleştirir) - veya daha iyi bir otomatik geçiş aracı - daha sonra çözümünüz kabul edilebilir. En azından işe yarıyor. Ve şimdi biliyorsun hack bir tür olduğunu :) –

+0

-) Ne yazık ki, Hibernate/Bahar göçmenler hakkında bilgi oldukça zor geldi. – Armand

İlgili konular