Hibernate OneToMany关系

时间:2014-03-03 12:51:32

标签: java hibernate jsf one-to-many hibernate-onetomany

我遇到了hibernate OneToMany关系的问题。出于某种原因,hibernate以正确的方式保存Relation有问题。以下是两个类:

@Entity
@Table
public class Project {

@Id
@GenericGenerator(name = "generator", strategy = "increment")
@GeneratedValue(generator = "generator")
@Column(unique = true, nullable = false)
private int projectId;

@Column(unique = true, nullable = false)
private String name;

@ManyToMany(fetch = FetchType.EAGER, mappedBy = "projects", targetEntity = User.class)
private Set<User> users;

@OneToMany(fetch = FetchType.EAGER, mappedBy = "project", 
        cascade = CascadeType.ALL, targetEntity = WorkingPackage.class)
private Set<WorkingPackage> workingPackages;

/**
 * Default Constructor. Creates an empty object.
 */
public Project() {
    // nothing to do here!
}

/**
 * Convenience Constructor. Use this constructor to create a new {@link Project} object.
 * 
 * @param name  The name of the project. May not be null.
 */
public Project(String name) {
    this.name = name;
}

/**
 * The id is the unique identifier for the {@link Project} in the database. DO NOT set the 
 * id manually since it will be generated by Hibernate.
 * 
 * @return  The unique identifier for the project.
 */
public int getProjectId() {
    return projectId;
}

/**
 * The id is the unique identifier for the {@link Project} in the database. DO NOT set the 
 * id manually since it will be generated by Hibernate.
 * 
 * @param projectId  The unique identifier for the project.
 */
public void setProjectId(int projectId) {
    this.projectId = projectId;
}

/**
 * Refers to the name of the {@link Project}.
 * 
 * @return  The name of the project.
 */
public String getName() {
    return name;
}

/**
 * Refers to the name of the {@link Project}.
 * 
 * @param name  The name of the project.
 */
public void setName(String name) {
    this.name = name;
}


/**
 * Gets the working packages.
 *
 * @return the working packages
 */
public Set<WorkingPackage> getWorkingPackages() {
    return workingPackages;
}

/**
 * Sets the working packages.
 *
 * @param workingPackages the new working packages
 */
public void setWorkingPackages(Set<WorkingPackage> workingPackages) {
    this.workingPackages = workingPackages;
}

/**
 * Gets the users.
 *
 * @return the users
 */
public Set<User> getUsers() {
    return users;
}

/**
 * Sets the users.
 *
 * @param users the new users
 */
public void setUsers(Set<User> users) {
    this.users = users;
}

@Override
public boolean equals(Object other) {
    if (this == other) {
        return true;
    }
    if (!(other instanceof Project)) {
        return false;
    }

    final Project project = (Project) other;

    if (!project.getName().equals(getName())) {
        return false;
    }
    return true;
}

@Override
public int hashCode() {
    return getName().hashCode();
}
}

第二课:

@Entity
@Table
public class WorkingPackage {

@Id
@GenericGenerator(name = "generator", strategy = "increment")
@GeneratedValue(generator = "generator")
@Column(unique = true, nullable = false)
private int workingPackageId;

@Column(nullable = false)
private String name;

@ManyToOne(fetch = FetchType.EAGER)
@Cascade({CascadeType.ALL })
@JoinColumn (name = "projectId")
private Project project;

/**
 * Default Constructor. Creates an empty object.1
 */
public WorkingPackage() {
    // nothing to do here!
}

/**
 * Convenience Constructor. Use this constructor to create a new {@link WorkingPackage} object.
 * 
 * @param name  The name of the project. May not be null.
 */
public WorkingPackage(String name) {
    this.name = name;
}

/**
 * The id is the unique identifier for the {@link WorkingPackage} in the database. DO NOT set the 
 * id manually since it will be generated by Hibernate.
 * 
 * @return  The unique identifier for the project.
 */
public int getWorkingPackageId() {
    return workingPackageId;
}

/**
 * The id is the unique identifier for the {@link WorkingPackage} in the database. DO NOT set the 
 * id manually since it will be generated by Hibernate.
 * 
 * @param workingPackageId  The unique identifier for the project.
 */
public void setWorkingPackage(int workingPackageId) {
    this.workingPackageId = workingPackageId;
}

/**
 * Refers to the name of the {@link WorkingPackage}.
 * 
 * @return  The name of the working package.
 */
public String getName() {
    return name;
}

/**
 * Refers to the name of the {@link WorkingPackage}.
 * 
 * @param name  The name of the working package.
 */
public void setName(String name) {
    this.name = name;
}

/**
 * Refers to the project of the {@link WorkingPackage}.
 * 
 * @return  The project of the working package.
 */
public Project getProject() {
    return project;
}

/**
 * Refers to the project of the {@link WorkingPackage}.
 * 
 * @param project  The name of the working package.
 */
public void setProject(Project project) {
    this.project = project;
}

@Override
public boolean equals(Object other) {
    if (this == other) {
        return true;
    }
    if (!(other instanceof WorkingPackage)) {
        return false;
    }

    final WorkingPackage workingPackage = (WorkingPackage) other;

    if (!workingPackage.getName().equals(getName())) {
        return false;
    }
    return true;
}

@Override
public int hashCode() {
    return getName().hashCode();
}
}

问题仅发生在Project和Workingpackage之间的OnetoMany关系中。由于某些原因,hibernate没有正确保存数据库中的对象,workpackage表中缺少projectID,因此没有链接。

编辑:之前我有过吸气剂和制定者,现在发布了所有课程......

EDIT2:

@OneToMany
@Cascade({CascadeType.SAVE_UPDATE })
@JoinColumn(name = "project_id")
private Set<WorkingPackage> workingPackages;

第二课:

@ManyToOne
private Project project;

对我有用....

1 个答案:

答案 0 :(得分:1)

您的映射将WorkingPackage定义为关系的所有者。 仅当设置了WorkingPackage.project时才会更新列projectId(如果元素已添加到Project.workingPackages中,则不会更新。)

请参阅:http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html: 该关联可以是双向的。在双向关系中,一方(并且只有一方)必须是所有者:所有者负责关联列更新。要声明一方不负责该关系,使用属性mappedBy。