我有一对一的映射关联类。
@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并在addressentity表上使用以下foriegn键约束的表(employeeentity,addressentity): 外键约束: “fkakhilesh”FOREIGN KEY(empid)REFERENCES employeeentity(id)ON DELETE CASCADE
我对不同的REST调用有以下要求:
我可以毫无问题地执行操作1到5。
主要问题在于6,我想到了以下问题: 1.当我执行“getSession()。update(object)”时,我得到了hibernate的StaleStateException:批量更新从update [0]返回了意外的行数;实际行数:0;预期:1。 如果地址不存在,“更新”是不可能的?我不能在更新期间创建新地址吗?
我是否需要将我的ServiceImpl调用更改为“getSession()。merge(object)?这种情况只能通过调用”merge“来处理吗?它如何影响性能?
如果我合并,我会得到hibernate的IdentifierGenerationException:尝试从null一对一属性中分配id。 我错过了什么吗?
这可以通过改变hibernate映射来解决吗?或者与cascade相关的事情。
这里@GeneratedValue(generator =“gen”)的重要性是什么?为什么@parameter在@GenericGenerator中使用
我是hibernate的新手,并试图深入了解hibernate映射。 此外,如果您能在设计上建议我应该是处理此问题的最佳方法,我会很高兴。
答案 0 :(得分:3)
我得到了解决方案。这个一对一的映射有点棘手,并不像我最初想的那么简单。 我使用了双向一对一映射,因此在更新期间调用EmployeeEntity和AddressEntity的setter来设置彼此非常重要。例如:
必须明确调用employeeEntity.setAddressEntity(addressEntity)和addressEntity.setEmpoyeeEntity(empoyeeEntity)。
单独设置employeeEntity.setAddressEntity(addressEntity)将无效。
答案 1 :(得分:0)
始终使用整数ID并使用.getSession.saveOrUpdate(entity);
进行保存或更新。
在一对一映射中,您应该在孩子身上提到constrained=true
。它使Child Id与Parent Id相同。
将这些行用于子ID。我不知道Java属性语法。
<generator class="foreign">
<param name="property">employeeEntity</param>
</generator>
Cascade.All
。我认为默认的提取模式是Select
,这很好。 Cascade通常用于负责父子关系的Parent部分。