【问题标题】:Hibernate set both crossed references on createHibernate 在创建时设置了两个交叉引用
【发布时间】:2017-11-29 07:49:34
【问题描述】:

我有两个实体,Project 和 ProjectFee:

public class Project implements Serializable {
    private Integer id;
    //some more fields
    private Set<ProjectFees> fees = new LinkedHashSet<>();
}

public class ProjectFee implements Serializable {
    //some more fields
    private Integer idProject; //id of the Project ProjectFee is related to
}

映射为:

<class name="com.package.Project" table="project">
    <id name="id" type="java.lang.Integer">
        <column name="id" />
        <generator class="identity" />
    </id>
    <!-- more fields -->
    <set name="fees" table="project_fees" cascade="all" fetch="join" lazy="false">
        <key>
            <column name="id_project"/>
        </key>
        <one-to-many class="com.package.ProjectFees"/>
    </set>

</class>

<class name="com.package.ProjectFees" table="project_fees">
    <!-- more fields -->
    <property name="idProject" type="java.lang.Integer">
        <column name="id_project" />
    </property>
</class>

因此,当我尝试使用级联创建一个新项目和一个新 ProjectFee 时,我收到一个错误,因为 idProject 在 db 中不能为空,并且它未设置,因为 Project 仍未创建,因此它没有 id。我知道我可以通过创建方法来解决它:

  1. 从项目中删除 ProjectFees
  2. 创建项目
  3. 将 ProjectFees 添加到每个项目的项目设置 idProject
  4. 更新项目

但这是一种“肮脏”的方式,所以我想知道是否有某种方法可以自动执行此操作

【问题讨论】:

  • 在关系的两边设置引用并尝试持久化它。
  • @AbdullahKhan 问题是我不能这样做,因为我没有 Project.id,因为数据库中尚不存在项目

标签: java hibernate hibernate-mapping cross-reference


【解决方案1】:

将您的 ProjectFees 映射更改为:

<many-to-one name="idProject" class="com.gesmifid2.common.model.Project">
    <column name="id_project" />
</many-to-one>

编辑:

您的 ProjectFee 类应如下所示:

public class ProjectFee implements Serializable {
    //some more fields
    private Project project; //project ProjectFee is related to
}

并且每次将新的ProjectFee 添加到Project 时,都应该在ProjectFee 中设置ProjectProject类中的方法示例:

public void addProjectFee( ProjectFee pf){
    fees.add(pf);
    pf.setProject(this);
}

【讨论】:

  • 还是同样的错误,Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'id_project' cannot be null
  • 是的,这可行,但我只想拥有 idProject,而不是 ProjectFee 中的整个项目
  • @Aldeguer 这实际上是在 ORM(双向映射)中处理数据库对象的一种方式。在您的数据库端,您只会在相应的表中获得 id。
  • @AbdullahKhan 我知道这是处理它们的一种方法,但这次我需要一些不同的东西:不是获取整个对象,而是获取 id
  • 除了 Project 之外,您还可以使用“updateable=false, insertable=false”映射 ID(需要,因为您将映射同一列两次)。
【解决方案2】:

如果您仔细查看您的ProjectFee 类,它无法知道这与Project 类有某种关联(作为外键id_project)。这就是为什么当您将两个对象保存在一起时,ProjectFee 类不知道它应该填充列 id_project 的 id 列值为 Project 类。

有两种可能-

  1. 您可以自己填充id_project 列(正如您在问题中提到的那样),方法是先保存Project 对象,然后将ID 提供给ProjectFee 对象。
  2. 或者,通过将id_project 属性设为Project 类型在实体中建立外键关系,并在id/id_project 列上连接两个实体。

希望对您有所帮助。

【讨论】:

  • 第一个是我已经在做的,第二个这次无效,因为我希望 idProject 是 Integer 而不是 Project
  • 如果您想将id_project 设置为整数,那么您必须自己设置它(就像您已经在做的那样),因为只有当您创建双向时,框架自动设置值才会起作用映射(您不想这样做)。
猜你喜欢
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-13
  • 2017-03-14
  • 1970-01-01
  • 2018-07-06
相关资源
最近更新 更多