java - Hibernate 一对多关系

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

我遇到了 hibernate OneToMany 关系的问题。由于某种原因, hibernate 在以正确的方式保存关系方面存在问题。这是两个类:

@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();
}
}

该问题仅发生在项目和工作包之间的 OnetoMany 关系中。由于某种原因,hibernate 没有正确地将对象保存在数据库中,工作包表中缺少项目 ID,因此没有链接。

编辑:我之前有 getter 和 setter,现在发布了整个类(class)......

编辑2:

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

第二类:

@ManyToOne
private Project project;

对我有用......

最佳答案

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

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

关于java - Hibernate 一对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22147309/

相关文章:

jsf - 如何启用/禁用 primefaces 命令按钮?

java - JAVA发送邮件时出现空指针异常

javascript - 如何从浏览器控制台访问 GWT 的 JsInterop 导出类型?

java - 如何将现有的 android studio 项目导入到 eclipse 中,使其成为原生的并成为代号应用程序?

hibernate - GGTS中使用grails的警告

java - 从日期中拆分日期和时间以单独键入

java - 如何在 Java 中使用 ln

java - JPA2/Hibernate - 停止延迟加载?

java - Hibernate查询语言: selecting some properties requires alias name

jsf - 有条件地渲染 <ui :include>