【问题标题】:why i get null at relationship field?为什么我在关系字段中得到空值?
【发布时间】:2013-10-21 12:36:21
【问题描述】:

如果我运行这段代码:

Student st = new Student();
st.setFirstName("First");
st.setLastName("Last");
st.setIndexNr("11");
st.setStudentPK(new StudentPK(0, user.getIdUser()));
studentFacade.create(st);

Mail m = new Mail();
m.setContent("con");
m.setRecipient("rec");
m.setIdMail(0);
mailFacade.create(m);

List<Mail> l = new ArrayList<Mail>();
l.add(m);
st.setMailList(l);
studentFacade.edit(st);     // st have mailList property set to l

stud=studentFacade.findByIndex("11"); //after edit and get student he has mailList equal null

为什么在持久化和编辑对象后,我在 OneToMany 关系的属性中得到空值?


在数据库 MySql 中,我有 STUDENT 表和 MAIL 表:

CREATE  TABLE IF NOT EXISTS `STUDENT` (
  `id_student` MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `first_name` VARCHAR(65) NULL ,
  `last_name` VARCHAR(65) NULL ,
  `index_nr` VARCHAR(45) NULL 
)
ENGINE = InnoDB

CREATE  TABLE IF NOT EXISTS `MAIL` (
 `id_mail` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
 `recipient` TEXT NULL ,
 `content` TEXT NULL ,
 `sender_student` MEDIUMINT UNSIGNED NULL ,
  PRIMARY KEY (`id_mail`) ,
  INDEX `fk_STUDENT_id_idx` (`sender_student` ASC) ,
  CONSTRAINT `fk_STUDENT`
 FOREIGN KEY (`sender_student` )
 REFERENCES `jkitaj`.`STUDENT` (`id_student` )
 ON DELETE CASCADE
 ON UPDATE CASCADE
)
ENGINE = InnoDB

从数据库中我在 netbeans 中生成实体:

@Entity
@Table(name = "STUDENT")
public class Student implements Serializable {
 private static final long serialVersionUID = 1L;
 @EmbeddedId
 protected StudentPK studentPK;
 @Size(max = 65)
 @Column(name = "first_name")
 private String firstName;
 @Size(max = 65)
 @Column(name = "last_name")
 private String lastName;
 @Size(max = 45)
 @Column(name = "index_nr")
 private String indexNr;
 @OneToMany(mappedBy = "senderStudent",fetch=FetchType.EAGER)
 private List<Mail> mailList;

 //getters, setters ...

}

public class Mail implements Serializable {
 private static final long serialVersionUID = 1L;
 @Id
 @GeneratedValue
 @Basic(optional = false)
 @Column(name = " id_mail")
 private Integer idMail;
 @Lob
 @Size(max = 65535)
 @Column(name = "recipient")
 private String recipient; 
 @Lob
 @Size(max = 65535)
 @Column(name = "content")
 private String content;
 @JoinColumn(name = "sender_student", referencedColumnName = "id_student")
 @ManyToOne
 private Student senderStudent;

 //getters, setters...
}

编辑:

我想我忘记了 fetch@OneToMany 注释中的 Student 实体。但是当我设置为fetch=FetchType.LAZY 时,我在编辑后再次获得空值,并从数据库中获取已编辑的对象。当设置 fetch=FetchType.EAGER mailList 字段不为空。为什么?

【问题讨论】:

  • 但是当我设置fetch=FetchType.EAGER 时它不为空。你怎么解释呢?
  • 但我在数据库中没有这种关系,所以我怎样才能从 JPA 获得这个?我没有关系STUDENT - ManyToOne - Mail,但相反:STUDENT - OneToMany - Mail - 一个学生到多个邮件

标签: java mysql sql jpa openjpa


【解决方案1】:

你有太多信息和太少信息的独特组合。

如果您实际上正在运行该代码,则将其打包为一个完整的、可运行的示例——是的,它不会在另一台机器上运行,除非该机器也有数据库设置,但它会告诉我们你的一切重新做而不是只做你认为重要的部分。

给我们完整的错误信息,不要告诉我们它是什么。

在这样的网站上发布问题时要记住两件重要的事情:您不知道出了什么问题,因此您需要向我们提供完整的原始数据,而不是半途而废的分析。对我们来说,仅仅猜测事情通常是浪费时间。

【讨论】:

  • 我的错误是 NullPointerException,我调试我的应用程序并发现在编辑学生对象(添加 mailList 到它)并从数据库中检索它(通过查找方法)mailList 设置为 null
  • NullPointerException 通常带有堆栈跟踪,但您似乎不愿意分享它。您可以确保您没有遇到延迟加载字段,因为您正在使用调试器进行检查。
  • 我调试了我的应用程序,发现mailList 为空。为什么要获取堆栈跟踪?如果我使用 fetch=FetchType.LAZY 运行,我会在 null 上得到 mailList 吗?
【解决方案2】:

问题出在 OpenJPA,当我在实体的某些属性上使用 fetch=FetchType.LAZY 时。问题在于实体的生命周期。所有实体都必须重新附加到持久化上下文。

同样的问题在这里:OpenJPA - lazy fetching does not work 和这里:What's the lazy strategy and how does it work?

【讨论】:

    猜你喜欢
    • 2013-09-10
    • 1970-01-01
    • 2016-09-26
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多