两个外键作为主键

时间:2015-09-22 09:20:02

标签: hibernate jpa spring-data spring-data-jpa

我有以下表格 enter image description here

我如何使用hibernate注释实现这一点?

目前的代码是:(为简洁而剥离)

用户

@Entity
@Table(name = "user")
public class User implements java.io.Serializable {
    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }
}

SocialNetwork

@Entity
@Table(name = "social_network")
public class SocialNetwork implements java.io.Serializable {
    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
}

SocialProfile

@Entity
@Table(name = "social_profile")
public class SocialProfile implements java.io.Serializable {
    @Id
    @ManyToOne
    @JoinColumn(name="user_id")
    public User getUser() {
        return user;
    }

    @Id
    @ManyToOne
    @JoinColumn(name="social_network_id")
    public SocialNetwork getSocialNetwork() {
        return socialNetwork;
    }
}

显然我的代码现在无法正常工作。任何人都可以对此有所了解吗?

4 个答案:

答案 0 :(得分:7)

你需要一个可嵌入的SocialProfileId:

@Embeddable
public class SocialProfileId implements Serializable {
    @Column(name = "user_id")
    private long userId;
    @Column(name = "social_network_id")
    private long socialNetworkId;
}

然后,您的SocialProfile实体将如下所示:

@Entity
@Table(name = "social_profile")
public class SocialProfile implements java.io.Serializable {

    @EmbeddedId
    private SocialProfileId id;

    @ManyToOne
    @JoinColumn(name="user_id")
    public User getUser() {
        return user;
    }

    @ManyToOne
    @JoinColumn(name="social_network_id")
    public SocialNetwork getSocialNetwork() {
        return socialNetwork;
    }
}

编辑抱歉,我在答案中对字段和方法进行了混合注释......从来没有这样做过! ; - )

答案 1 :(得分:0)

似乎你需要具有额外列的join-table的mamy-to-many映射。 为此,您需要再创建2个类。

仅供参考:http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/

答案 2 :(得分:0)

我对REST应用程序的问题类似但有点不同,我将在此处发布。 我有2个数据表:歌曲&带有ID的标记(songid,tagid)。 然后我有一张桌子将 Tagassignment 加在一起 Tagassignment ,它只有 Song Tag 这两个主键。所以我不想加入他们,我想用两个外键保留表格。

我的解决方案来源:http://www.objectdb.com/java/jpa/entity/id

之前

歌曲

@Entity
@Table(name = "songs")
data class Song(

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    val id: Int,

    ...
)

代码

@Entity
@Table(name = "tags")
data class Tag(

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    val id: Int,

    ...
)

<强> Tagassignment

 @Entity
 @Table(name = "tagassignment")
 data class Tagassignment(

     val songid: Int,

     val tagid: Int

 )

之后

我没有更改歌曲标记

<强> Tagassignment

@Entity
@IdClass(value = TagassignmentKey::class)
@Table(name = "tagassignment")
data class Tagassignment(

    @Id
    val songid: Int,

    @Id
    val tagid: Int

)

我创建了一个Key类

<强> TagassignmentKey

class TagassignmentKey(val songid: Int, val tagid: Int) : Serializable {

    constructor() : this(0, 0)

}

答案 3 :(得分:0)

除了Pras所说的之外,我们甚至可以将@ManyToOne移到@Embeddable类本身内,以使SocialProfileId看起来像,您可以在Embedded类本身中清楚地看到它引用了另一个表

.

您的SocialProfile实体可以简单地具有嵌入式类和其他字段,例如电子邮件等。

@Embeddable
public class SocialProfileId implements Serializable {

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User userId;


    @ManyToOne
    @JoinColumn(name = "social_network_id")
    private SocialNetwork socialNetworkId;

    public SocialProfileId(User userId, SocialNetwork socialNetworkId) {
        this.userId = userId;
        this.socialNetworkId = socialNetworkId;
    }

}