Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 传递持久性&&引用;已分离的实体传递给persist“;_Spring_Hibernate_Jpa 2.0_Nhibernate Mapping - Fatal编程技术网

Spring 传递持久性&&引用;已分离的实体传递给persist“;

Spring 传递持久性&&引用;已分离的实体传递给persist“;,spring,hibernate,jpa-2.0,nhibernate-mapping,Spring,Hibernate,Jpa 2.0,Nhibernate Mapping,我想(希望)我做的一切都是对的。谷歌搜索了很多,都找不到问题所在 Profile可以有多个约会。 每个约会都有一个部门 部门被加载并存储在一个集合中,当然是分离的 将创建约会,并从上述集合中获取一个部门 约会将添加到配置文件中 配置文件被持久化 为部门抛出传递给persist的分离实体 简介: @Entity @Table(name = "PROFILE") public class Profile { /** * */ private Set<Appointment> a

我想(希望)我做的一切都是对的。谷歌搜索了很多,都找不到问题所在

Profile
可以有多个约会。 每个
约会
都有一个
部门

  • 部门被加载并存储在一个集合中,当然是分离的
  • 将创建约会,并从上述集合中获取一个部门
  • 约会将添加到配置文件中
  • 配置文件被持久化
  • 为部门抛出传递给persist的分离实体
简介:

@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 = "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;
}
}
我希望我遗漏了什么,因为我正在获取并将
Department
设置为持久状态以避免此异常


谢谢。

当您需要保存通过级联关系引用分离实体的新实体时,您必须使用
merge()
而不是
persist()
但这不是解决此问题的最佳方法

真正的问题是,
部门
关系根本就是层叠的。级联在引用相关实体逻辑上拥有的实体时是有意义的。但在您的情况下,您有一组预定义的部门,这些部门是单独管理的。因此,您无需将任何操作从
约会
级联到
部门


因此,最好的解决方案是从部门关系中移除级联。

@axtvat就是这样,谢谢。有一个问题,当配置文件是新的,约会是新的,只有一个部门不是时,我如何调用合并?请参阅。但我应该强调一点,用
merge()
替换
persist()
不是解决此问题的最佳方法,最好是以逻辑正确的方式配置级联。请查看此答案以了解类似问题
@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;
}
}
@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;
}