2010-08-09 34 views
6

'den Oluşan Boş Birleştirme Tablosu JPA sağlayıcım olarak Hibernate kullanan 2 varlık arasında ManyToMany ilişkisini uygulamaya çalıştığım bir uygulama var.JPA ManyToMany

Çalıştığım örnek tek yönlü bir kameradır, burada bir Kamera birden fazla Lense ve Lense birden çok Kameraya sığabilir. Takip

(Sadece bunun ilgili bölümünü yapıştırarak) benim varlık sınıfı ve ...

Kamera:

@Entity 
@Table(name = "CAMERAS") 
public class Camera implements Serializable { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "CAM_ID", nullable = false) 
    private Long camId; 

    @Column(name="CAMERA_BRAND") 
    private String cameraBrand; 

    @ManyToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE},fetch=FetchType.EAGER) 
    @JoinTable(name="CAMERA_LENS",[email protected](name="CAM_ID"),[email protected](name="LENS_ID")) 
     private Set<Lens> lenses = new HashSet<Lens>(); 

    ... 
} 

Objektif: Test-durumda

@Entity 
@Table(name = "LENSES") 
public class Lens implements Serializable {   
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "LENS_ID", nullable = false) 
    private Long lensId; 

    @Column(name="LENS_NAME") 
    private String name; 

    ... 
} 

, ben bu gibi Kamera örneğini sürdürmeye çalışın ...

@Test 
public void test_saveCameraLenseManyToMany() { 
    Camera cam = new Camera(); 
    cam.setCameraBrand("Nikon"); 
    Set<Camera> cameras = new HashSet<Camera>(); 
    cameras.add(cam); 

    Set<Lens> lenses = new HashSet<Lens>(); 
    Lens lens1 = new Lens(); 
    lens1.setName("WideAngle"); 
    lenses.add(lens1); 

    cam.setLenses(lenses); 

    // concreteDAO.saveLens(lens1); 
    concreteDAO.saveCamera(cam); 
} 

Kalıcılık başarıyla gerçekleşir ve Hazırda Bekletme tarafından atılan bir hata/istisna yoktur. Ancak, beklentinin aksine JoinTable'da bir satır oluşturulmaz (bu durumda CAMERA_LENS). Sadece Lens ve Kamera tablolarının her birinde bir satır oluşturulur, böylece ManyToMany'nin amacına hizmet etmez. Ancak, birleştirme tablosu için DDL oluşturulur ve aynı zamanda herhangi bir kayıt içermez.

Herhangi bir yardım veya işaretçi çok takdir edilecektir.

cevap

5

Sorunu buldum. Bu biraz garip. Ben kullanıyordum DAO sınıf bir sınıf seviyesi ek açıklama vardı:

@Transactional(readOnly=true) 

sql o 2 varlıkları kurtardı hala

Hibernate: insert into CAMERAS (CAMERA_BRAND) values (?) 
Hibernate: insert into LENSES (LENS_NAME) values (?) 
Hibernate: insert into LENSES (LENS_NAME) values (?) 

oldu Ve üretilen, ancak kaydetmek veya katılmak veri eklemek vermedi tablo.

I'in bir yöntem seviyesi ek açıklama ilave an:

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 

şey iyi olduğu ortaya çıktı ve veriler gerçekten birleştirme tabloya yerleştirilmiştir. Bu durumda oluşturulan yeni SQLs hiçbir işlem propogation stratejisi 2 tablolarına veri kurtardığını hala

Hibernate: insert into CAMERAS (CAMERA_BRAND) values (?) 
Hibernate: insert into LENSES (LENS_NAME) values (?) 
Hibernate: insert into LENSES (LENS_NAME) values (?) 

Hibernate: insert into CAMERAS_LENSES (CAM_ID, LENS_ID) values (?, ?) 
Hibernate: insert into CAMERAS_LENSES (CAM_ID, LENS_ID) values (?, ?) 

Biraz tuhaf ... ama propogation strateji verildi kez her şey iyi olduğu ortaya çıktı.

Diğer ilginç bir gözlem, yöntem stratejisini MANDATORY olarak eklemeyi denediğimde (ilk ve hatalı duruma neden olan bir İşlem olup olmadığını kontrol etmek için), ancak yöntem hiçbir işlemin var olmadığını belirten bir istisna attı. hala veriler 2 tabloya kaydedildi.

Umarım bir başkasına yardım eder ...

+2

Benim durumumda, bu yardımcı olmadı. Yardımın ne olduğu belirsizdi ... (Hala bunun neden gerekli olduğunu anlamıyorum, diğer toplama güncellemeleri işlemin içinde görüldüğü gibi. Sadece ara masanın bir güncellemeye ihtiyaç duymadığı görülmedi. –

+0

Sanırım @Transactional (readOnly = true) hala bir tx başlatacak olan GEREKLİ bir varsayılan yaymaya sahip olabilir.Aynı soruna rastladım ve @Transactional (progpagation = REQUIRED, readOnly = true) ile birleştirme, birleştirme tablosuna eklenmiyordu. @Adres, çalışmayı önerdi, ancak readOnly'yi kaldırarak – ams