【问题标题】:Hibernate @ManyToMany Class Annotations ConfigureHibernate @ManyToMany 类注解配置
【发布时间】:2019-06-25 01:02:01
【问题描述】:

我正在学习 Hibernate 并尝试创建一个简单的网络应用程序。每次运行下面的代码时,由于类注释配置错误,我都会收到一条错误消息。我尝试了很多教程 - 但都没有成功。

@Entity
@Table(name = "POST")
public class Post extends IdEntity {
    private long id;
    private String message;
    private Date datePosted;
    private String location;
    private List<User> usersTagged = new ArrayList<>();
    private User userPosted;
    private User userPagePosted;

    @Id
    @SequenceGenerator(name = "POST_SEQ", sequenceName = "POST_SEQ", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "POST_SEQ")
    @Column(name = "POST_ID")
    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    @Column(name = "MESSAGE")
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Column(name = "DATE_POSTED")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "YYYY-MM-DD HH:mm:ss")
    public Date getDatePosted() {
        return datePosted;
    }

    public void setDatePosted(Date datePosted) {
        this.datePosted = datePosted;
    }

    @Column(name = "LOCATION")
    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    @ManyToMany(cascade = {CascadeType.ALL})
    @JoinTable(
            name = "USERS_POST",
            joinColumns = {@JoinColumn(name = "USER_ID")},
            inverseJoinColumns = {@JoinColumn(name = "POST_ID")}
    )
    @Column(name = "USERS_TAGGED")
    public List<User> getUsersTagged() {
        return usersTagged;
    }

    public void setUsersTagged(List<User> usersTagged) {
        this.usersTagged = usersTagged;
    }

    @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "USER_POSTED")
    @JsonBackReference
    public User getUserPosted() {
        return userPosted;
    }

    public void setUserPosted(User userPosted) {
        this.userPosted = userPosted;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinTable(
            name = "USERS_POST",
            joinColumns = {@JoinColumn(name = "USER_ID")},
            inverseJoinColumns = {@JoinColumn(name = "POST_ID")}
    )
    public User getUserPagePosted() {
        return userPagePosted;
    }

    public void setUserPagePosted(User userPagePosted) {
        this.userPagePosted = userPagePosted;
    }

@Entity
@Table(name = "USERS")
public class User extends IdEntity {
    private long id;
    private String userName;
    private String realName;
    private String email;
    private String phoneNumber;
    private Date birthDate;
    private List<Post> posts = new ArrayList<>();
    private String password;


    @Id
    @SequenceGenerator(name = "SEQ", sequenceName = "USER_SEQ", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "SEQ")
    @Column(name = "USER_ID")
    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    @Column(name = "USER_NAME")
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Column(name = "REAL_NAME")
    public String getRealName() {
        return realName;
    }

    public void setRealName(String realName) {
        this.realName = realName;
    }

    @Column(name = "EMAIL")
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Column(name = "PHONE_NUMBER")
    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    @Column(name = "BIRTH_DATE")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "YYYY-MM-DD HH:mm:ss")
    public Date getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    @OneToMany(targetEntity = Post.class, mappedBy = "userPosted", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JsonManagedReference
    public List<Post> getPosts() {
        return posts;
    }

    public void setPosts(List<Post> posts) {
        this.posts = posts;
    }

    @Column(name = "PASSWORD")
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

@Entity
@Table(name = "RELATIONSHIP")
public class Relationship implements Serializable {
    private long userIdFrom;
    private long userIdTo;
    private RelationshipStatus status;
    private Date friendsRequestDate;


    @Id
    @Column(name = "USER_ID_FROM")
    public long getUserIdFrom() {
        return userIdFrom;
    }

    public void setUserIdFrom(long userIdFrom) {
        this.userIdFrom = userIdFrom;
    }

    @Id
    @Column(name = "USER_ID_TO")
    public long getUserIdTo() {
        return userIdTo;
    }

    public void setUserIdTo(long userIdTo) {
        this.userIdTo = userIdTo;
    }

    @Enumerated(EnumType.STRING)
    @Column(name = "STATUS")
    public RelationshipStatus getStatus() {
        return status;
    }

    public void setStatus(RelationshipStatus status) {
        this.status = status;
    }

    @Column(name = "FRIENDS_REQUEST_DATE")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "YYYY-MM-DD HH:mm:ss")
    public Date getFriendsRequestDate() {
        return friendsRequestDate;
    }

    public void setFriendsRequestDate(Date friendsRequestDate) {
        this.friendsRequestDate = friendsRequestDate;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Relationship that = (Relationship) o;
        return userIdFrom == that.userIdFrom &&
                userIdTo == that.userIdTo &&
                status == that.status;
    }

    @Override
    public int hashCode() {
        return Objects.hash(userIdFrom, userIdTo, status);
    }

SQL:

CREATE TABLE USERS
(
    USER_ID      NUMBER PRIMARY KEY,
    USER_NAME    NVARCHAR2(64),
    REAL_NAME    NVARCHAR2(64),
    EMAIL        NVARCHAR2(64),
    PHONE_NUMBER NVARCHAR2(64),
    BIRTH_DATE   TIMESTAMP,
    POST_ID      NUMBER,
    PASSWORD     NVARCHAR2(16)

);

CREATE TABLE POST
(
    POST_ID          NUMBER PRIMARY KEY,
    MESSAGE          NVARCHAR2(128),
    DATE_POSTED      TIMESTAMP,
    LOCATION         NVARCHAR2(128),
    USERS_TAGGED     NUMBER,
    USER_POSTED      NUMBER,
    USER_PAGE_POSTED NUMBER,
    CONSTRAINT USER_TARGET_FK FOREIGN KEY (USERS_TAGGED) REFERENCES USERS (USER_ID),
    CONSTRAINT USER_POSTED_FK FOREIGN KEY (USER_POSTED) REFERENCES USERS (USER_ID),
    CONSTRAINT USER_PAGE_POSTED_FK FOREIGN KEY (USER_PAGE_POSTED) REFERENCES USERS (USER_ID)
);

ALTER TABLE USERS
    ADD CONSTRAINT POST_FK FOREIGN KEY (POST_ID) REFERENCES POST (POST_ID);

CREATE TABLE RELATIONSHIP
(
    USER_ID_FROM         NUMBER NOT NULL,
    USER_ID_TO           NUMBER NOT NULL,
    STATUS               NVARCHAR2(256),
    FRIENDS_REQUEST_DATE TIMESTAMP,
    CONSTRAINT FK_USER_ONE FOREIGN KEY (USER_ID_FROM) REFERENCES USERS (USER_ID),
    CONSTRAINT FK_USER_TWO FOREIGN KEY (USER_ID_TO) REFERENCES USERS (USER_ID),
    CONSTRAINT PK_RELATIONSHIP PRIMARY KEY (USER_ID_FROM, USER_ID_TO)

);

CREATE TABLE USERS_POST
(
    USER_ID NUMBER,
    POST_ID NUMBER,
    CONSTRAINT USERS_POST_PK PRIMARY KEY (USER_ID, POST_ID),
    CONSTRAINT USER_ID_FK FOREIGN KEY (USER_ID) REFERENCES USERS (USER_ID),
    CONSTRAINT POST_ID_FK FOREIGN KEY (POST_ID) REFERENCES POST (POST_ID)
);

现在我有这个错误:

ORA-02291: integrity constraint violated-(ROOT.POST_ID_FK) parent key not found.

不知道为什么会出现这个错误?你能帮我处理一下吗,也许你会看到一些其他的配置错误。

【问题讨论】:

    标签: java hibernate jpa orm


    【解决方案1】:

    您的 ID 生成器不正确。您正在混合 SEQUENCE 和 IDENTITY:

    如果要使用数据库序列,对于 Oracle 或 PosgreSQL 等数据库,代码必须如下所示:

    @Id
    @SequenceGenerator(name = "POST_SEQ", sequenceName = "POST_SEQ", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "POST_SEQ")
    @Column(name = "POST_ID")
    public long getId() {
        return id;
    }
    

    如果你有一个支持自动增量的数据库,比如 MySQL,你必须配置:

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "POST_ID")
    public long getId() {
        return id;
    }
    

    那么你和ManyToMany同一个表有ManyToOne关系。这可能效果不佳,因为在 ToOne 关系中,您通常在相关表之一上拥有外键:

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinTable(
            name = "USERS_POST",
            joinColumns = {@JoinColumn(name = "USER_ID")},
            inverseJoinColumns = {@JoinColumn(name = "POST_ID")}
    )
    public User getUserPagePosted() {
        return userPagePosted;
    }
    

    【讨论】:

    • 您能否详细介绍一下与ManyToMany 相同的表的ManyToOne 关系。我该如何解决?我必须创建第四个表吗?
    【解决方案2】:

    我发现了问题。 joinColumns 是关联的拥有方,USER 不拥有该方,POST 拥有。

     @ManyToMany(cascade = {CascadeType.ALL})
        @JoinTable(
                name = "USERS_POST",
                joinColumns = {@JoinColumn(name = "POST_ID")},
                inverseJoinColumns = {@JoinColumn(name = "USER_ID")}
        )
    

    并且@ManyToOne 必须没有@JoinTable

    【讨论】:

      猜你喜欢
      • 2017-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-07
      • 2011-11-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-14
      相关资源
      最近更新 更多