2013-02-14 69 views
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", [email protected](name="property", value="employeeEntity")) 
    private String empId; 

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

我使用Postgres的和具有下面就addressentity表foriegn键约束表(employeeentity,addressentity): 外键约束: “fkakhilesh” 外键(EMPID)参考employeeentity(ID)ON DELETE CASCADE

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

  1. POST REST调用 - 应该创建一个员工提供地址。
  2. POST其余呼叫 - 应创建一个没有地址的员工。
  3. GET Rest call - 应该检索employeee。地址也应该来,如果它存在。
  4. PUT其余呼叫 - 应更新员工和地址(如果地址存在)。
  5. 把REST调用 - 应该更新雇员和地址(在地址传递,它已经在EMPID addressentity表存在)
  6. 把REST调用 - 应该更新的员工,并创建地址(如果地址是过去了,在empid的地址表中不存在)

我能够在没有任何问题的情况下执行操作1到5。

主要问题出现在我的脑海里,并且出现以下问题: 1.当我做“getSession()。update(object)”时,我得到hibernate的StaleStateException:批量更新返回来自update [0 ]。实际行数:0;预期:1. 如果地址不存在,这是不可能的“更新”?我无法在更新期间创建新地址吗?

  1. 我需要改变我的ServiceImpl呼叫合并‘?它如何影响性能“的getSession()。合并(对象)?在这种情况下,只能通过调用来处理’?

  2. 如果我做的合并,我得到Hibernate的IdentifierGenerationException:试图从空一到一个属性 我在这里失去了一些东西给ID

  3. ,这可以通过改变Hibernate映射解决或事端有关级联

    。?。
  4. @GeneratedValue(generator =“gen”)在这里的重要性是什么?为什么在@GenericGenerator

是@parameter用我新的休眠和试图进入Hibernate映射的深度。 另外,如果你能在设计上建议我应该是最好的处理方法,我会很高兴。

回答

0
  • 始终使用整数ID并使用.getSession.saveOrUpdate(entity);进行保存或更新。

  • 在一对一映射中,你应该提到儿童的constrained=true。它使Child ID与Parent Id相同。

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

<generator class="foreign"> 
    <param name="property">employeeEntity</param> 
</generator> 
  • 同时删除获取类型,然后从孩子Cascade.All。我认为默认的获取模式是Select这很好。 Cascade通常用于负责父子关系的Parent部分。
+0

不要紧,如果你使用整数ID或字符串ID。 – akhi 2013-02-28 05:45:55

3

我得到了解决这个问题。这个一对一映射有点棘手,并不像我想的那样简单。 我已经使用双向一对一映射,因此在更新过程中调用EmployeeEntity和AddressEntity的setter来设置对方非常重要。例如:

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

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

+1

您的解决方案不适合我。我分别创建了两个链接,它显示“org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已与会话相关联”,您能分享关于您是如何做的更多细节? – 2016-09-11 09:11:24