2016-11-19 316 views
0

我創建了一個系統,我有一些實體具有一些常見的屬性,如地址(與街道,號碼,郵編等)和電話號碼,類型等),我不想在每個實體上重複這些列。Springboot JPA/hibernate:如何映射一個表多個實體

這裏有一個例子:

  • 學生有地址和電話
  • 教師有多個地址(家庭 和辦公室)和多部電話(家庭,移動,辦公)
  • StaffMember 有地址和多個電話(家庭,移動和辦公室)

我在開發Ruby On Rails時使用類似的東西ic協會。我在Java/JPA/Hibernate上搜索了一些東西,並且找不到像它那樣的東西。我發現了許多關於JPA繼承的內容,但我不太明白。

你能給我一個關於如何建模和使用它的例子嗎?

編輯

閱讀我的問題後,我認爲這是不夠清晰,所以讓我在這裏添加數據庫架構,我有:

Student 
------- 
id bigint 
name varchar 
birth_date date 
... 

Teacher 
------- 
id bigint 
name varchar 
birth_date date 
department varchar 
... 

StaffMember 
------- 
id bigint 
name varchar 
birth_date date 
department varchar 
function varchar 
... 

Address 
------- 
id bigint 
street varchar 
number int 
... 
entity_id bigint 
entity_type varchar 

Phone 
----- 
id bigint 
type varchar 
number varchar 
... 
entity_id bigint 
entity_type varchar 

而且兩個AddressPhoneentity_identity_type是對Student,TeacherStaffMember的引用。

但如何使用Hibernate/JPA映射它?

+0

可以肯定的是:你的數據庫模式是固定的,JPA/hibernate必須適應它嗎? – larsgrefer

+0

Hi @larsgrefer,模式不夠靈活,上面只是它認爲最好的一個例子,但我願意接受建議。 – rfsbsb

+0

當你使用spring-boot時,只需設置'spring.jpa.generate-ddl = true'並讓hibernate爲你生成模式 – larsgrefer

回答

1

如果你不介意使用Hibernate特有的註解,還有@Any@AnyDef註解你想要什麼做的。您需要指定相關的地址,以便Hibernate知道如何存儲適當的值ITEM_TYPE

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 

import org.hibernate.annotations.Any; 
import org.hibernate.annotations.AnyMetaDef; 
import org.hibernate.annotations.MetaValue; 

@Entity 
public class Address { 

    @Any(metaColumn = @Column(name = "ITEM_TYPE")) 
    @AnyMetaDef(idType = "long", metaType = "string", 
      metaValues = { 
        @MetaValue(targetEntity = Student.class, value = "STUDENT"), 
        @MetaValue(targetEntity = Teacher.class, value = "TEACHER") 
      }) 
    @JoinColumn(name="ITEM_ID") 
    private Object item; 

    @Id 
    @GeneratedValue 
    private Long id; 

    @Column 
    private String type; 

    @Column 
    private String street; 

    @Column 
    private int number; 

    public String getType() { 
     return type; 
    } 

    public void setType(String type) { 
     this.type = type; 
    } 

    public Long getId() { 
     return id; 
    } 

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

    public String getStreet() { 
     return street; 
    } 

    public void setStreet(String street) { 
     this.street = street; 
    } 

    public int getNumber() { 
     return number; 
    } 

    public void setNumber(int number) { 
     this.number = number; 
    } 


    public Object getItem() { 
     return item; 
    } 

    public void setItem(Object item) { 
     this.item = item; 
    } 

    @Override 
    public String toString() { 
     return "Address{" + 
       "person=" + item + 
       ", id=" + id + 
       ", type='" + type + '\'' + 
       ", street='" + street + '\'' + 
       ", number=" + number + 
       '}'; 
    } 
} 

現在每個實體類型@MetaValue項,你可以只使用地址在具有適當@MetaValue進入任何豆,無論是作爲@ManyToOne協會:

@ManyToOne 
protected Address address; 

還是一個@OneToMany關聯:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) 
protected Collection<Address> addresses; 

我創建使用Spring啓動一個簡單的測試項目,它似乎很好地工作!

+0

謝謝@JoãoMarcus,那就是我一直在尋找的! – rfsbsb

0

東西沿着這些路線:

@Embeddable 
    public class Address { 
     // Fields & accessors 
     // Do the Phone class in similar fashion 
    } 

    @Entity 
    @DiscriminatorColumn(name = "entity_type") 
    public abstract class Person { 
     @Id 
     private Integer id; 

     private String name; 

     @Embedded 
     private Address homeAddress; 

     @Embedded 
     private Phone homePhone; 

     // Other shared fields & accessors 

    } 

    @Entity 
    public abstract class Employee extends Person { 

     @Embedded 
     private Phone mobilePhone; 

     @Embedded 
     private Phone officePhone; 

     //... 

    } 

    @Entity 
    public class Students extends Person { 

    } 

    @Entity 
    public class StaffMember extends Employeee { 

    } 

    @Entity 
    public class Teacher extends Employeee { 

     @Embedded 
     private Address officeAddress; 

     // Accessors & other ... 
    } 
+0

Hi @ dev-null通過使用Embeddable可以將地址存儲在單獨的表中嗎?我不想在我的數據庫的每個表上覆制這個結構。 – rfsbsb

+0

@Embeddable的要點是它沒有特殊的表格,它只是嵌入到其他表格中的數據結構。類似複合數據類型。 –

相關問題