Java 一通映射中的MappedBy

Java 一通映射中的MappedBy,java,hibernate,jpa,hibernate-mapping,Java,Hibernate,Jpa,Hibernate Mapping,我创建了三个类:User、UserSubscription和Subscription。我希望UserSubscription表中的用户应该被User表中现有的用户引用。那么,如何使用mappedBy呢? 课程如下: 用户: 订阅: package com.model; import java.sql.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.

我创建了三个类:User、UserSubscription和Subscription。我希望UserSubscription表中的用户应该被User表中现有的用户引用。那么,如何使用mappedBy呢? 课程如下:

用户:

订阅:

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)

在您的代码中,用户对用户的订阅看起来是单向的“mappedby”应在双向关系中使用

您可以在用户实体中使用以下代码,使其与用户订阅双向

private UserSubscription userSubscription; 
@OneToOne
    public User getUserSubscription() {
        return userSubscription;
    }

或者从用户订阅中删除mappedby并使其成为单向的

您的用户类中应该有UserSubscription memeber和相应的gette和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 ;
}
}


你做错了

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;
    }
}

似乎您不确定mappedBy的用途或含义。数据库关系是片面的;一个表将具有对目标表的外键引用。在JPA中,您可以将此关系映射为OneToOne,并指定要与@JoinColumn注释一起使用的外键:

@OneToOne(mappedBy="userId")
@JoinColumn(name = "USER_ID")
public User getUser() {
    return user;
}
联接列定义是可选的,如果不使用,JPA将默认使用带有“\u”的属性名和目标实体的ID名,因此在本例中仍然使用“USER\u ID”

回到数据库,因为目标表被源表引用,这形成了另一个隐式关系(目标表的ID可用于查找另一个表的外键)。在JPA中,这可以根据基数再次映射为OneToOne或OneToMany。如果是OneToOne,则通过将外键标记为mappedBy另一个关系来指定此关系不定义外键:

@OneToOne(mappedBy="user")
public UserSubscription getUserSubscription() {
    return userSubscription;
}
但一个用户更有可能拥有多个用户订阅:

@OneToMany(mappedBy="user")
public Collection<UserSubscription> getUserSubscriptions () {
    return userSubscription ;
}
@OneToOne(mappedBy="userId")
@JoinColumn(name = "USER_ID")
public User getUser() {
    return user;
}
@OneToOne(mappedBy="user")
public UserSubscription getUserSubscription() {
    return userSubscription;
}
@OneToMany(mappedBy="user")
public Collection<UserSubscription> getUserSubscriptions () {
    return userSubscription ;
}
@OneToOne
@JoinColumn(name="Subscription_Id")
public Subscription getSubscription() {
    return subscription;
}