2017-03-07 79 views
0
@Entity 
@Table(name = "USER_DATA") 
public class UserData { 
    Entity entity; 

    @OneToOne(fetch = FetchType.EAGER) 
    @PrimaryKeyJoinColumn(name="PK_FK_ENTITY") 
    @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE}) 
    public Entity getEntity() { 
     return entity; 
    } 

    public void setEntity(Entity entity) { 
     this.entity = entity; 
    } 
} 

給出的錯誤是「沒有爲實體指定標識符」。我如何指定實體字段既是主鍵又是外鍵?請注意,這裏沒有'UserData'的類層次結構;它只是一個班級。對於每個'UserData'來說,只會有一個'Entity',因此我們希望使它成爲主鍵和外鍵。帶主鍵的休眠類也是外鍵

回答

0

我們已經在我們的應用程序相同的情況下,並與該作品(我們標註的屬性不是干將,不知道是否有任何區別):

public class UserData { 
    @Id 
    @Column(name="PK_FK_ENTITY") 
    private int id; 

    @OneToOne 
    @JoinColumn(name="PK_FK_ENTITY") 
    private Entity entity; 
    ... 

    public UserData (Entity entity, ...) { 

     this.id = entity.getId(); 
     ... 
    } 
    ... 
} 

注意,在構造函數中你應該設置爲ididentity都不應該有一個setter,因爲它不能改變。

另請注意,在這種情況下我們不使用級聯。我們首先保存具有生成的ID的Entity,然後保存UserData

+0

你有另一個,無參數的構造共享主鍵?我認爲Hibernate需要一個無參數構造函數。我很高興這可以工作,但它似乎是一種解決方法,而不是預期的解決方案。沒有冒犯 - 謝謝你的迴應。如果沒有其他答案即將出現,我們可能會這樣做。 – KyleM

+0

是的,我們有另一個沒有參數的構造函數,並且認爲這就像一個解決方法,我們在很多年前寫了這個,並且在那個時候找不到另一種方法。 – jorgegm

0

對於一對一的雙向映射,只需在子實體上定義@MapsId註釋即可。

@Entity 
@Table(name = "USER_DATA") 
public class UserData { 

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "userData", orphanRemoval = true) 
    private Entity entity; 

    public void setEntity(Entity entity) { 
     this.entity = entity; 
     if (null != entity && entity.getUserData() != this) { 
      entity.setUserData(this); 
     } 
    } 
} 

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

    @Id 
    private Long id; 

    @MapsId 
    @OneToOne 
    @JoinColumn(name = "user_data_id") 
    private UserData userData; 

    public void setUserData(UserData userData) { 
     this.userData = userData; 
     if (null != userData && userData.getEntity() != this) { 
      userData.setEntity(this); 
     } 
    } 

} 

對於一對多的單向映射,你必須使用@ElementalCollection和@CollectionTable和註釋Entity.class與@Embeddable註解

 @Entity 
     @Table(name = "USER_DATA") 
     public class UserData { 

      @ElementCollection 
      @CollectionTable(name = "entity", 
           joinColumns = @JoinColumn(name = "user_data_id"), 
           uniqueConstraints = { @UniqueConstraint(columnNames  
= { "user_data_id", "name" }) }) 
      private final Set<Entity> entities = new LinkedHashSet<>(); 

      public void setEntities(Set<Entity> entities) { 
       this.entities.clear(); 
       if (null != entities) { 
        this.entities.addAll(entities); 
       } 
      } 
     } 

     @Embeddable 
     public class Entity { 

      @Column 
      @Access(AccessType.FIELD) 
      private String name; 

     } 

請指爲更好地理解下面的文章:
1. @OneToOne使用@PrimaryKeyJoinColumn http://vard-lokkur.blogspot.my/2011/05/onetoone-with-shared-primary-key.html共享主鍵。

  • @OneToOne使用@MapsId http://vard-lokkur.blogspot.my/2014/05/onetoone-with-shared-primary-key.html