How would I implement the following tables using hibernate annotations?
Current code is: (stripped for brevity)
User
@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;
}
}
Obviously my code is not working correctly right now. Can anyone shed some light onto this?
you need an embeddable SocialProfileId like this :
@Embeddable
public class SocialProfileId implements Serializable {
@Column(name = "user_id")
private long userId;
@Column(name = "social_network_id")
private long socialNetworkId;
}
then, your SocialProfile entity will look like this :
@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;
}
}
EDIT sorry, i have mixed annotations on fields and methods on my answer ... never do that ! ;-)
It seems you need mamy-to-many mapping having join-table with extra column.
For this you need to create 2 more classes.
FYI : http://www.mkyong.com/hibernate/hibernate-many-to-many-example-join-table-extra-column-annotation/
My problem for a REST application was similar but a little bit different, I will post it here.
I had 2 data tables: Song & Tag with an id each (songid, tagid).
Then I had a table for joining them together Tagassignment which only had both of the primary keys from Song and Tag. So I did not want to join them, I wanted to keep the table with both foreign keys.
Source of my solution: http://www.objectdb.com/java/jpa/entity/id
Before
Song
@Entity
@Table(name = "songs")
data class Song(
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
val id: Int,
...
)
Tag
@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
)
After
I did not change Song and Tag.
Tagassignment
@Entity
@IdClass(value = TagassignmentKey::class)
@Table(name = "tagassignment")
data class Tagassignment(
@Id
val songid: Int,
@Id
val tagid: Int
)
and I created a Key class
TagassignmentKey
class TagassignmentKey(val songid: Int, val tagid: Int) : Serializable {
constructor() : this(0, 0)
}
In addition to what Pras has said, we can even move the @ManyToOne inside the @Embeddable class itself so SocialProfileId will look like, where you can clearly see in your Embedded class itself that it referencing another table
@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;
}
}
And your SocialProfile entity can simply have the embedded class and other fields like email and so on..
@Entity
@Table(name = "social_profile")
public class SocialProfile implements java.io.Serializable {
@EmbeddedId
private SocialProfileId id;
@Column(name="email")
private String email;
}