2013-07-19 27 views
0

我有三個類:PeelTestFile,DiscreteJob和PeelTestFileJob。這與User,Group和UserGroup的典型問題類似。我試圖刪除一個PeelTestFileJob。當我這樣做時,它將外鍵設置爲空。這是一個問題,因爲我將外鍵設置爲NOT NULL,這是正確的。我希望它只刪除數據庫中的一條記錄,然後在Java中,我希望它從它所屬的兩個集合中刪除實例(這是它似乎設置爲空的地方)。如何正確地從休眠中的多對多中刪除聯接實例

以下是我的代碼。什麼是正確的方法來做到這一點?

public class DiscreteJob 
{ 
    private Set<PeelTestFileJob>   peelTestJobs; 

    /** 
    * @hibernate.set 
    * inverse="true" 
    * lazy="true" 
    * cascade="all-delete-orphan" 
    * @hibernate.collection-key 
    * column="WIP_ENTITY_ID" 
    * @hibernate.collection-one-to-many 
    * class="com.icumed.ifactory3.dto.PeelTestFileJob" 
    */ 
    public Set<PeelTestFileJob> getPeelTestJobs() 
    { 
    return this.peelTestJobs; 
    } 

    public boolean remove(
    PeelTestFileJob peelTestFileJob) 
    { 
    return this.peelTestJobs.remove(peelTestFileJob); 
    } 

    public void setPeelTestJobs(
    Set<PeelTestFileJob> peelTestJobs) 
    { 
    this.peelTestJobs = peelTestJobs; 
    } 
} 

public class PeelTestFile 
{ 
    private Set<PeelTestFileJob> peelTestFileJobs; 

    /** 
    * @hibernate.set 
    * inverse="true" 
    * lazy="true" 
    * cascade="all-delete-orphan" 
    * @hibernate.collection-key 
    * column="PEEL_TEST_FILE_ID" 
    * @hibernate.collection-one-to-many 
    * class="com.icumed.ifactory3.dto.PeelTestFileJob" 
    */ 
    public Set<PeelTestFileJob> getPeelTestFileJobs() 
    { 
    return this.peelTestFileJobs; 
    } 

    public boolean remove(
    PeelTestFileJob peelTestFileJob) 
    { 
    return this.peelTestFileJobs.remove(peelTestFileJob); 
    } 

    public void setPeelTestFileJobs(
    Set<PeelTestFileJob> jobs) 
    { 
    this.peelTestFileJobs = jobs; 
    } 
} 

public class PeelTestFileJob 
{ 
    private PeelTestFile  peelTestFile; 
    private DiscreteJob  job; 
    private User    createdBy; 
    private Date    creationDate; 

    /** 
    * @hibernate.many-to-one 
    * column="PEEL_TEST_FILE_ID" 
    * not-null="true" 
    * outer-join="false" 
    */ 
    public PeelTestFile getPeelTestFile() 
    { 
    return this.peelTestFile; 
    } 

    public void setPeelTestFile(
    PeelTestFile file) 
    { 
    this.peelTestFile = file; 
    } 

    /** 
    * @hibernate.many-to-one 
    * column="WIP_ENTITY_ID" 
    * not-null="true" 
    * outer-join="false" 
    */ 
    public DiscreteJob getJob() 
    { 
    return this.job; 
    } 

    public void setJob(
    DiscreteJob job) 
    { 
    this.job = job; 
    } 
} 

下面是我的代碼,這是造成問題:

super.getHibernateTemplate().delete(peelTestFileJob); 

if (job.remove(peelTestFileJob)) // setting foreign key to null? 
{ 
    if (peelTestFile.remove(peelTestFileJob)) // setting foreign key to null? 
    { 
    if (peelTestFile.getPeelTestFileJobs().isEmpty()) 
    { 
     // modify the peel test file here 

     getPeelTestFileDAO().update(peelTestFile, bioIdentification); 
    } 
    } 
} 

回答

0

你應該有2個實體類+ 1個自動創建的表多對多的關係。以及爲什麼您的FK數據變爲空的原因是因爲您使用了一組關係表(Set<PeelTestFileJob>)而不是DiscreteJob或PeelTestFile集。

實體類爲例,加入表多對多表B(與PeelTestFile你的情況DiscreteJob):

表A

@ManyToMany(cascade = CascadeType.REFRESH) 
@JoinTable(name="A_JOIN_B", 
     joinColumns={@JoinColumn(name="A_ID")}, 
     inverseJoinColumns={@JoinColumn(name="B_ID")}) 
private Set<TestTableB> testJoins = new HashSet<TestTableB>(); 

表B:

@ManyToMany(mappedBy="testJoins") 
private Set<TestTableA> testJoins = new HashSet<TestTableA>(); 

__ _ __ _ __ _ __ _ __ _ __ _ __ _ ___編輯_ __ _ __ _ __ _ __ _ __ 我測試這個,這是工作:

關鍵是使用@OneToMany(mappedBy="bId", cascade = CascadeType.DETACH) bId是連接表實體中的FK。並嘗試刪除你的inverse = true,如果你不需要它。 inverse: If true, Hibernate will not try to insert or update the properties defined by this join. Default to false.

這是(你的情況一樣PeelTestFile或DiscreteJob)父表例如:

@Entity 
@Table(name = "TEST_TABLE_B") 
public class TestTableB { 

    //constructors here 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "B_ID") 
    private Long id; 

    @Column(name = "B_NAME") 
    private String bName; 

    @OneToMany(mappedBy="bId", cascade = CascadeType.DETACH) 
    private Set<AJoinB> testJoins = new HashSet<AJoinB>(); 
    //getters and setters here 

此甲加入乙表的例子(你的情況PeelTestFileJob):

@Entity 
@Table(name = "A_JOIN_B") 
public class AJoinB { 
    //constructors here 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "ID") 
    private Long id; 

    @Column(name = "C_NAME") 
    private String aName; 
    //you can add another column here 

    @Column(name = "A_ID", nullable = false) 
    private Long aId; 

    @Column(name = "B_ID", nullable = false) 
    private Long bId; 
    //getter setters here 

當我在java中執行此命令我刪除A連接B表中的1行:

TestTableB b = (TestTableB) this.genericDao.getList("from TestTableB b where b.id = 1",false,null).get(0); 
Set<AJoinB> testJoins = b.getTestJoins(); 
AJoinB ab = (AJoinB) testJoins.toArray()[0]; 
this.genericDao.remove(ab); 
+0

我需要該表和該類,因爲除了連接數據之外還有其他信息。還有這些列:created_by,creation_date,last_updated_by,last_update_date。 –

+0

編輯所以你可以保留連接表內的其他列,我的主要區別是** ** **和** cascade **屬性 – Angga

+0

我終於有時間回來了。我現在遇到的問題是,在調用「this.genericDao.remove(ab)」後,我需要調用「b.getTestJoins()。remove(ab)」,因爲我要回到一個Web頁面這將顯示b和設置。那時,當我在同一個會話中,並且現在提交事務時,Hibernate嘗試設置A_JOIN_B.B_ID = null,由於B_ID不可爲空,這會導致問題。 –