1

我认为(希望)我在做所有正确的事情。谷歌了很多,找不到什么问题。

Profile可以有多个Appointments。每个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为持久状态以避免此异常。

谢谢你。

4

1 回答 1

2

When you need to save a new entity that references detached entities via cascaded relationships you have to use merge() instead of persist(), but it's not the best way to solve this problem.

The real problem is that department relaionship has cascading at all. Cascading makes sense when referring to entities that the entity in question logically own. But in your case you have a predefined set of Departments that is managed separately. Therefore you never need to cascade any operation from Appointment to Department.

So, the best solution is to remove cascading from department relationship.

于 2013-06-26T17:56:28.280 回答