簡體   English   中英

多對多JPA提取

[英]ManyToMany JPA fetch

嗨,我在從志願者那里獲取技能時遇到問題。 由於某種原因,使用此方法時我沒有得到列表

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;
 }

}

只是嘗試使用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不能像以前的EJB 2.0那樣為您修復關系。 將志願者添加到技能時,還必須將技能添加到志願者,以便緩存與您要在數據庫中強制執行的更改保持同步。

該列表為空,因此獲取似乎無效。

獲取空列表並不能得出“獲取”無效的結論,並且無論您使用LAZY還是EAGER訪存類型,都應該獲取給定志願者的技能記錄(如果有)。

而且由於映射看起來正確,因此我將首先查看生成的SQL,然后對數據庫運行它以確認

  1. 生成的SQL是預期結果
  2. 數據正確。

為此,請在persistence.xml設置以下屬性:

  <property name="eclipselink.logging.level" value="FINEST" />
  <property name="eclipselink.logging.level.sql" value="FINEST" />

然后找到findByIdgetSkills的SQL查詢,並針對數據庫運行它們。

並請使用給定id的獲得結果更新問題(生成的SQL和確認數據都正確)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM