【问题标题】:Creating an instance of a class and at the same time create an instance of another class that depends on the first class [duplicate]创建一个类的实例,同时创建另一个依赖于第一个类的类的实例[重复]
【发布时间】:2016-09-22 11:46:03
【问题描述】:

编辑:这个问题与链接的问题有何不同?

我认为这个问题是不同的,因为它似乎是由 JPA 试图添加另一个具有相同 id 的用户引起的,因为在类 (Student) 中添加了一个外键值。链接的问题似乎是由于未自动生成 id 引起的。

我有一个创建用户并返回用户的方法。我将此用户传递给另一种方法来创建学生。用户是学生。但我不能这样做,因为我得到了:
org.postgresql.util.PSQLException:错误:重复键值违反唯一约束“pk_user_id” 详细信息:密钥 (user_id)=(7001) 已存在。

我在 backing bean 中的方法如下所示:

public Users2 addUser(String username, String password, String emailadress, 
    String firstname, String lastname) {

    Users2 u = new Users2();
    u.setUsername(username);
    u.setPassword(password);
    u.setEmailaddress(emailadress);
    u.setFirstname(firstname);
    u.setLastname(lastname);
    System.out.println(em + ": Adding course " + u);
    em.persist(u);
    em.flush();
    System.out.println(u.getUser_id());
    return u;
}

public void addStudent(Users2 u2) {
    Student s = new Student();

    s.setUser_id(u2.getUser_id());
    s.setUsername(u2.getUsername());
    s.setLastname(u2.getLastname());
    s.setFirstname(u2.getFirstname());
    s.setPassword(u2.getPassword());
    s.setEmailaddress((u2.getEmailaddress()));

    em.persist(s);
}

我在 Jsf bean 中的方法如下所示:

@Inject
DbStore store;

public String CreateUser(){
    long usrid;

    String username = this.username;
    String password = this.password;
    String emailadress = this.emailaddress;
    String firstname = this.firstname;
    String lastname = this.lastname;
    Users2 u1 = store.addUser(username, password, emailadress, firstname, lastname);
    //System.out.println(usrid);
    String role = this.role;
    if(this.role.equals("Student"))
        store.addStudent(u1);
    return "admin_listcourses.xhtml";

}

我的实体:

import javax.persistence.Id;
import javax.validation.constraints.Max;
import java.util.List;
import java.util.Set;


@Entity
@Table(name = "student")
@SecondaryTable(name = "users2",     pkJoinColumns=@PrimaryKeyJoinColumn(name="user_id", referencedColumnName="user_id"))
public class Student {

    /**
     * Created by Elev1 on 2016-08-25.
     *
     */
    @Id
    @SequenceGenerator(name="student_student_id_seq",
        sequenceName="student_student_id_seq",
        allocationSize=1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,
        generator="seq")
    @Column(name = "student_id", updatable=false)
    private long student_id;

    @Column(table="users2", name="username")
    private String username;

    @Column(table="users2", name="firstname")
    private String firstname;

    @Column(table="users2", name="lastname")
    private String lastname;

    @Column(table="users2", name="password")
    private String password;

    @Column(table="users2", name="emailaddress")
    private String emailaddress;

    @Column(table="users2", name="user_id")

    private  long user_id;

    @ManyToMany
    @JoinTable(name="student_course",
        joinColumns=
        @JoinColumn(name="student_id", referencedColumnName="student_id"),
        inverseJoinColumns=
        @JoinColumn(name="course_id", referencedColumnName="course_id")
    )


    // public List<Course> getCourses() { return courses ; }
    public List<Course> courses;


    //Getters and setters
    public long getStudent_id() {
        return student_id;
    }

    public void setStudent_id(long student_id) {
        this.student_id = student_id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public List<Course> getCourses() {
        return courses;
    }

    public void setCourses(List<Course> courses) {
        this.courses = courses;
    }

    public long getUser_id() {
        return user_id;
    }

    public void setUser_id(long user_id) {
        this.user_id = user_id;
    }

    public String getPassword() {
        return password;
    }

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

    public String getEmailaddress() {
        return emailaddress;
    }

    public void setEmailaddress(String emailaddress) {
        this.emailaddress = emailaddress;
    }
}

package se.lexicon.entities;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

@Entity

public class Users2{

    // ***********************
    // **     Attributes    **
    // ***********************

    @Id
    @SequenceGenerator(name="users_user_id_seq",
        sequenceName="users_user_id_seq",
        allocationSize=1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,
        generator="seq")
    private Long user_id;

    @Column(name = "username", length = 64)
    private String username;

    private String password;
    @Column(name = "emailaddress", length = 64)
    private String emailaddress;

    @Column(name = "firstname")
    private String firstname;

    @Column(name = "lastname")
    private String lastname;

    @Temporal(TemporalType.TIMESTAMP)
    private Date last_login;

    // ************************
    // **     Constructors   **
    // ************************

    //  public User() {

    //     public User(Long user_id) {
    //          this.user_id = user_id;
    //      }

    //      public User(Long user_id, String username, String password, String emailaddress, ??? last_login) {

    //          this.user_id = user_id;
    //          this.username = username;
    //         this.password = password;
    //         this.emailaddress = emailaddress;
    //        this.last_login = last_login;
    //}

    // ******************************
    // **    Getters & Setters     **
    // ******************************

    public long getUser_id() {
        return user_id;
    }

    public void setUser_id(long user_id) {
        this.user_id = user_id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

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

    public String getEmailaddress() {
        return emailaddress;
    }

    public void setEmailaddress(String emailaddress) {
        this.emailaddress = emailaddress;
    }

    public Date getLast_login() {
        return last_login;
    }

    public void setLast_login(Date last_login) {
        this.last_login = last_login;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }
//}

}

编辑:我的解决方案。我删除了学生表中的foregin_key 约束。我只在 Student 类中保留了 student_id、course_id 和 user_id。我删除了 Student 类中 Student 和 Users2 之间的所有连接,如果给出了 student_id,我使用方法从 Users2 类中获取这些连接。当创建一个用户时,即Student,然后添加一个Student,并将用户的user_id设置为Student的user_id。

现在这不是一个很好的解决方案,所以如果有人能解决我最初的问题,我很乐意接受这个解决方案。但现在我的解决方案必须这样做。

【问题讨论】:

  • 您的实体类会很有趣地发现问题
  • 我现在用我的实体更新了我的问题。

标签: java jpa jakarta-ee


【解决方案1】:

当您持久化 Student 实例时,JPA 还将在 Users2 表中创建一行,并将 user_id 作为 Student 表中行的外键。但是Users2 中已经有一行具有完全相同的 ID,因为您之前保留了一个 Users2 实例。这就是为什么你会遇到这个 SQLException 的原因。

对我来说,在这里使用 SecondaryTable 方法没有多大意义,因为我的用户可能根本不是学生,对吧?但在您当前的模型中,Users 表将外键存储到 Student 表中。

在这种情况下,在这里使用继承(或某些组合)似乎更合适,而不是 SecondaryTable 方法。 Student is-a User,因此 Student 可以从 User 继承。 您将在此处找到如何定义映射的第一个概述:
https://en.wikibooks.org/wiki/Java_Persistence/Inheritance

【讨论】:

  • 如果我只想将学生表中的外键存储到用户表(user_id)而不是将用户表中的外键存储到学生表中?使用继承似乎有点乱,因为我希望用户能够成为一门课程的学生和另一门课程的老师。
  • 我不明白为什么这可能是个问题,但无论如何:如果Course 实体持有对User 的引用并且您将该字段命名为teacher 可能就足够了以及对名为students 的用户集合的引用。如果要查找教师和/或学生,则必须查找课程以获取数据。或者学生和教师类持有对“他们的”用户对象的引用。这就是我在回答中所说的 composition 的意思。无法回答 best 方法是什么样的,因为这需要更多关于所有用例等的知识。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-02
  • 2016-08-25
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多