我遇到了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;
对我有用....
答案 0 :(得分:1)
您的映射将WorkingPackage定义为关系的所有者。 仅当设置了WorkingPackage.project时才会更新列projectId(如果元素已添加到Project.workingPackages中,则不会更新。)
请参阅:http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html: 该关联可以是双向的。在双向关系中,一方(并且只有一方)必须是所有者:所有者负责关联列更新。要声明一方不负责该关系,使用属性mappedBy。