ManyToMany JPA получить - PullRequest
       0

ManyToMany JPA получить

1 голос
/ 14 сентября 2010

Привет, у меня проблема с извлечением навыков у волонтера. по какой-то причине я не получаю список при использовании этого метода

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

}

Ответы [ 3 ]

0 голосов
/ 17 сентября 2012

Просто попробуйте использовать 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);  
}
0 голосов
/ 17 сентября 2012

Наиболее распространенная проблема с двунаправленными отношениями - это когда пользователи не поддерживают обе стороны - объекты JPA являются простыми объектами java, а JPA не устанавливает для вас отношения, как в EJB 2.0. Когда вы добавляете добровольца к навыку, вы также должны добавить навык к волонтеру, чтобы кэш оставался синхронизированным с изменениями, которые вы вносите в базу данных.

0 голосов
/ 14 сентября 2010

список пуст, поэтому выборка, похоже, не работает.

Получение пустого списка не позволяет сделать вывод, что «выборка» не работает и используете ли вытип извлечения LAZY или EAGER, вы должны получить записи навыков для данного добровольца, если таковые имеются.

И поскольку отображение выглядит корректно, я бы начал с просмотра сгенерированного SQL и запуска его в базе данных

  1. для подтверждения того, что сгенерированный SQL является ожидаемым результатом
  2. , что данные верны.

Для этого установите следующие свойства вpersistence.xml:

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

Затем найдите SQL-запросы для findById и getSkills и запустите их для базы данных.

И, пожалуйста, обновите вопрос с полученным результатом для данного идентификатора (как сгенерированный SQL, так и подтверждение, что данные в порядке).

...