java - 如何正确向jpa onetomany join表添加记录

标签 java mysql hibernate jpa jpa-2.0

我正在开发一个归档系统,其中有 3 个表。 PROJECTS 表由projectid、项目名称和其他详细信息组成(见下文)。这是一个现有的类和填充的架构,如果可能的话,我不想修改应用程序的这一部分。

文件夹表(称为ProjectClassification)由folderid 和foldername 组成,是单向一对多关系的拥有方。

Project_Folders 是一个连接表。我使用 JPA 2.0 (EclipseLink) 和 JSF 2.0 作为我的 Web 框架。

我的基本问题是我无法使用合并操作将重复记录添加到连接表中。 MERGE 适合添加记录,直到拥有的键已经存在,之后它只会更新连接表。我知道这是它应该工作的方式,但即使拥有 key 重复,我也需要添加新记录。这将允许我将不同的项目存储在同一文件夹中。

我在这里查看了一些其他问题,例如:

onetomany unidirectional with jointable setup using jpa

这说明了在连接表中将一个实体添加到另一个实体需要什么,但我需要了解有关如何正确保留或将添加的实体合并到数据库的更多信息。

文件夹实体类:

@Entity
@Table(name = "PROJECTCLASSIFICATIONS")
public class ProjectClassifications implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int proclassid;
private int projectid;

private String classification;

@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "PROJECT_CLASSF_JOIN",
        joinColumns = @JoinColumn(name = "proclassid", referencedColumnName = "proclassid"),
        inverseJoinColumns = @JoinColumn(name = "projectid", referencedColumnName = "projectid", unique = true))

private Collection<Projects> projects;

public ProjectClassifications() {

}

public ProjectClassifications(String classification) {
    this.classification = classification;
}

public ProjectClassifications(int proclassid, int projectid) {
    this.proclassid = proclassid;

    projects = new ArrayList<Projects>();
}

public ProjectClassifications(Projects newProject) {

    projects = new ArrayList<Projects>();

}

public void addProject(Projects newProject) {
    if(!getProjects().contains(newProject))
    getProjects().add(newProject);
}

....
....

项目实体类是预先存在的代码,如果可能的话我根本不想修改:

@Entity
@Table(name = "PROJECTS")
public class Projects {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int projectid;

private String projectName;
private String projectDescription;

@Temporal(javax.persistence.TemporalType.DATE)
private Date startDate;
@Temporal(javax.persistence.TemporalType.DATE)
private Date endDate;
private String commnts;



// foreign keys to parent tables
private int fk_countryid;
private int fk_companyid;
private int fk_employeeid;

@ManyToOne(optional = true)
@JoinColumn(name = "countryid")
private Country country;
....
....

然后,我使用两个 html 选择列表来选择 projectid 和 proclassid 的值,它们使用 JSF 托管 bean 调用以下方法:

public String makeProClassRecord() {
   newProClass = new ProjectClassifications(proclassid, projectid);
   newProject = proServ.findByProjectId(projectid);
   newProClass.addProject(newProject);


facade.update(newProClass);
//facade.save(newProClass);
    return showProclass();
}

我的问题是:

1) MERGE 是将记录添加到连接表中的正确操作吗?

2) 有没有办法使用 MERGE 添加包含重复键的记录(外键在连接表中表示为新记录)?

3) 应该使用 PERSIST 来实现问题 2 吗?

4) 为连接表本身创建一个实体并简单地使用 PERSIST 方法插入记录会更好吗?

非常感谢

最佳答案

所以几周前我自己解决了这个问题并考虑分享答案。我没有对任何目标实体执行合并或持久操作,而是创建了一个连接表和从 Project 实体到下面的 ProjectFileSystem 连接表实体的单向 OneToMany 关系,并使用该实体简单地执行了持久操作。我需要为不同的项目添加重复的文件夹(或在单个文件夹项下存储许多项目),因此在实际连接表实体中执行 CRUD 操作似乎比从目标实体中执行 CRUD 操作更有效。希望这有帮助:

@Entity
@Table(name = "PROFOLDERSYS_JOIN")

public class ProjectFileSystem implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int foldersysid;

private int proclassid;

private int projectid;

private String projectName;

private String folderName;

public ProjectFileSystem() {

}

public ProjectFileSystem(int proclassid, int projectid,
        String projectName, String folderName) {
    this.proclassid = proclassid;
    this.projectid = projectid;
    this.projectName = projectName;
    this.folderName = folderName;
}


// getters and setters
}

bean 中的方法是:

public String makeProSys() {
    newProSys = new ProjectFileSystem(proclassid, projectid,     classification, projectName);

    newProject = proServ.findByProjectId(projectid);
    projectName = newProject.getProjectName();
    newProSys.setProjectName(projectName);

    newProClass = facade.findByContactId(proclassid);
    classification = newProClass.getClassification();
    newProSys.setFolderName(classification);

    profilFacade.save(newProSys);
    return showProSys();
}

关于java - 如何正确向jpa onetomany join表添加记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29981455/

相关文章:

java - Hibernate @Formula 导致 org.hibernate.HibernateException : Missing column

java - ClassNotFoundException : org. hibernate .bytecode.instrumentation.internal.FieldInterceptionHelper

database - 数据库迁移 - Hibernate/JPA - hbm2ddl - diff 工具

java - 使用 JDBC 将对象(文档文件)存储到 SQL 中

mysql - 如何将将一列分成两列的 MySQL 查询结果添加到表中?

java <identifier> 期望在初始化变量时

php - 复杂的 MySQL 查询?

php - 搜索多个表php activerecord

java - 为同一个 Titan Graph 创建多个实例

java - 具有填充方法的数据结构设计模式?