休眠一对多关系
Posted
技术标签:
【中文标题】休眠一对多关系【英文标题】:Hibernate OneToMany Relation 【发布时间】:2014-03-03 12:51:32 【问题描述】:我遇到了休眠 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();
该问题仅出现在 Project 和 Workingpackage 之间的 OnetoMany 关系中。由于某种原因,hibernate没有正确保存数据库中的对象,工作包表中缺少projectID,因此没有链接。
编辑:我之前有 getter 和 setter,现在发布了整个类...
编辑2:
@OneToMany
@Cascade(CascadeType.SAVE_UPDATE )
@JoinColumn(name = "project_id")
private Set<WorkingPackage> workingPackages;
二等:
@ManyToOne
private Project project;
为我工作....
【问题讨论】:
你缺少 getter 和 setter ,尝试用 hibernate 生成 pojo 类,看看有什么不同 【参考方案1】:您的映射将 WorkingPackage 定义为关系的所有者。 仅当设置了 WorkingPackage.project 时才会更新列 projectId(如果将元素添加到 Project.workingPackages 则不会)。
请参阅:http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html: 该关联可以是双向的。在双向关系中,一方(并且只有一方)必须是所有者:所有者负责关联列的更新。要声明一方不负责关系,则使用属性 mappedBy。
【讨论】:
以上是关于休眠一对多关系的主要内容,如果未能解决你的问题,请参考以下文章