【问题标题】:JPA @ManyToOne Two TablesJPA @ManyToOne 两个表
【发布时间】:2018-07-04 11:14:09
【问题描述】:

我有两张表 Student 和 Student_Pseudo。
一个 Pseudo 可以归因于一个或多个 Student。

学生包含

* Student_code 
* Student_login 

Student_Pseudo 包含

* Stu_code 
* Pseudo 

Stu_code 是 Student_code 的外键

我想使用 @ManyToOne 关系在学生实体中获取 Pseudo,但它不起作用

@ManyToOne(optional = false)
    @JoinColumn(name="STU_CODE", referencedColumnName="STUDENT_CODE", nullable=false)
    private Pseudo pseudo;

当我得到学生时,Pseudo 始终为空!!!

【问题讨论】:

  • 您的映射(或您的描述)错误:Student 中的连接列名为 STUDENT_CODE,而不是 STU_CODE。它在伪表中引用的列名为 STU_CODE,而不是 STUDENT_CODE。为什么首先会出现这种不一致的命名?你让自己的生活变得比应有的更艰难。
  • 感谢您的回复。项目中的表格很旧,我无法更改它们。你的意思是我应该把 name="STUDENT_CODE", referencedColumnName="STU_CODE" ?
  • 是的,我就是这个意思。
  • 这样做我得到了一个错误堆栈。
  • @Samy 请用该错误更新您的问题

标签: java eclipselink jpa-2.0


【解决方案1】:

嗯,这是一个小环岛,但它是我想到的第一件事,它确实有效。您说您需要获取学生的伪代码,因此在 Student 中添加了 Set。它应该是EmbeddableCollection,因为我没有看到您在 student_pseudo 中引用任何主键。外键由父实体创建,您只需使用JoinColumn 命名它。其他的都是多余的。

@Entity
public class Student {
    @Id private int studentCode;
    private String studentLogin;
    @ElementCollection(targetClass=StudentPseudo.class)
    @CollectionTable(joinColumns={@JoinColumn(name="stu_code")})
    private Set<StudentPseudo> pseudos = new HashSet<>();


@Embeddable
public class StudentPseudo {
    private String pseudo;

也许你的问题在于获取它。

tx.begin();
Student student = new Student();
student.setStudentCode(1);
StudentPseudo studentPseudo1 = new StudentPseudo();
studentPseudo1.setPseudo("ps1");
student.getPseudos().add(studentPseudo1);
StudentPseudo studentPseudo2 = new StudentPseudo();
studentPseudo2.setPseudo("ps2");
student.getPseudos().add(studentPseudo2);

em.persist(student);
tx.commit();

em.clear();

List<Student> rl = em.createQuery("select distinct s from Student s left join fetch s.pseudos", Student.class).getResultList();

System.out.println(rl.get(0) + Arrays.toString(rl.get(0).getPseudos().toArray()));

这给了

Hibernate: select distinct student0_.studentCode as studentC1_1_, student0_.studentLogin as studentL2_1_, pseudos1_.stu_code as stu_code1_2_0__, pseudos1_.pseudo as pseudo2_2_0__ from Student student0_ left outer join Student_pseudos pseudos1_ on student0_.studentCode=pseudos1_.stu_code
model.Student@2e380628[model.StudentPseudo@2b8bd14b, model.StudentPseudo@5f13be1]

【讨论】:

  • 感谢您的回复。一个学生只能有一个伪,多个学生可以有相同的伪。你认为收藏是解决方案吗? Student_pseudo 中的主键是 CONSTRAINT "STUDENT_PSEUDO_PK" PRIMARY KEY ("STU_CODE", "PSEUDO")
  • 你可以用实体来做到这一点。您应该让您的问题更清楚地说明您遇到或没有遇到什么问题。
  • 我需要的是,例如,如果我有 3 名学生,分别有 student_code (1, 2, 3) 和 student_login (St_1, St_2, St_3)。假设学生 1 和 2 具有相同的伪“PST”。在 Student_pseudo 表中,我将有两个值 [Stu_code = 1, Pseudo = 'PST'] , [Stu_code = 2, Pseudo = 'PST']。我需要的是,当我加载学生时,我想在实体 Student 中添加一个伪属性,St_1 和 St_2 的值为“PST”,St_3 的值为 (null)
【解决方案2】:

假设 Student_Pseudo 是 Student 和 Pseudo 之间的关系表,有多种方法可以做到这一点,但最简单的是:

@ManyToOne(optional = false)
@JoinTable(
    name = "Student_Pseudo", 
    joinColumns = @JoinColumn(name = "PSEUDO"), 
    inverseJoinColumns = @JoinColumn(name="STU_CODE", referencedColumnName="STUDENT_CODE", nullable=false))
private Pseudo pseudo;

【讨论】:

    【解决方案3】:

    我终于根据@Chris 的回复找到了解决方案。感谢大家的帮助。

    @ManyToOne(optional = false)
        @JoinTable(
            name = "Student_Pseudo", 
            joinColumns = @JoinColumn(name = "STU_CODE", nullable=false), 
            inverseJoinColumns = @JoinColumn(name="STU_CODE", nullable=false))
    private Pseudo pseudo;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-08
      • 2021-02-09
      • 2019-03-31
      • 2016-12-27
      • 1970-01-01
      • 2023-04-05
      • 2016-11-14
      相关资源
      最近更新 更多