Java 许多JPA获取

Java 许多JPA获取,java,orm,jpa,eclipselink,Java,Orm,Jpa,Eclipselink,嗨,我在从志愿者那里获取技能时遇到了问题。由于某些原因,我在使用此方法时无法获得列表 public Volunteer getVolunteer(int id){ Volunteer vo; Query q; q = em.createNamedQuery("Volunteer.findById").setParameter("id", id); vo = (Volunteer) q.getSingleResult(); for(Skill s: vo.getSkills())

嗨,我在从志愿者那里获取技能时遇到了问题。由于某些原因,我在使用此方法时无法获得列表

public Volunteer getVolunteer(int id){

 Volunteer vo;

 Query q;

 q = em.createNamedQuery("Volunteer.findById").setParameter("id", id);
 vo = (Volunteer) q.getSingleResult();

 for(Skill s: vo.getSkills()){
  System.out.println(s);
 }

 return vo;

}
列表为空,因此抓取似乎不起作用

我在使用JPA Eclipselink和Glassfish

感谢您的帮助

技能实体:

@Entity
@Table(name="skill")
@NamedQueries({
    @NamedQuery(name = "Skill.findAll", query = "SELECT s FROM Skill s"),
    @NamedQuery(name = "Skill.findById", query = "SELECT s FROM Skill s WHERE s.id = :id"),
    @NamedQuery(name = "Skill.findBySkillDescription", query = "SELECT s FROM Skill s WHERE s.skillDescription = :skillDescription")})
public class Skill implements Serializable {
 @Override
 public String toString() {
  return "Skill [id=" + id + ", skillDescription=" + skillDescription
    + "]";
 }

 private static final long serialVersionUID = 1L;

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 @Column(unique=true, nullable=false)
 private int id;

 @Column(name="skill_description", length=130)
 private String skillDescription;

 //bi-directional many-to-many association to Volunteer
    @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
 @JoinTable(
  name="skill_volunteer"
  , joinColumns={
   @JoinColumn(name="skill_id", nullable=false)
   }
  , inverseJoinColumns={
   @JoinColumn(name="volunteer_id", nullable=false)
   }
  )
 private List<Volunteer> volunteers;

    public Skill() {
    }

 public int getId() {
  return this.id;
 }

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

 public String getSkillDescription() {
  return this.skillDescription;
 }

 public void setSkillDescription(String skillDescription) {
  this.skillDescription = skillDescription;
 }

 public List<Volunteer> getVolunteers() {
  return this.volunteers;
 }

 public void setVolunteers(List<Volunteer> volunteers) {
  this.volunteers = volunteers;
 }

}
@Entity
@Table(name="volunteer")
@NamedQueries({
    @NamedQuery(name = "Volunteer.findAll", query = "SELECT v FROM Volunteer v"),
    @NamedQuery(name = "Volunteer.findById", query = "SELECT v FROM Volunteer v WHERE v.id = :id"),
    @NamedQuery(name = "Volunteer.findByPhone", query = "SELECT v FROM Volunteer v WHERE v.phone = :phone"),
    @NamedQuery(name = "Volunteer.findByEmail", query = "SELECT v FROM Volunteer v WHERE v.email = :email"),
    @NamedQuery(name = "Volunteer.findByFirstName", query = "SELECT v FROM Volunteer v WHERE v.firstName = :firstName"),
    @NamedQuery(name = "Volunteer.findByLastName", query = "SELECT v FROM Volunteer v WHERE v.lastName = :lastName")})
public class Volunteer implements Serializable {
 @Override
 public String toString() {
  return "Volunteer [id=" + id + ", email=" + email + ", firstName="
    + firstName + ", lastName=" + lastName + ", phone=" + phone
    + "]";
 }

 private static final long serialVersionUID = 1L;

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 @Column(unique=true, nullable=false)
 private int id;

 @Column(length=255)
 private String email;

 @Column(name="first_name", length=255)
 private String firstName;

 @Column(name="last_name", length=255)
 private String lastName;

 @Column(length=255)
 private String phone;

 //bi-directional many-to-many association to Event
 @ManyToMany(mappedBy="volunteers")
 private List<Event> events;

 //bi-directional many-to-many association to Skill
 @ManyToMany(mappedBy="volunteers", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
 private List<Skill> skills;

    public Volunteer() {
    }

 public int getId() {
  return this.id;
 }

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

 public String getEmail() {
  return this.email;
 }

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

 public String getFirstName() {
  return this.firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return this.lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public String getPhone() {
  return this.phone;
 }

 public void setPhone(String phone) {
  this.phone = phone;
 }

 public List<Event> getEvents() {
  return this.events;
 }

 public void setEvents(List<Event> events) {
  this.events = events;
 }

 public List<Skill> getSkills() {
  return this.skills;
 }

 public void setSkills(List<Skill> skills) {
  this.skills = skills;
 }

}
@实体
@表(name=“skill”)
@命名查询({
@NamedQuery(name=“Skill.findAll”,query=“从技能s中选择s”),
@NamedQuery(name=“Skill.findById”,query=“从Skill s中选择s,其中s.id=:id”),
@NamedQuery(name=“Skill.findBySkillDescription”,query=“从技能s中选择s,其中s.skillDescription=:skillDescription”)}
公共类技能实现可序列化{
@凌驾
公共字符串toString(){
return“Skill[id=“+id+”,skillDescription=“+skillDescription
+ "]";
}
私有静态最终长serialVersionUID=1L;
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(unique=true,nullable=false)
私有int-id;
@列(name=“skill\u description”,长度=130)
私有字符串技术描述;
//双向多对多协会志愿者
@ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@可接合(
name=“技能\志愿者”
,连接柱={
@JoinColumn(name=“skill\u id”,nullable=false)
}
,反向连接列={
@JoinColumn(name=“志愿者id”,null=false)
}
)
私人名单志愿者;
公共技能(){
}
公共int getId(){
返回此.id;
}
公共无效集合id(内部id){
this.id=id;
}
公共字符串getSkillDescription(){
返回此.skillDescription;
}
public void setSkillDescription(字符串skillDescription){
this.skillDescription=skillDescription;
}
公开名单{
把这个还给志愿者;
}
公众志愿者(列出志愿者){
这个。志愿者=志愿者;
}
}
和志愿者实体:

@Entity
@Table(name="skill")
@NamedQueries({
    @NamedQuery(name = "Skill.findAll", query = "SELECT s FROM Skill s"),
    @NamedQuery(name = "Skill.findById", query = "SELECT s FROM Skill s WHERE s.id = :id"),
    @NamedQuery(name = "Skill.findBySkillDescription", query = "SELECT s FROM Skill s WHERE s.skillDescription = :skillDescription")})
public class Skill implements Serializable {
 @Override
 public String toString() {
  return "Skill [id=" + id + ", skillDescription=" + skillDescription
    + "]";
 }

 private static final long serialVersionUID = 1L;

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 @Column(unique=true, nullable=false)
 private int id;

 @Column(name="skill_description", length=130)
 private String skillDescription;

 //bi-directional many-to-many association to Volunteer
    @ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
 @JoinTable(
  name="skill_volunteer"
  , joinColumns={
   @JoinColumn(name="skill_id", nullable=false)
   }
  , inverseJoinColumns={
   @JoinColumn(name="volunteer_id", nullable=false)
   }
  )
 private List<Volunteer> volunteers;

    public Skill() {
    }

 public int getId() {
  return this.id;
 }

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

 public String getSkillDescription() {
  return this.skillDescription;
 }

 public void setSkillDescription(String skillDescription) {
  this.skillDescription = skillDescription;
 }

 public List<Volunteer> getVolunteers() {
  return this.volunteers;
 }

 public void setVolunteers(List<Volunteer> volunteers) {
  this.volunteers = volunteers;
 }

}
@Entity
@Table(name="volunteer")
@NamedQueries({
    @NamedQuery(name = "Volunteer.findAll", query = "SELECT v FROM Volunteer v"),
    @NamedQuery(name = "Volunteer.findById", query = "SELECT v FROM Volunteer v WHERE v.id = :id"),
    @NamedQuery(name = "Volunteer.findByPhone", query = "SELECT v FROM Volunteer v WHERE v.phone = :phone"),
    @NamedQuery(name = "Volunteer.findByEmail", query = "SELECT v FROM Volunteer v WHERE v.email = :email"),
    @NamedQuery(name = "Volunteer.findByFirstName", query = "SELECT v FROM Volunteer v WHERE v.firstName = :firstName"),
    @NamedQuery(name = "Volunteer.findByLastName", query = "SELECT v FROM Volunteer v WHERE v.lastName = :lastName")})
public class Volunteer implements Serializable {
 @Override
 public String toString() {
  return "Volunteer [id=" + id + ", email=" + email + ", firstName="
    + firstName + ", lastName=" + lastName + ", phone=" + phone
    + "]";
 }

 private static final long serialVersionUID = 1L;

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 @Column(unique=true, nullable=false)
 private int id;

 @Column(length=255)
 private String email;

 @Column(name="first_name", length=255)
 private String firstName;

 @Column(name="last_name", length=255)
 private String lastName;

 @Column(length=255)
 private String phone;

 //bi-directional many-to-many association to Event
 @ManyToMany(mappedBy="volunteers")
 private List<Event> events;

 //bi-directional many-to-many association to Skill
 @ManyToMany(mappedBy="volunteers", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
 private List<Skill> skills;

    public Volunteer() {
    }

 public int getId() {
  return this.id;
 }

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

 public String getEmail() {
  return this.email;
 }

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

 public String getFirstName() {
  return this.firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return this.lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public String getPhone() {
  return this.phone;
 }

 public void setPhone(String phone) {
  this.phone = phone;
 }

 public List<Event> getEvents() {
  return this.events;
 }

 public void setEvents(List<Event> events) {
  this.events = events;
 }

 public List<Skill> getSkills() {
  return this.skills;
 }

 public void setSkills(List<Skill> skills) {
  this.skills = skills;
 }

}
@实体
@表(name=“志愿者”)
@命名查询({
@NamedQuery(name=“志愿者.findAll”,query=“从志愿者v中选择v”),
@NamedQuery(name=“志愿者.findById”,query=“从志愿者v中选择v,其中v.id=:id”),
@NamedQuery(name=“志愿者.findByPhone”,query=“从志愿者v中选择v,其中v.phone=:phone”),
@NamedQuery(name=“志愿者.findByEmail”,query=“从志愿者v中选择v,其中v.email=:email”),
@NamedQuery(name=“志愿者.findByFirstName”,query=“从志愿者v中选择v,其中v.firstName=:firstName”),
@NamedQuery(name=“志愿者.findByLastName”,query=“从志愿者v中选择v,其中v.lastName=:lastName”)}
公共类实现了可序列化{
@凌驾
公共字符串toString(){
return“志愿者[id=“+id+”,email=“+email+”,firstName=”
+firstName+”,lastName=“+lastName+”,phone=“+phone”
+ "]";
}
私有静态最终长serialVersionUID=1L;
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(unique=true,nullable=false)
私有int-id;
@列(长度=255)
私人字符串电子邮件;
@列(name=“first_name”,长度=255)
私有字符串名;
@列(name=“last_name”,长度=255)
私有字符串lastName;
@列(长度=255)
私人电话;
//事件的双向多对多关联
@许多人(mappedBy=“志愿者”)
私人列表活动;
//技能的双向多对多关联
@ManyToMany(mappedBy=“志愿者”,cascade=CascadeType.ALL,fetch=FetchType.EAGER)
私人名单技能;
公共志愿者(){
}
公共int getId(){
返回此.id;
}
公共无效集合id(内部id){
this.id=id;
}
公共字符串getEmail(){
返回此电子邮件;
}
公用电子邮件(字符串电子邮件){
this.email=电子邮件;
}
公共字符串getFirstName(){
返回这个.firstName;
}
public void setFirstName(字符串firstName){
this.firstName=firstName;
}
公共字符串getLastName(){
返回this.lastName;
}
public void setLastName(字符串lastName){
this.lastName=lastName;
}
公共字符串getPhone(){
还这个电话;
}
公用无效设置电话(字符串电话){
this.phone=电话;
}
公共列表getEvents(){
返回此项。事件;
}
公共void setEvents(列出事件){
这个事件=事件;
}
公共列表getSkills(){
归还这本书。技能;
}
公共技能(列出技能){
这就是:技能=技能;
}
}
列表为空,因此抓取似乎不起作用

获取一个空列表并不意味着“获取”不起作用,无论您使用的是惰性获取类型还是渴望获取类型,您都应该获取给定志愿者的技能记录(如果有的话)

因为映射看起来是正确的,所以我将首先查看生成的SQL并对数据库运行它以确认

  • 生成的SQL是预期的结果
  • 确保数据是正确的
  • 为此,请在
    persistence.xml
    中设置以下属性:

      <property name="eclipselink.logging.level" value="FINEST" />
      <property name="eclipselink.logging.level.sql" value="FINEST" />
    
    
    
    然后找到
    findById
    getSkills
    的SQL查询,并对数据库运行它们

    并且请用获得的给定id的结果更新问题(生成的SQL和数据是否正常的确认)。

    只需尝试使用em.flush(),它对我有用

    Query q = em.createNamedQuery("Volunteer.findById").setParameter("id", id);
    vo = (Volunteer) q.getSingleResult();
    em.flush();
    for(Skill s: vo.getSkills()){
        System.out.println(s);  
    }
    

    双向关系最常见的问题是当用户不同时维护双方时——JPA实体是普通java对象,JPA不会像EJB2.0那样为您修复关系。将志愿者添加到技能时,还必须将该技能添加到志愿者,以便缓存与您在数据库中强制执行的更改保持同步