2013-06-26 58 views
1

我認爲(希望)我正在做所有正確的事情。 Google搜索了很多,無法找到問題所在。可以有多個Appointment s。每個Appointment有一個Department傳遞持久性&「分離的實體傳遞到堅持」

  • 部門被加載和存儲在一個集合,當然,分離。
  • 約會已創建並從上述集合中獲取部門。
  • 約會被添加到配置文件。
  • 個人資料持續存在。通過堅持
  • 脫離實體拋出部

簡介:

@Entity 
@Table(name = "PROFILE") 
public class Profile { 
/** 
* 
*/ 
private Set<Appointment> appointments = new HashSet<Appointment>(); 

/** 
* @return the appointments 
*/ 

@OneToMany(mappedBy = "profile", cascade = { CascadeType.PERSIST, 
     CascadeType.MERGE }) 
public Set<Appointment> getAppointments() { 
    return appointments; 
} 

/** 
* @param appointments 
*   the appointments to set 
*/ 
public void setAppointments(Set<Appointment> appointments) { 
    this.appointments = appointments; 
} 

/** 
* 
* @param apt 
*/ 
public void addAppointment(Appointment apt) { 
    apt.setProfile(this); 
    appointments.add(apt); 
} 
} 

約會:

@Entity 
@Table(name = "APPOINTMENT") 
public class Appointment { 
/** 
* 
*/ 
private Department department; 
private Profile profile; 


/** 
* @return the department 
*/ 
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY) 
@JoinColumn(name = "DEPARTMENT_ID") 
@Index(name = "IDX_APPOINTMENT_DEPARTMENT") 
@ForeignKey(name = "FK_APPOINTMENT_DEPARTMENT") 
public Department getDepartment() { 
    return department; 
} 

/** 
* @param department 
*   the department to set 
*/ 
public void setDepartment(Department department) { 
    this.department = department; 
} 

/** 
* @return the profile 
*/ 
@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY) 
@JoinColumn(name = "PROFILE_ID") 
@Index(name = "IDX_APPOINTMENT_PROFILE") 
@ForeignKey(name = "FK_APPOINTMENT_PROFILE") 
public Profile getProfile() { 
    return profile; 
} 

/** 
* @param profile 
*   the profile to set 
*/ 
public void setProfile(Profile profile) { 
    this.profile = profile; 
} 
} 

部:

@Entity 
@Table(name = "DEPARTMENT") 
public class Department { 
/** 
* 
*/ 
private Set<Appointment> appointments = new HashSet<Appointment>(); 
private Set<Department> children = new HashSet<Department>(); 
private Department parent; 


/** 
* @return the appointments 
*/ 
@OneToMany(mappedBy = "department") 
public Set<Appointment> getAppointments() { 
    return appointments; 
} 

/** 
* @param appointments 
*   the appointments to set 
*/ 
public void setAppointments(Set<Appointment> appointments) { 
    this.appointments = appointments; 
} 

/** 
* @return the children 
*/ 
@OneToMany(mappedBy = "parent", cascade = { CascadeType.PERSIST, 
     CascadeType.MERGE }) 
public Set<Department> getChildren() { 
    return children; 
} 

/** 
* @param children 
*   the children to set 
*/ 
public void setChildren(Set<Department> children) { 
    this.children = children; 
} 

/** 
* @return the parent 
*/ 
@ManyToOne(fetch = FetchType.LAZY) 
@JoinColumn(name = "PARENTDEPARTMENT_ID") 
@Index(name = "IDX_DEPARTMENT_CHILDREN") 
@ForeignKey(name = "FK_DEPARTMENT_CHILDREN") 
public Department getParent() { 
    return parent; 
} 

/** 
* @param parent 
*   the parent to set 
*/ 
public void setParent(Department parent) { 
    this.parent = parent; 
} 
} 

ŧ他犯錯誤的@Service代碼:

@Transactional(propagation = Propagation.REQUIRED) 
private Profile addNewProfile(ProfileJxb profileJxb) { 
    logger.entry(); 

    Profile profile = new Profile(profileJxb); 
    for (AppointmentJxb aptJxb : profileJxb.getAppointments() 
      .getAppointmentJxb()) { 
     Appointment apt = new Appointment(aptJxb); 
     Department d = getDepartmentByName(aptJxb.getDepartment()); // previously fetched 
     apt.setDepartment(d); 
     // d.getAppointments().add(apt); // another failed attempt, this results in LazyInitException 

     profile.addAppointment(apt); 
    } 

    profile = profileDao.makePersistent(profile); // Exception thrown here! 

    logger.exit(); 
    return profile; 
} 

我希望我失去了一些東西,因爲我取,並在持續的狀態設置Department避免這種例外。

謝謝。

+0

請檢查這個答案類似的問題http://stackoverflow.com/questions/13370221/jpa-hibernate-detached-entity-passed-to-persist/13500921#13500921 – Sam

回答

2

當你需要保存引用通過級聯關係分離的實體,你必須使用merge()代替persist()但它不是解決這個問題的最佳方式的新實體。

真正的問題是department相關性完全級聯。級聯在涉及所涉及的實體邏輯上擁有的實體時是有意義的。但在你的情況下,你有一套預定義的Departments,它是單獨管理的。因此,您從不需要將AppointmentDepartment的任何操作級聯。

所以,最好的解決方案是從department關係中刪除級聯。

+0

@axtvat這是它,謝謝你。一個問題,當配置文件是新的時,我怎樣才能調用合併,約會是新的,只有一個部門不是? – kmansoor

+0

請參閱http://stackoverflow.com/questions/4509086/what-is-the-difference-between-persist-and-merge-in-hibernate。但是我應該強調,用merge()代替'persist()'不是解決這個問題的最好方法,而是以邏輯正確的方式配置級聯會更好。 – axtavt

相關問題