0

我有以下具有一对一映射的关联类。

@Entity
    public class EmployeeEntity
    {
      @Id
      private String id;

      private String name;


      @OneToOne(mappedBy = "employeeEntity", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
      @Fetch(FetchMode.SELECT)
      @JoinColumn(name = "empid")
      private AddressEntity addressEntity;
        ...
        ...
        getters & setters
    }


@Entity
public class AddressEntity
{
    @Id
    @Column(unique=true, nullable=false)
    @GeneratedValue(generator="gen")
    @GenericGenerator(name="gen", strategy="foreign", parameters=@Parameter(name="property", value="employeeEntity"))
    private String empId;

    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    private EmployeeEntity employeeEntity;
    ...
    getters & setters
}

我正在使用 postgres 并在地址实体表上有以下外键约束的表(employeeentity,addressentity):外键约束:“fkakhilesh”外键(empid)参考employeeentity(id)ON DELETE CASCADE

我对不同的 REST 调用有以下要求:

  1. POST Rest call - 应该创建一个有地址的员工。
  2. POST Rest call - 应该创建一个没有地址的员工。
  3. GET Rest 调用 - 应该检索一个员工。地址也应该出现(如果存在)。
  4. PUT Rest call - 应该更新员工和地址(如果地址存在)。
  5. PUT Rest 调用 - 应该更新员工和地址(当地址被传递并且它已经存在于 empid 的地址实体表中时)
  6. PUT Rest 调用 - 应该更新员工并创建地址(当地址被传递并且它在 empid 的地址实体表中不存在时)

我能够毫无问题地执行操作 1 到 5。

主要问题在 6 中,我想到了以下问题: 1. 当我执行 "getSession().update(object)" 时,我得到 hibernate 的 StaleStateException: Batch update returned unexpected row count from update [0]; 实际行数:0;预期:1.如果地址不存在,“更新”是否不可能?我不能在更新期间创建一个新地址吗?

  1. 我是否需要将我的 ServiceImpl 调用更改为“getSession().merge(object)?这种情况只能通过调用“merge”来处理吗?它如何影响性能?

  2. 如果我合并,我会得到休眠的 IdentifierGenerationException:试图从空的一对一属性分配 id。我在这里错过了什么吗?

  3. 这可以通过更改休眠映射来解决吗?或与级联有关的东西。

  4. @GeneratedValue(generator="gen") 在这里的重要性是什么?为什么在@GenericGenerator 中使用@parameter

我是休眠新手,并试图深入了解休眠映射。此外,如果您能就设计建议我作为处理此问题的最佳方法,我将很高兴。

4

2 回答 2

3

我得到了解决这个问题。这种一对一的映射有点棘手,并不像我最初想象的那样简单。我使用了双向的一对一映射,因此在更新期间调用 EmployeeEntity 和 AddressEntity 的设置器以相互设置非常重要。例如:

employeeEntity.setAddressEntity(addressEntity) 和 addressEntity.setEmpoyeeEntity(empoyeeEntity) 必须显式调用。

单独设置 employeeEntity.setAddressEntity(addressEntity) 将不起作用。

于 2013-02-28T05:52:02.047 回答
0
  • 始终使用整数 ID 并.getSession.saveOrUpdate(entity);用于保存或更新。

  • 在一对一映射中,您应该提到constrained=true孩子。它使子 ID 与父 ID 相同。

  • 将这些行用于子 ID。我不知道 Java 属性语法。

<generator class="foreign">
    <param name="property">employeeEntity</param>
</generator>
  • 还要Cascade.All从子级中删除 Fetch 类型。我认为默认的获取模式Select很好。Cascade 通常用于负责父子关系的 Parent 部分。
于 2013-02-14T16:08:15.397 回答