2011-03-14 80 views
1

我有兩個類:ExternalTask​​和ExternalSource。 ExternalTask​​有一個ExternalSource列表和許多從ExternalTask​​到ExternalSource的單向關係。JPA manytomany單向映射

當我想要刪除一個ExternalSource時,我檢查它是否被任何ExternalTask​​引用。如果是這樣,我檢查這個ExternalTask​​是否在它的列表中只有這個外部源。 İf它是我完全刪除ExternalTask​​;否則,我從列表中刪除此外部源併合並外部任務。然後我刪除了externalsource。但是,這是違反約束的。我嘗試使用沒有級聯,cascadetype.update和cascadetype.refresh的連接表,但它仍然無法工作。任何幫助?

這是remove方法:

public class Foo{ 
     public boolean deleteExternalDataStorage(Long sid) { 
      EntityManager em = getEntityManager(); 
      EntityTransaction et = em.getTransaction(); 
      try { 
       et.begin(); 
       ExternalDataStorage s = em.find(ExternalDataStorage.class, sid); 
       List<ExternalTask> tasks=(List<ExternalTask>) em.createQuery("SELECT t FROM ExternalTask t ").getResultList(); 
       for(ExternalTask t:tasks) { 
        if(t.getExternalSources().contains(s)){ 
        t.getExternalSources().remove(s); 
        if(t.getExternalSources().isEmpty()){ 
         em.remove(t); 
        }else{ 
         em.merge(t); 
        } 
        } 
       } 


       em.remove(s); 
       et.commit(); 
       return true; 
      } catch (Exception e) { 
       e.printStackTrace(); 

      } finally { 
       if (et.isActive()) { 
        et.rollback(); 
       } 
      } 
      return false; 
     } 


    } 


    @Entity 
    public class ExternalTask { 

     @ManyToMany 
     @JoinTable(name = "ExternalTask_ExternalSource", joinColumns = @JoinColumn(name = "TID"), inverseJoinColumns = @JoinColumn(name = "EXID")) 
     private List<ExternalDataStorage> externalSources=new ArrayList<ExternalDataStorage>(); 


     @ManyToMany 
     @JoinTable(name = "ExternalTask_Archive", joinColumns = @JoinColumn(name = "TID"), inverseJoinColumns = @JoinColumn(name = "AID")) 
     protected List<Archive> archives=new ArrayList<Archive>(); 


     @Id 
     @GeneratedValue(strategy = GenerationType.IDENTITY) 
     @Column(name = "TID") 
     protected Long id; 


     @NotNull 
     @Column(name = "name") 
     protected String name; 

     @Column(name = "description") 
     protected String description; 

     @Column(name="timeinterval") 
     protected String interval; 



     @Column(name="startdate") 
     @Temporal(javax.persistence.TemporalType.TIMESTAMP) 
     protected Date startDate; 

     ... 
    } 

    @Entity 
    @Table(name = "ExternalSource") 
    public class ExternalDataStorage implements Serializable { 
     private static final long serialVersionUID = 3926424342696569894L;   

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

     @NotNull 
     @Column(name = "NAME") 
     private String name; 

     @Column(name = "DESCRIPTION") 
     private String description; 

     @NotNull 
     @Column(name = "USERNAME") 
     private String username; 

     @Column(name = "PATH") 
     private String path; 


     @Column(name = "PORT") 
     private int port = 22; 

     @NotNull 
     @Column(name = "ISSECURE") 
     private boolean isSecure=true; 

     @NotNull 
     @Column(name = "ISINDEXINGENABLED") 
     private boolean indexingEnabled; 

     @Column(name = "INDEXINGREGEXP") 
     private String indexingRegExp = "({time}\\d{8}-\\d{6})"; 

     @NotNull 
     @Column(name = "IP") 
     private String ip; 

     @Column 
     private String password; 

     @Column 
     private String protocol; 

     @Transient 
     private String publicKey; 

     @Column(name = "RSA_PRIV_KEY", length = 4096) 
     private String privateKey; 

     @Transient 
     private String regExpTestStr=""; 

     @Transient 
     private boolean testSucced; 

     @Transient 
     private InputAddress inputAddr; 

     @Column 
     private boolean authenticationType; 

     @Column 
     private boolean timeStampingEnable=true; 

     @Column 
     private String sshPath; 

     @Column 
     private String filename="(.*\\.log)"; 

     public ExternalDataStorage() { 
       inputAddr=new InputAddress(); 
     } 

     ... 
    } 
+0

你確定違規是由'externalSource'引起的,而不是'archives'造成的嗎? – axtavt 2011-03-14 15:47:54

+0

約束名稱爲空所以我不知道它的來源可能是歸檔結果,但爲什麼檔案會導致這樣的事情,我不認爲這是因爲檔案。 – ayengin 2011-03-14 17:26:55

+0

事實上,我不知道什麼時候發生連接表,當沒有cascade時。任何人都知道hibernate如何處理連接表。 – ayengin 2011-03-14 22:00:30

回答

1

好吧,你應該有你的任務和源之間的雙向多對一一對多的關係。顯然根據您的要求,Source應該是關係中的所有者,並且在定義Source端的關係時不要使用CascadeType = All,而是在Task端使用它。如果您確實有雙向關係,那麼您不必檢查所有任務的完整列表。該部分代碼是二次的,可以使用b方向映射輕鬆進行優化。另外,如果您將Source設置爲沒有級聯選項的擁有方,則依賴項將位於Source上,以將其自身從任務中附加/分離。所以你需要做的是:

if(source.getTaskList().size() == 1) { 
    //remove the task source.getTaskList().get(0), this will remove the source also 
} 
else { 
    //remove the source. The task is unaffected, as the source is the owning side 
}