我创建了三个类 - User,UserSubscription和Subscription。我希望UserSubscription表中的用户应该由User表中的用户引用。那么,如何使用mappedBy? 课程如下:
用户:
package com.model;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
@Entity
public class User {
private int userId;
private String password;
private String contact;
private String firstName;
private String lastName;
private String gender;
private String address;
private int age;
private String email;
private String countBooks;
private Set<Language> languages = new HashSet<Language>(0);
private Set<Book> favorites = new HashSet<Book>(0);
@Id
@GeneratedValue
@Column(name="User_Id")
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
@Column(name="Password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Column(name="Contact")
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
@Column(name="First_Name")
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@Column(name="Last_Name")
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Column(name="Gender")
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Column(name="Address")
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Column(name="Age")
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Column(name="Email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Column(name="Count_Books")
public String getCountBooks() {
return countBooks;
}
public void setCountBooks(String countBooks) {
this.countBooks = countBooks;
}
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name="User_Language", joinColumns = {
@JoinColumn(name = "User_Id", nullable = false, updatable = false) },
inverseJoinColumns = { @JoinColumn(name = "Language_Id",
nullable = false, updatable = false) })
public Set<Language> getLanguages() {
return languages;
}
public void setLanguages(Set<Language> languages) {
this.languages = languages;
}
@ManyToMany
@JoinTable(name="User_Favorite", joinColumns = {
@JoinColumn(name = "User_Id", nullable = false, updatable = false) },
inverseJoinColumns = { @JoinColumn(name = "Book_Id",
nullable = false, updatable = false) })
public Set<Book> getFavorites() {
return favorites;
}
public void setFavorites(Set<Book> favorites) {
this.favorites = favorites;
}
}
UserSubscription:
package com.model;
import java.sql.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity
public class UserSubscription {
private int userSubscriptionId;
private Subscription subscription;
private User user;
private Date subscriptionStartDate;
private Date subscriptionEndDate;
private int status;
@Id
@GeneratedValue
@Column(name="User_Subscription_Id")
public int getUserSubscriptionId() {
return userSubscriptionId;
}
public void setUserSubscriptionId(int userSubscriptionId) {
this.userSubscriptionId = userSubscriptionId;
}
@Column(name="Subscription_Id")
public Subscription getSubscription() {
return subscription;
}
public void setSubscription(Subscription subscription) {
this.subscription = subscription;
}
@OneToOne(mappedBy="userId")
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Column(name="Subscription_Start_Date")
public Date getSubscriptionStartDate() {
return subscriptionStartDate;
}
public void setSubscriptionStartDate(Date subscriptionStartDate) {
this.subscriptionStartDate = subscriptionStartDate;
}
@Column(name="Subscription_End_Date")
public Date getSubscriptionEndDate() {
return subscriptionEndDate;
}
public void setSubscriptionEndDate(Date subscriptionEndDate) {
this.subscriptionEndDate = subscriptionEndDate;
}
@Column(name="Status")
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
订阅:
package com.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Subscription {
private int subscriptionId;
private String name;
private int period;
private float fees;
private int noOfBooks;
private int Status;
@Id
@GeneratedValue
public int getSubscriptionId() {
return subscriptionId;
}
public void setSubscriptionId(int subscriptionId) {
this.subscriptionId = subscriptionId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPeriod() {
return period;
}
public void setPeriod(int period) {
this.period = period;
}
public float getFees() {
return fees;
}
public void setFees(float fees) {
this.fees = fees;
}
public int getNoOfBooks() {
return noOfBooks;
}
public void setNoOfBooks(int noOfBooks) {
this.noOfBooks = noOfBooks;
}
public int getStatus() {
return Status;
}
public void setStatus(int status) {
Status = status;
}
}
执行时出现异常:
Exception in thread "main" org.hibernate.AnnotationException: Referenced property not a (One|Many)ToOne: com.model.User.userId in mappedBy of com.model.UserSubscription.user
at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:248)
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1695)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1424)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928)
at com.impetus.model.Check.main(Check.java:92)
答案 0 :(得分:4)
在您的代码中,user-user_subscription看起来是单向的。 'mappedby'应该用于双向关系。
您可以在用户实体中使用以下代码,使其与user_subscription成双向。
private UserSubscription userSubscription;
@OneToOne
public User getUserSubscription() {
return userSubscription;
}
或者从user_subscription中删除mappedby并使其成为单向的。
答案 1 :(得分:0)
你的User类中应该有UserSubscription memeber和corrosponding gettes和setter,如下所示:
private Set<Company> userSubscriptions = new HashSet<Company>(0);
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
public Set<UserSubscription> getUserSubscriptions() {
return this.userSubscriptions ;
}
public void setUserSubscriptions(Set<UserSubscription> userSubscriptions ) {
this.userSubscriptions = userSubscriptions ;
}
以及在UserSubscription实体类中将用户对象作为memeber的方式相同。
私人用户;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "USER_ID", nullable = false)
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
答案 2 :(得分:0)
你做错了
class User {
UserSubscription userSubscription ;
@OneToOne
public UserSubscription getUserSubscription(){
return userSubscription ;
}
public void setUserSubscription(UserSubscription userSubscription ){
this.userSubscription = userSubscription ;
}
}
class UserSubscription {
@OneToOne(mappedBy="userSubscription")
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
答案 3 :(得分:0)
似乎您不确定使用了什么是mappedBy或意味着什么。数据库关系是单方面的;一个表将具有目标表的外键引用。在JPA中,您可以将此关系映射为OneToOne,并指定要与@JoinColumn批注一起使用的外键:
@OneToOne(mappedBy="userId")
@JoinColumn(name = "USER_ID")
public User getUser() {
return user;
}
Join列定义是可选的,如果不使用,JPA将默认使用属性名称&#34; _&#34;并且目标实体的ID名称前置,因此&#34; USER_ID&#34;在这种情况下无论如何。
回到数据库,因为源表引用了目标表,这形成了另一个隐式关系(目标表的ID可以用来查找另一个表的外键)。在JPA中,这可以再次映射为OneToOne或OneToMany,具体取决于基数。如果它是OneToOne,则指定此关系不通过将其标记为mappedBy与其他关系来定义外键:
@OneToOne(mappedBy="user")
public UserSubscription getUserSubscription() {
return userSubscription;
}
但用户更有可能拥有多个userSubscriptions:
@OneToMany(mappedBy="user")
public Collection<UserSubscription> getUserSubscriptions () {
return userSubscription ;
}
在这两种情况下,您都使用mappedBy来表示有一个&#39;用户&#39;目标实体中的属性,用于定义与此实体的关系,并控制数据库中的外键设置。
您还需要更改定义UserSubscription-&gt;订阅关系的方式,因为您已经定义了@Column似乎是一种关系。应该是
@OneToOne
@JoinColumn(name="Subscription_Id")
public Subscription getSubscription() {
return subscription;
}