当前位置: 首页 > 知识库问答 >
问题:

持久性三重关联JPA/EclipseLink

拓拔泓
2023-03-14

我目前正在使用Java EE/Eclipselink和PostgreSQL开发一个web应用程序。关于我的实体,我特别管理“Project”、“User”和“Right”(读、写、删除等访问权限)。这些实体之间的关系是:一个项目可以有多个对该项目拥有不同权限的用户。因此,我得到了一个三重关联:Project+User+Right。

在这个协会坚持的过程中,我面临着一个恼人的问题。当我用它的信息持久化一个项目时,一切都很好(它在DB中,我可以在我的应用程序中使用它),我也有持久化的权限和用户。然后,我想在它们之间添加一个关联,所以我创建了名为ProjectUserRight的关联实体,我从现有实体中设置了项目、用户和权限,但当我持久化它时,我得到了以下异常:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERREUR: une valeur NULL viole la contrainte NOT NULL de la colonne « id_project »
Error Code: 0
Call: INSERT INTO project_user_right (id_right, id_project, id_user) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: InsertObjectQuery(ProjectUserRight@192db555)

下面是类项目:

@Entity
@Table(name="project")
public class Project implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id_project", unique=true, nullable=false)
private Integer idProject;


   //bi-directional many-to-one association to ProjectUserRight
@OneToMany(mappedBy="project", cascade={CascadeType.ALL})
private Set<ProjectUserRight> projetUtilDroits;


  ...

类用户:

 @Entity
 @Table(name="user")
 public class User implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id_user", unique=true, nullable=false)
private Integer idUser;


@Column(name="nom_utilisateur", nullable=false, length=50)
private String userName;

   //bi-directional many-to-one association to ProjectUserRight
@OneToMany(mappedBy="user")
private Set<ProjectUserRight> projetUtilDroits;

   ...

类右:

   @Entity
   @Table(name="right")
   public class Right implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id_right", unique=true, nullable=false)
private Integer idRight;

@Column(name="type_right", nullable=false, length=10)
private String typeRight;

//bi-directional many-to-one association to ProjectUserRight
@OneToMany(mappedBy="right")
private Set<ProjectUserRight> projetUtilDroits;

    ...

和association类:

 @Entity
 @Table(name="project_user_right")
 public class ProjectUserRight implements Serializable {
private static final long serialVersionUID = 1L;

@EmbeddedId
private ProjectUserRightPK id;

//bi-directional many-to-one association to Right
    @ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name="id_right", insertable=false, updatable=false)
private Right right;

//bi-directional many-to-one association to Project
@ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name="id_project", insertable=false, updatable=false)
private Project project;

//bi-directional many-to-one association to User
@ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name="id_user", insertable=false, updatable=false)
private User user;

和ProjectUserRightPK(注释后编辑):

@Embeddable
public class ProjectUserRightPK implements Serializable {
//default serial version id, required for serializable classes.
private static final long serialVersionUID = 1L;

@Column(name="id_project", unique=true, nullable=false)
private Integer idProject;

@Column(name="id_right", unique=true, nullable=false)
private Integer idRight;
    ...//getters and setters
@Column(name="id_user", unique=true, nullable=false)
private Integer idUser;

我编写了以下代码来持久化关联:

 Project project = getService(Projet.class).getFromID(projectId);//retrieve the existing project from database with id

 User user = getService(Utilisateur.class).getFromID(userId);//retrieve the existing user from database with id

 Right right = getService(Right.class).getFromID(rightId);//retrieve the existing right from database with id
 if(project !=null && user!=null && right!=null){
   ProjectUserRight pud = new ProjectUserRight();
   pud.setRight(right);
   pud.setProject(project);
   pud.setUser(user);
   project.getProjectUserRights().add(pud);
   right.getProjectUserRights().add(pud);
   user.getProjectUserRights().add(pud);
   service(ProjetUtilDroit.class).persist(pud);//call the persist function on this entity (works fine with all other entities)
   }

我也尝试合并项目,而不是保留关联,但我得到了同样的错误。(我还检查了id项目,它是正确设置的)我想知道是不是这个关联被错误地注释了,但我找不到正确的方法来更改它。

所以,我真的需要你的帮助!:-)

共有1个答案

施阳夏
2023-03-14

您错过了@mapsid批注:

指定ManyToOne或OneToOne关系属性,该属性为EmbeddedId主键、EmbeddedId主键内的属性或父实体的简单主键提供映射。value元素指定复合键中与relationship属性对应的属性。

@MapsId("idRight")
@ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name="id_right")
private Right right;

@MapsId("idProject")
@ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name="id_project")
private Project project;

@MapsId("idUser")
@ManyToOne(cascade={CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name="id_user")
private User user;
 类似资料:
  • 我有一个使用JPA(EclipseLink)和Spring框架的JavaEE应用程序。 在添加Spring事务管理之前,我的持久性类中一切都很好。我有以下实体(对应于数据库表): > 项目 使用者 对吧 以及将用户链接到具有特定权限的项目的关联(ProjectUserRight) 关联的嵌入id: 我创建项目的方法及其权利: 它就像一个魅力(保持项目和相关的用户权限),直到我在“createPro

  • 主要内容:JPA级联持久化示例,输出结果级联持久化用于指定如果实体持久化,则其所有关联的子实体也将被持久化。 以下语法用于执行级联持久性操作 - JPA级联持久化示例 在这个例子中,我们将创建两个相互关联的实体类,但要建立它们之间的依赖关系,我们将执行级联操作。 这个例子包含以下步骤 - 第1步: 在包下创建一个名为的实体类,其中包含属性:,,以及标记为级联规范的类型的对象。 文件: StudentEntity.java - 第2步:

  • 这就是我的datasourcebean的样子

  • 问题内容: JPA中的和批注有什么区别?它们可以一起使用吗? 如果 他们可以一起使用吗?还是其中之一就足够了? 问题答案: 表示要保留属性,并且要使用标准映射。它具有允许您指定是否要延迟加载属性以及该属性是否为空的参数。 允许您指定数据库中属性要保留到的列的名称。 如果您指定一个不带另一个,那么您将获得明智的默认行为,因此,除了特殊情况外,通常人们只使用一个。 因此,如果我们想要延迟加载属性并指定

  • 问题内容: 我正在开发Java桌面应用程序,并且对使用JavaFX非常感兴趣。我计划使用MVC架构,因为我对Java EE和MVC模型有一定的经验。 我想将数据存储在嵌入式derby数据库中,并使用Hibernate作为持久层,但是找不到关于使用hibernate和JavaFX实现MVC的出色教程。 我已经创建了持久性文件,但不确定如何使其与JavaFX一起使用。在Java EE中,我注入了EJB

  • 我有两个这样的 JPA 实体: 如您所见, 字段在 和 之间形成了多对多关系,因此我认为使用 来指定字段的级联是合适的。但是,当尝试在映射中保留具有几个 值的 时,我得到以下异常: 显然,EclipseLink 不会级联我的 实例的持久性。我应该如何注释 以使级联持久工作?