简体   繁体   English

休眠一对一映射不更新子表

[英]Hibernate One to One mapping not updating the child table

I have following Associated classes with one to one mapping. 我有一对一映射的关联类。

@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
}

I am using postgres and having tables (employeeentity, addressentity) with following foriegn key constraint on addressentity table: Foreign-key constraints: "fkakhilesh" FOREIGN KEY (empid) REFERENCES employeeentity(id) ON DELETE CASCADE 我正在使用postgres并具有表(员工身份,地址实体),并在地址实体表上具有以下foriegn键约束:外键约束:“ fkakhilesh”外键(empid)引用employeeentity(id)在删除级联上

I have following requirements with different REST calls: 我对不同的REST调用有以下要求:

  1. POST Rest call - should create an employee with address. POST休息电话-应该创建一个具有地址的员工。
  2. POST Rest call - should create an employee without address. POST休息电话-应该创建没有地址的员工。
  3. GET Rest call - should retrieve an employeee. GET Rest电话-应该找一个雇员。 Address should also come if it exist. 地址(如果存在)也应该到来。
  4. PUT Rest call - should update an employee and address (if address exists). PUT休息电话-应该更新员工和地址(如果地址存在)。
  5. PUT Rest call - should update an employee and address (when address is passed and it already exists in addressentity table for empid) PUT Rest呼叫-应该更新员工和地址(当传递地址且该地址已存在于Empententity表中以供Empid时)
  6. PUT Rest call - should update an employee and create the address (when address is passed and it does not exists in addressentity table for empid) PUT Rest呼叫-应该更新一个员工并创建地址(当地址通过后,在Empententity表中不存在该地址)

I am able to perform operations 1 to 5 without any issues. 我能够执行1到5的操作而没有任何问题。

The main problem is in 6 and following questions come to my mind: 1. when i do "getSession().update(object)" , I get hibernate's StaleStateException: Batch update returned unexpected row count from update [0]; 主要问题是在6中,以下是我想到的问题:1.当我执行“ getSession()。update(object)”时,我得到了Hibernate的StaleStateException:批处理更新从更新[0]返回了意外的行数; actual row count: 0; 实际行数:0; expected: 1. is this not possible with "update" if address does not exists? 预期:1.如果地址不存在,使用“更新”是不可能的吗? can't I create a new address during update? 更新期间不能创建新地址吗?

  1. do i need to change my ServiceImpl call to "getSession().merge(object) ? is this case can only be handled by calling "merge" ? how it impacts performance? 我是否需要将ServiceImpl调用更改为“ getSession()。merge(object)”?这种情况只能通过调用“ merge”来处理吗?它如何影响性能?

  2. If i do merge, i get hibernate's IdentifierGenerationException: attempted to assign id from null one-to-one property. 如果我确实合并,则会得到休眠的IdentifierGenerationException:尝试从空的一对一属性分配ID。 Am i missing something here? 我在这里想念什么吗?

  3. this can be solved by changing hibernate mapping? 这可以通过更改休眠映射来解决? or somethin related to cascade. 或与级联有关的东西。

  4. what is the importance of @GeneratedValue(generator="gen") here? @GeneratedValue(generator =“ gen”)在这里的重要性是什么? why is @parameter used in @GenericGenerator 为什么在@GenericGenerator中使用@parameter

I am new to hibernate and trying to get into the depth of hibernate mapping. 我是休眠的新手,正在尝试进入休眠映射的深度。 Also, I would be delighted if you could suggest me on the design as what should be the best way to handle this. 另外,如果您能在设计上提出建议,我将非常高兴,因为这应该是处理此问题的最佳方法。

I got the fix for this. 我已经解决了。 This one-one mapping is somewhat tricky and not simple as i thought initially. 这种一一对应的映射有些棘手,并不像我最初想象的那么简单。 I have used bidirectional one to one mapping, so it is important to call the setters of both EmployeeEntity and AddressEntity to set each other during update. 我已经使用了双向的一对一映射,因此在更新过程中调用EmployeeEntity和AddressEntity的设置器互相设置很重要。 for example: 例如:

employeeEntity.setAddressEntity(addressEntity) and addressEntity.setEmpoyeeEntity(empoyeeEntity) has to explicitly called. employeeEntity.setAddressEntity(addressEntity)和addressEntity.setEmpoyeeEntity(empoyeeEntity)必须显式调用。

setting alone employeeEntity.setAddressEntity(addressEntity) will not work. 单独设置employeeEntity.setAddressEntity(addressEntity)将不起作用。

  • Always use integer Id and use .getSession.saveOrUpdate(entity); 始终使用整数ID并使用.getSession.saveOrUpdate(entity); for save or update. 用于保存或更新。

  • In the One to One Mapping you should mention constrained=true on the child. 在一对一映射中,您应该在孩子上提到constrained=true It makes Child Id the same as Parent Id. 它使子ID与父ID相同。

  • Use these lines for child id. 将这些行用作子ID。 I don't know Java attributes syntax. 我不知道Java属性语法。

<generator class="foreign">
    <param name="property">employeeEntity</param>
</generator>
  • Also remove Fetch type and Cascade.All from child. 还要从子项中删除Fetch类型和Cascade.All I think the default fetch mode is Select which is fine. 我认为默认的获取模式是Select ,这很好。 Cascade is usally used for the Parent part which is responsible for the parent-child relation. 级联通常用于父部分,该部分负责父子关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM