2013-02-28 57 views
2

我遇到以下問題:我必須將我的Employee類映射到以下數據庫模式(,其中id1和id2是複合主鍵關鍵):一旦外鍵是主鍵的一部分,如何映射與複合鍵的自加入

-------------------------- 
| id1 | id2 | ManagerId2 | 
-------------------------- 
| 1 | 1 | NULL  | <--- Have no manager/Can be manager of many 
-------------------------- 
| 1 | 2 | 1   | <--- Is manager/Has manager 1-1 
-------------------------- 
| 1 | 3 | 1   | <--- Is manager/Has manager 1-1 
-------------------------- 

我知道,一個外鍵必須具有相同的列作爲主鍵也引用(列數相同)。重點是一旦Employee插入id1 = 1它必須只參考經理id1 = 1。一種方法來保持完整性和避免類似以下情況:

--------------------------------------- 
| id1 | id2 | ManagerId1 | ManagerId2 | 
--------------------------------------- 
| 1 | 1 | NULL  | NULL  | <--- Have no manager/Can be manager of many 
--------------------------------------- 
| 2 | 1 | NULL  | NULL  | <--- Have no manager/Can be manager of many 
--------------------------------------- 
| 1 | 2 | 2   | 1   | <--- THIS IS NOT ALLOWED 
--------------------------------------- 
| 1 | 3 | 2   | 1   | <--- NOR THIS 
--------------------------------------- 

到目前爲止,我得到的是下面的映射(儘管它產生預期它根本不填充ManagerId2字段的表)的最佳:

@Entity 
@Table(name="Employee") 
public class Employee { 

    public Employee(){ 
    } 

    @EmbeddedId 
    private EmployeeId id; 
    public void setId(EmployeeId id) { 
     this.id = id; 
    } 
    public EmployeeId getId() { 
     return id; 
    } 

    @ManyToOne(cascade={CascadeType.ALL}) 
    @JoinColumns({ 
     @JoinColumn(name = "id1", referencedColumnName = "id1", insertable=false, updatable=false), //its fine to have this attribute not insertable nor updatable 
     @JoinColumn(name = "id2_manager", referencedColumnName = "id2", insertable=false, updatable=false) //but I must be able to update this one! 
    }) 
    private Employee manager; 
    public Employee getManager() { 
     return manager; 
    } 
     public void setManager(Employee manager) { 
     this.manager = manager; 
    } 
} 

@Embeddable 
public class EmployeeId implements Serializable{ 

    public EmployeeId() { 

    } 

    public EmployeeId(int id1, int id2) { 
     this.id1 = id1; 
     this.id2 = id2; 
    } 

    private int id1; 

    private int id2; 

    public int getId1() { 
     return id; 
    } 

    public void setId(int id1) { 
     this.id1 = id1; 
    } 

    public int getId2() { 
     return id2; 
    } 

    public void setId2(int id2) { 
     this.id2 = id2; 
    } 

      //hashCode and equals properly overriden 
} 

經過一整天的護目鏡後,似乎我無法找到任何東西! 有人可以告訴我我做錯了什麼,或指出任何好的資源?

PS:我不能改變DB模式,它不是一個選項

+0

請問您的表有ManagerId1列或不? – 2013-02-28 20:49:07

+0

不,它不。我的意思是,它不能存在,因爲模式是強制性的,模式只有'id1','id1'和'managerId2'在裏面 – renatoargh 2013-02-28 20:51:50

+0

爲什麼你說「它不會填充ManagerId1字段?」這是一個錯字嗎? – 2013-02-28 21:04:10

回答

1

林不知道如何與註解做到這一點,但香港專業教育學院找到了解決方法,可以幫助你。

@Entity 
@Table(name = "Employee") 
public class Employee { 

    @EmbeddedId 
    private EmployeeId id; 

    private Integer id2_manager; 

    @PrePersist 
    @PreUpdate 
    public void prePersistUpdate() { 
     if (manager != null) 
      id2_manager = manager.getId().getId2(); 
    } 

    public Employee() { 
    } 

    public void setId(EmployeeId id) { 
     this.id = id; 
    } 

    public EmployeeId getId() { 
     return id; 
    } 

    @ManyToOne(cascade = { CascadeType.ALL }) 
    @JoinColumns({ @JoinColumn(name = "id1", referencedColumnName = "id1", insertable = false, updatable = false), 
      @JoinColumn(name = "id2_manager", referencedColumnName = "id2", insertable = false, updatable = false, nullable = true) }) 
    private Employee manager; 

    public Employee getManager() { 
     return manager; 
    } 

    public void setManager(Employee manager) { 
     this.manager = manager; 
    } 
} 

測試

static EntityManagerFactory emf; 
    static EntityManager em; 

    public static void main(String[] args) { 

     emf = Persistence.createEntityManagerFactory("unit"); 
     em = emf.createEntityManager(); 

     Employee manager = new Employee(); 
     manager.setId(new EmployeeId(1, 1)); 

     Employee e1 = new Employee(); 
     e1.setId(new EmployeeId(1,2)); 
     e1.setManager(manager); 


     em.getTransaction().begin(); 

     em.persist(manager); 
     em.persist(e1); 

     em.getTransaction().commit(); 

     Employee e2 = em.find(Employee.class, new EmployeeId(1, 2)); 

     System.out.println(e2.getManager().getId().getId1() + "-" + e2.getManager().getId().getId2()); 
     // prints 1-1 

    } 
相關問題