2017-03-07 55 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